Add ivtest to the iverilog source tree

By adding ivtest to the iverilog source tree, it is easier to keep
the regression test synchronized with the source that is being tested.
This should be especially helpful for PRs that add a new feature, and
have a matching ivtest PR with the regression test for that feature.
This commit is contained in:
Stephen Williams 2022-01-15 10:18:50 -08:00
parent 279b2665af
commit cea237b407
3839 changed files with 279083 additions and 1 deletions

4
.github/test.sh vendored
View File

@ -1,6 +1,8 @@
#!/usr/bin/env sh
git clone https://github.com/steveicarus/ivtest.git || exit 1
echo "Using the bundled ivtest to run regression tests."
echo " pwd = $(pwd)"
cd ivtest
version=devel

5
ivtest/.gitattributes vendored Normal file
View File

@ -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

33
ivtest/.gitignore vendored Normal file
View File

@ -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

339
ivtest/COPYING Normal file
View File

@ -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.

120
ivtest/README Normal file
View File

@ -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.

21
ivtest/blif.list Normal file
View File

@ -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

66
ivtest/blif/blif01a.v Normal file
View File

@ -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

40
ivtest/blif/blif01a_tb.v Normal file
View File

@ -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

9
ivtest/blif/blif01b.v Normal file
View File

@ -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

34
ivtest/blif/blif01b_tb.v Normal file
View File

@ -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

11
ivtest/blif/blif01c.v Normal file
View File

@ -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

40
ivtest/blif/blif01c_tb.v Normal file
View File

@ -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

11
ivtest/blif/blif01d.v Normal file
View File

@ -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

40
ivtest/blif/blif01d_tb.v Normal file
View File

@ -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

14
ivtest/blif/blif01e.v Normal file
View File

@ -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

53
ivtest/blif/blif01e_tb.v Normal file
View File

@ -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

11
ivtest/blif/blif01f.v Normal file
View File

@ -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

32
ivtest/blif/blif01f_tb.v Normal file
View File

@ -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

14
ivtest/blif/blif01g.v Normal file
View File

@ -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

44
ivtest/blif/blif01g_tb.v Normal file
View File

@ -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

9
ivtest/blif/blif01h.v Normal file
View File

@ -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

33
ivtest/blif/blif01h_tb.v Normal file
View File

@ -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

12
ivtest/blif/blif01i.v Normal file
View File

@ -0,0 +1,12 @@
module ivtest
(
input [3:0] x,
input [3:0] y,
output [3:0] z
);
assign z = x ^ y;
endmodule // ivtest

25
ivtest/blif/blif01i_tb.v Normal file
View File

@ -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

40
ivtest/blif/blif02a.v Normal file
View File

@ -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

40
ivtest/blif/blif02a_tb.v Normal file
View File

@ -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

11
ivtest/blif/blif02b.v Normal file
View File

@ -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

34
ivtest/blif/blif02b_tb.v Normal file
View File

@ -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

11
ivtest/blif/blif02c.v Normal file
View File

@ -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

40
ivtest/blif/blif02c_tb.v Normal file
View File

@ -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

11
ivtest/blif/blif02d.v Normal file
View File

@ -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

40
ivtest/blif/blif02d_tb.v Normal file
View File

@ -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

27
ivtest/blif/blif02e.v Normal file
View File

@ -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

53
ivtest/blif/blif02e_tb.v Normal file
View File

@ -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

11
ivtest/blif/blif02f.v Normal file
View File

@ -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

32
ivtest/blif/blif02f_tb.v Normal file
View File

@ -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

16
ivtest/blif/blif02g.v Normal file
View File

@ -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

44
ivtest/blif/blif02g_tb.v Normal file
View File

@ -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

15
ivtest/blif/blif02h.v Normal file
View File

@ -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

33
ivtest/blif/blif02h_tb.v Normal file
View File

@ -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

53
ivtest/blif/blif02i.v Normal file
View File

@ -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

53
ivtest/blif/blif02i_tb.v Normal file
View File

@ -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

17
ivtest/blif/blif02j.v Normal file
View File

@ -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

33
ivtest/blif/blif02j_tb.v Normal file
View File

@ -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

25
ivtest/blif/blif02k.v Normal file
View File

@ -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

52
ivtest/blif/blif02k_tb.v Normal file
View File

@ -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

25
ivtest/blif/blif_shift.v Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

86
ivtest/blif_reg.py Normal file
View File

@ -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."

2048
ivtest/contrib/TEST9.ROM Normal file

File diff suppressed because it is too large Load Diff

48
ivtest/contrib/add32.v Normal file
View File

@ -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

260
ivtest/contrib/div16.v Normal file
View File

@ -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

375
ivtest/contrib/fifo.v Normal file
View File

@ -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

301
ivtest/contrib/gencrc.v Normal file
View File

@ -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

173
ivtest/contrib/mult16.v Normal file
View File

@ -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

257
ivtest/contrib/onehot.v Normal file
View File

@ -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

2262
ivtest/contrib/pic.v Normal file

File diff suppressed because it is too large Load Diff

37
ivtest/find_valg_all Executable file
View File

@ -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."

31
ivtest/find_valg_errs Executable file
View File

@ -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."

View File

@ -0,0 +1,2 @@
fpga_log
fpga_tmp

View File

@ -0,0 +1,6 @@
module bufifab (output Out0, output Out1, input I, input E);
bufif0 (Out0, I, E);
bufif1 (Out1, I, E);
endmodule

View File

@ -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

View File

@ -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

45
ivtest/fpga_tests/cell_ld_tb.v Executable file
View File

@ -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

13
ivtest/fpga_tests/eqne.v Normal file
View File

@ -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

View File

@ -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

View File

@ -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 -

141
ivtest/fpga_tests/fpga_reg.sh Executable file
View File

@ -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.
#

View File

@ -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

5
ivtest/fpga_tests/ge2.v Normal file
View File

@ -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

View File

@ -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

5
ivtest/fpga_tests/ge8.v Normal file
View File

@ -0,0 +1,5 @@
module ge8(output wire out, input wire [7:0] A, input wire [7:0] B);
assign out = A >= B;
endmodule

View File

@ -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

View File

@ -0,0 +1,5 @@
module onehot16(output wire [15:0] out, input wire [3:0] A);
assign out = 1 << A;
endmodule

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

25
ivtest/fpga_tests/ornor7_tb.v Executable file
View File

@ -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

View File

@ -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

View File

@ -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

128
ivtest/fpga_tests/sqrt.v Normal file
View File

@ -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

View File

@ -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

5
ivtest/fpga_tests/sub8.v Normal file
View File

@ -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

View File

@ -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

33
ivtest/fpga_tests/timer.v Normal file
View File

@ -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

View File

@ -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

View File

@ -0,0 +1,2 @@
./ivltests/always_comb_no_sens.v:5: warning: always_comb process has no sensitivities.
PASSED

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,5 @@
0 1 2 3
4 1 2 3
4 5 2 3
4 5 6 3
4 5 6 7

View File

@ -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 !

View File

@ -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

View File

@ -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.

View File

@ -0,0 +1 @@
0003

View File

@ -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