Add ivtest to the iverilog source tree
By adding ivtest to the iverilog source tree, it is easier to keep the regression test synchronized with the source that is being tested. This should be especially helpful for PRs that add a new feature, and have a matching ivtest PR with the regression test for that feature.
This commit is contained in:
parent
279b2665af
commit
cea237b407
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
git clone https://github.com/steveicarus/ivtest.git || exit 1
|
||||
echo "Using the bundled ivtest to run regression tests."
|
||||
echo " pwd = $(pwd)"
|
||||
|
||||
cd ivtest
|
||||
|
||||
version=devel
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
# 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
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# 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
|
||||
|
|
@ -0,0 +1,339 @@
|
|||
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.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can 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.
|
||||
|
||||
<signature of Ty Coon>, 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.
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
####################
|
||||
#
|
||||
# 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<version>.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=<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=<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=<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.
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
blif01a
|
||||
blif01b
|
||||
blif01c
|
||||
blif01d
|
||||
blif01e
|
||||
blif01f
|
||||
blif01g
|
||||
blif01h
|
||||
blif01i
|
||||
blif02a
|
||||
blif02b
|
||||
blif02c
|
||||
blif02d
|
||||
blif02e
|
||||
blif02f
|
||||
blif02g
|
||||
blif02h
|
||||
blif02i
|
||||
blif02j
|
||||
blif02k
|
||||
blif_shift
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
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<<SWID) ; sdx = sdx+1) begin
|
||||
S = sdx[SWID-1:0];
|
||||
#1 ;
|
||||
if (Q !== D[S]) begin
|
||||
$display("FAILED = D=%b, S=%0d, Q=%b", D, S, Q);
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
end // for (idx = 0 ; idx < 50 ; idx += 1)
|
||||
$display("PASSED");
|
||||
end // initial begin
|
||||
|
||||
endmodule // main
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
module test_logic
|
||||
#(parameter WID = 4)
|
||||
(input wire [WID-1:0] A,
|
||||
output q_and, q_or, q_xor, q_nand, q_nor, q_xnor);
|
||||
|
||||
assign q_and = & A;
|
||||
assign q_or = | A;
|
||||
assign q_xor = ^ A;
|
||||
assign q_nand= ~& A;
|
||||
assign q_nor = ~| A;
|
||||
assign q_xnor= ~^ A;
|
||||
|
||||
endmodule // test_logic
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
module main;
|
||||
|
||||
localparam WID = 4;
|
||||
reg [WID:0] X;
|
||||
wire q_and, q_or, q_xor, q_nand, q_nor, q_xnor;
|
||||
|
||||
test_logic DUT(.\A[3] (X[3]), .\A[2] (X[2]), .\A[1] (X[1]), .\A[0] (X[0]),
|
||||
.q_and(q_and), .q_or(q_or), .q_xor(q_xor),
|
||||
.q_nand(q_nand), .q_nor(q_nor), .q_xnor(q_xnor));
|
||||
|
||||
initial begin
|
||||
for (X = 0 ; X < 16 ; X = X+1) begin
|
||||
#1 /* Let gates settle. */;
|
||||
if (q_and !== & X[WID-1:0]) begin
|
||||
$display("FAILED -- q_and=%b, X=%b", q_and, X[WID-1:0]);
|
||||
$finish;
|
||||
end
|
||||
if (q_or !== | X[WID-1:0]) begin
|
||||
$display("FAILED -- q_or=%b, X=%b", q_or, X[WID-1:0]);
|
||||
$finish;
|
||||
end
|
||||
if (q_xor !== ^ X[WID-1:0]) begin
|
||||
$display("FAILED -- q_xor=%b, X=%b", q_xor, X[WID-1:0]);
|
||||
$finish;
|
||||
end
|
||||
if (q_nand !== ~& X[WID-1:0]) begin
|
||||
$display("FAILED -- q_nand=%b, X=%b", q_nand, X[WID-1:0]);
|
||||
$finish;
|
||||
end
|
||||
if (q_nor !== ~| X[WID-1:0]) begin
|
||||
$display("FAILED -- q_nor=%b, X=%b", q_nor, X[WID-1:0]);
|
||||
$finish;
|
||||
end
|
||||
if (q_xnor !== ~^ X[WID-1:0]) begin
|
||||
$display("FAILED -- q_xnor=%b, X=%b", q_xnor, X[WID-1:0]);
|
||||
$finish;
|
||||
end
|
||||
|
||||
end
|
||||
$display("PASSED");
|
||||
end
|
||||
|
||||
endmodule // main
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
module test_mux
|
||||
(input wire [1:0] D0, D1,
|
||||
input wire S,
|
||||
output wire [1:0] Q);
|
||||
|
||||
assign Q = S? D1 : D0;
|
||||
|
||||
endmodule // test_mux
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
module main;
|
||||
|
||||
reg [1:0] D0, D1;
|
||||
reg sel;
|
||||
wire [1:0] Q;
|
||||
|
||||
test_mux DUT(.S(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
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
module ivtest
|
||||
(
|
||||
input [3:0] x,
|
||||
input [3:0] y,
|
||||
output [3:0] z
|
||||
);
|
||||
|
||||
assign z = x ^ y;
|
||||
|
||||
endmodule // ivtest
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
module main;
|
||||
|
||||
reg [3:0] x, y;
|
||||
wire [3:0] z;
|
||||
|
||||
ivtest dut (.\x[3] (x[3]), .\x[2] (x[2]), .\x[1] (x[1]), .\x[0] (x[0]),
|
||||
.\y[3] (y[3]), .\y[2] (y[2]), .\y[1] (y[1]), .\y[0] (y[0]),
|
||||
.\z[3] (z[3]), .\z[2] (z[2]), .\z[1] (z[1]), .\z[0] (z[0]));
|
||||
|
||||
integer idx;
|
||||
initial begin
|
||||
for (idx = 0 ; idx[8]==0 ; idx = idx+1) begin
|
||||
x = idx[3:0];
|
||||
y = idx[7:4];
|
||||
#1 /* let devices settle. */ ;
|
||||
if (z !== (x ^ y)) begin
|
||||
$display("FAILED -- x=%b, y=%b, x^y=%b", x, y, z);
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
$display("PASSED");
|
||||
end // initial begin
|
||||
|
||||
endmodule // main
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
/*
|
||||
* 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 reg Q, output reg Cout);
|
||||
|
||||
always @* begin
|
||||
Q = A ^ B ^ Cin;
|
||||
Cout = A&B | A&Cin | B&Cin;
|
||||
end
|
||||
|
||||
endmodule // hadd
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
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<<SWID) ; sdx = sdx+1) begin
|
||||
S = sdx[SWID-1:0];
|
||||
#1 ;
|
||||
if (Q !== D[S]) begin
|
||||
$display("FAILED = D=%b, S=%0d, Q=%b", D, S, Q);
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
end // for (idx = 0 ; idx < 50 ; idx += 1)
|
||||
$display("PASSED");
|
||||
end // initial begin
|
||||
|
||||
endmodule // main
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
module test_logic
|
||||
#(parameter WID = 4)
|
||||
(input wire [WID-1:0] A,
|
||||
output reg q_and, q_or, q_xor, q_nand, q_nor, q_xnor);
|
||||
|
||||
always @(A) begin
|
||||
q_and = &A;
|
||||
q_or = |A;
|
||||
q_xor = ^A;
|
||||
q_nand = ~q_and;
|
||||
q_nor = ~q_or;
|
||||
q_xnor = ~q_xor;
|
||||
end
|
||||
|
||||
endmodule // test_logic
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
module main;
|
||||
|
||||
localparam WID = 4;
|
||||
reg [WID:0] X;
|
||||
wire q_and, q_or, q_xor, q_nand, q_nor, q_xnor;
|
||||
|
||||
test_logic DUT(.\A[3] (X[3]), .\A[2] (X[2]), .\A[1] (X[1]), .\A[0] (X[0]),
|
||||
.q_and(q_and), .q_or(q_or), .q_xor(q_xor),
|
||||
.q_nand(q_nand), .q_nor(q_nor), .q_xnor(q_xnor));
|
||||
|
||||
initial begin
|
||||
for (X = 0 ; X < 16 ; X = X+1) begin
|
||||
#1 /* Let gates settle. */;
|
||||
if (q_and !== & X[WID-1:0]) begin
|
||||
$display("FAILED -- q_and=%b, X=%b", q_and, X[WID-1:0]);
|
||||
$finish;
|
||||
end
|
||||
if (q_or !== | X[WID-1:0]) begin
|
||||
$display("FAILED -- q_or=%b, X=%b", q_or, X[WID-1:0]);
|
||||
$finish;
|
||||
end
|
||||
if (q_xor !== ^ X[WID-1:0]) begin
|
||||
$display("FAILED -- q_xor=%b, X=%b", q_xor, X[WID-1:0]);
|
||||
$finish;
|
||||
end
|
||||
if (q_nand !== ~& X[WID-1:0]) begin
|
||||
$display("FAILED -- q_nand=%b, X=%b", q_nand, X[WID-1:0]);
|
||||
$finish;
|
||||
end
|
||||
if (q_nor !== ~| X[WID-1:0]) begin
|
||||
$display("FAILED -- q_nor=%b, X=%b", q_nor, X[WID-1:0]);
|
||||
$finish;
|
||||
end
|
||||
if (q_xnor !== ~^ X[WID-1:0]) begin
|
||||
$display("FAILED -- q_xnor=%b, X=%b", q_xnor, X[WID-1:0]);
|
||||
$finish;
|
||||
end
|
||||
|
||||
end
|
||||
$display("PASSED");
|
||||
end
|
||||
|
||||
endmodule // main
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
module test_mux
|
||||
(input wire [1:0] D0, D1,
|
||||
input wire [1:0] S,
|
||||
output reg [1:0] Q);
|
||||
|
||||
always @(*) begin
|
||||
case (S)
|
||||
2'b00: Q = D0;
|
||||
2'b01: Q = D1;
|
||||
default: Q = 0;
|
||||
endcase // case (S)
|
||||
end
|
||||
|
||||
endmodule // test_mux
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
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)
|
||||
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
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
#
|
||||
# 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:
|
||||
# <http://www.eecs.berkeley.edu/~alanmi/abc/>
|
||||
#
|
||||
# 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."
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,48 @@
|
|||
module 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
|
||||
|
|
@ -0,0 +1,260 @@
|
|||
//
|
||||
// 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
|
||||
|
|
@ -0,0 +1,375 @@
|
|||
`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
|
||||
|
|
@ -0,0 +1,301 @@
|
|||
`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
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
//
|
||||
// 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
|
||||
|
|
@ -0,0 +1,257 @@
|
|||
//
|
||||
// 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
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,37 @@
|
|||
#!/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."
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#!/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."
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
fpga_log
|
||||
fpga_tmp
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
module bufifab (output Out0, output Out1, input I, input E);
|
||||
|
||||
bufif0 (Out0, I, E);
|
||||
bufif1 (Out1, I, E);
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
module 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
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
`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
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
`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
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
module 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
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
module 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
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# 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 -
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
#!/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.
|
||||
#
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
00 >= 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
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
module ge2(output wire out, input wire [1:0] A, input wire [1:0] B);
|
||||
|
||||
assign out = A >= B;
|
||||
|
||||
endmodule // ge2
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
module 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
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
module ge8(output wire out, input wire [7:0] A, input wire [7:0] B);
|
||||
|
||||
assign out = A >= B;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
module onehot16(output wire [15:0] out, input wire [3:0] A);
|
||||
|
||||
assign out = 1 << A;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
module 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
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
module 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
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
module 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
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
module 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
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
module 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
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
module 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
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* 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<<bitl) + bit
|
||||
//
|
||||
// This works out using shifts because bit and bit2 are known to
|
||||
// have only a single bit in them.
|
||||
wire [15:0] guess = acc | bit;
|
||||
wire [31:0] guess2 = acc2 + bit2 + ((acc << bitl) << 1);
|
||||
|
||||
(* ivl_synthesis_on *)
|
||||
always @(posedge clk or posedge reset)
|
||||
if (reset) begin
|
||||
acc = 0;
|
||||
acc2 = 0;
|
||||
bitl = 15;
|
||||
end else begin
|
||||
if (guess2 <= x) begin
|
||||
acc <= guess;
|
||||
acc2 <= guess2;
|
||||
end
|
||||
bitl <= bitl - 5'd1;
|
||||
end
|
||||
|
||||
endmodule // sqrt32
|
||||
|
||||
/*
|
||||
* 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", "39");
|
||||
|
||||
// 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
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* This module is a test bench for the sqrt32 module. It runs some
|
||||
* test input values through the sqrt32 module, and checks that the
|
||||
* output is valid. If an invalid output is generated, print and
|
||||
* error message and stop immediately. If all the tested values pass,
|
||||
* then print PASSED after the test is complete.
|
||||
*/
|
||||
module main;
|
||||
|
||||
reg [31:0] x;
|
||||
reg clk, reset;
|
||||
|
||||
wire [15:0] y;
|
||||
wire rdy;
|
||||
|
||||
chip_root dut(.clk(clk), .reset(reset), .rdy(rdy), .x(x), .y(y));
|
||||
|
||||
(* ivl_synthesis_off *)
|
||||
always #5 clk = !clk;
|
||||
|
||||
task reset_dut;
|
||||
begin
|
||||
reset = 1;
|
||||
#1 reset = 0;
|
||||
@(negedge clk) ;
|
||||
end
|
||||
endtask // reset_dut
|
||||
|
||||
task crank_dut;
|
||||
begin
|
||||
while (rdy == 0) begin
|
||||
@(posedge clk) /* wait */;
|
||||
end
|
||||
end
|
||||
endtask // crank_dut
|
||||
|
||||
reg GSR;
|
||||
assign glbl.GSR = GSR;
|
||||
|
||||
integer idx;
|
||||
|
||||
(* ivl_synthesis_off *)
|
||||
initial begin
|
||||
reset = 0;
|
||||
clk = 0;
|
||||
|
||||
/* If doing a post-map simulation, when we need to wiggle
|
||||
The GSR bit to simulate chip power-up. */
|
||||
GSR = 1;
|
||||
#100 GSR = 0;
|
||||
#100 x = 1;
|
||||
reset_dut;
|
||||
crank_dut;
|
||||
$display("x=%d, y=%d", x, y);
|
||||
|
||||
x = 3;
|
||||
reset_dut;
|
||||
crank_dut;
|
||||
$display("x=%d, y=%d", x, y);
|
||||
|
||||
x = 4;
|
||||
reset_dut;
|
||||
crank_dut;
|
||||
$display("x=%d, y=%d", x, y);
|
||||
|
||||
for (idx = 0 ; idx < 200 ; idx = idx + 1) begin
|
||||
x = $random;
|
||||
reset_dut;
|
||||
crank_dut;
|
||||
$display("x=%d, y=%d", x, y);
|
||||
|
||||
if (x < (y * y)) begin
|
||||
$display("ERROR: y is too big");
|
||||
$finish;
|
||||
end
|
||||
|
||||
if (x > ((y + 1)*(y + 1))) begin
|
||||
$display("ERROR: y is too small");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
$display("PASSED");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule // main
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
module sub8(output wire [7:0] out, input wire [7:0] A, input wire [7:0] B);
|
||||
|
||||
assign out = A - B;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
./ivltests/always_comb_no_sens.v:5: warning: always_comb process has no sensitivities.
|
||||
PASSED
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
./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
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
./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
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
./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
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
./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
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
0 1 2 3
|
||||
4 1 2 3
|
||||
4 5 2 3
|
||||
4 5 6 3
|
||||
4 5 6 7
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
$date
|
||||
Tue Apr 21 18:40:22 2009
|
||||
$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
|
||||
#0
|
||||
$dumpvars
|
||||
bx #
|
||||
bx "
|
||||
bx !
|
||||
$end
|
||||
#1
|
||||
b1010101 #
|
||||
b0 "
|
||||
b11111111 !
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
02040608
|
||||
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
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
VCD 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.
|
||||
|
|
@ -0,0 +1 @@
|
|||
0003
|
||||
|
|
@ -0,0 +1 @@
|
|||
ERROR: ./ivltests/automatic_error11.v:9: $monitor argument "local" is an automatic variable.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue