Merge pull request #583 from steveicarus/bring-in-ivtest
v11: Add ivtest to the iverilog source tree
This commit is contained in:
commit
b17a967ced
|
|
@ -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=v11
|
||||
|
|
|
|||
|
|
@ -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