URL
https://opencores.org/ocsvn/zap/zap/trunk
Subversion Repositories zap
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 42 to Rev 43
- ↔ Reverse comparison
Rev 42 → Rev 43
/zap/trunk/doc/wishbone_b3_spec.pdf
File deleted
zap/trunk/doc/wishbone_b3_spec.pdf
Property changes :
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Index: zap/trunk/doc/ZAP_PROCESSOR_CORE_DATASHEET.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: zap/trunk/doc/ZAP_PROCESSOR_CORE_DATASHEET.pdf
===================================================================
--- zap/trunk/doc/ZAP_PROCESSOR_CORE_DATASHEET.pdf (revision 42)
+++ zap/trunk/doc/ZAP_PROCESSOR_CORE_DATASHEET.pdf (nonexistent)
zap/trunk/doc/ZAP_PROCESSOR_CORE_DATASHEET.pdf
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: zap/trunk/sw/gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: zap/trunk/sw/gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2
===================================================================
--- zap/trunk/sw/gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2 (revision 42)
+++ zap/trunk/sw/gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2 (nonexistent)
zap/trunk/sw/gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: zap/trunk/LICENSE.md
===================================================================
--- zap/trunk/LICENSE.md (revision 42)
+++ zap/trunk/LICENSE.md (nonexistent)
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- {description}
- Copyright (C) {year} {fullname}
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- {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 Lesser General
-Public License instead of this License.
Index: zap/trunk/src/doc/makefile
===================================================================
--- zap/trunk/src/doc/makefile (revision 42)
+++ zap/trunk/src/doc/makefile (nonexistent)
@@ -1,39 +0,0 @@
-// ---------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- ------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program is distributed in the hope that it will be useful, --
-// -- but WITHOUT ANY WARRANTY; without even the implied warranty of --
-// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
-// -- GNU General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// ---------------------------------------------------------------------------
-
-.DEFAULT_GOAL=view
-
-view: ../../doc/ZAP_PROCESSOR_CORE_DATASHEET.pdf
- evince ../../doc/ZAP_PROCESSOR_CORE_DATASHEET.pdf
-
-../../doc/ZAP_PROCESSOR_CORE_DATASHEET.pdf: zap_ug.tex
- mkdir -p ../../doc/ ../../obj/doc/
- pdflatex -output-directory ../../obj/doc/ zap_ug.tex
- mv ../../obj/doc/zap_ug.pdf ../../doc/ZAP_PROCESSOR_CORE_DATASHEET.pdf
-
-clean:
- rm -rfv ../../obj/doc/*zap_ug* ../../doc/ZAP_PROCESSOR_CORE_DATASHEET.pdf
- rm -rfv zap_ug.pdf zap_ug.log zap_ug.aux ZAP_PROCESSOR_CORE_DATASHEET.pdf
-
-.PHONY: view
-.PHONY: clean
Index: zap/trunk/src/doc/zap_ug.tex
===================================================================
--- zap/trunk/src/doc/zap_ug.tex (revision 42)
+++ zap/trunk/src/doc/zap_ug.tex (nonexistent)
@@ -1,556 +0,0 @@
-% ---------------------------------------------------------------------------
-% -- --
-% -- (C) 2016-2018 Revanth Kamaraj. --
-% -- --
-% -- ------------------------------------------------------------------------
-% -- --
-% -- This program is free software; you can redistribute it and/or --
-% -- modify it under the terms of the GNU General Public License --
-% -- as published by the Free Software Foundation; either version 2 --
-% -- of the License, or (at your option) any later version. --
-% -- --
-% -- This program is distributed in the hope that it will be useful, --
-% -- but WITHOUT ANY WARRANTY; without even the implied warranty of --
-% -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
-% -- GNU General Public License for more details. --
-% -- --
-% -- You should have received a copy of the GNU General Public License --
-% -- along with this program; if not, write to the Free Software --
-% -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-% -- 02110-1301, USA. --
-% -- --
-% ---------------------------------------------------------------------------
-
-
-
-\documentclass[10pt]{article}
-\usepackage{graphicx}
-\usepackage{tabularx}
-\usepackage{verbatim}
-\usepackage{listings}
-\usepackage{longtable}
-
-\renewcommand{\familydefault}{\sfdefault}
-
-\title{ZAP Processor User Guide}
-\author{Revanth Kamaraj}
-
-\begin{document}
-
-\lstset{language=Perl}
-\maketitle
-
-\section{Introduction}
-
-ZAP is a synthesizable open source 32-bit RISC processor core capable of
-executing ARM®v4T binaries at both the user and supervisor level. The processor
-features a 10-stage pipeline that allows it to reach reasonable operating
-frequencies. The processor supports standard I/D cache and memory management
-that may be controlled using coprocessor \#15. Both the cache and TLB are direct
-mapped. Caches, TLBs and branch memory are implemented as generic fully
-synchronous RAMs that can efficiently map to native FPGA block RAM to save FPGA
-resources. To simplify device integration, the memory bus is fully compliant
-with Wishbone B3. A store buffer is implemented to improve performance.
-\linebreak
-\linebreak
-NOTE: Please use pipeline retiming during synthesis for maximum timing performance.
-
-\subsection{CPU Clock and Reset}
-ZAP uses a single clock called the core clock to drive the entire design. The
-clock must be supplied to the port I\_CLK. ZAP expects a rising edge
-synchronous I\_RESET (active high) to be applied i.e.,
-the reset signal must change only on the rising edges of clock. The reset
-must be externally synchronized to the core clock before being applied to
-the processor.
-
-\subsection{Block Digram}
-\includegraphics{images/image004.png}
-
-\subsection{Pipeline Overview}
-
-\begin{tabularx} {\linewidth}{|r|X|}
-\hline
-
-Stage &
-Description \\ \hline
-
-Fetch &
-Clocks data from I-cache into instruction register. Also branch predictor memory
-is read out in this stage. \\ \hline
-
-FIFO &
-Instructions and corresponding PC+8 values are clocked into a shallow buffer.
- \\ \hline
-
-Thumb Decoder &
-Converts 16-bit instructions to 32-bit ARM instructions. Instructions predicted
-as taken cause the pipeline to change to the new predicted target. \\ \hline
-
-Predecode &
-Handles coprocessor instructions, SWAP and LDM/STM. \\ \hline
-
-Decode &
-Decodes ARM instructions. \\ \hline
-
-Issue &
-Operand values are extracted here from the bypass network. In case data from
-the bypass network is not available, the register file is read. \\ \hline
-
-Shift &
-Performs shifts and multiplies. Contains a single level bypass network to
-optimize away certain dependencies. Multiplication takes multiple clock cycles. \\ \hline
-
-Execute &
-Contains the ALU. The ALU is single cycle and handles arithmetic and logical
-operations. \\ \hline
-
-Memory &
-Clocks data from the data cache into the pipeline. Aligns read data as
-necessary. \\ \hline
-
-Writeback &
-Writes to register file. Can sustain 2 writes per clock cycle although the
-only use for the feature is accelerate LDR performance in the current
-implementation. \\ \hline
-\end{tabularx}
-\\
-\\
-ZAP features a 10 stage pipeline. The pipeline has an extensive bypass network
-to minimize pipeline stalls. A load accelerator allows data to be forwarded
-from memory a cycle early. Most non-multiply instructions can be executed
-within a single clock tick with no stalls. Exceptions to this rule are when
-multiplies or non-trivial shifts are used.
-\\
-\\
-The following code takes 3 cycles to execute because R1 needs to be shifted
-and is not available until the first instruction enters the ALU:
-\\
-\\
-ADD R1, R2, R3 \\
-ADD R4, R5, R1 LSL R2 \\
-\\
-\\
-If the second register is not source shifted by a register that depends on the
-previous instruction, a data dependency check may be relaxed (Register R9 for
-the second instruction can be obtained in issue itself so nothing is blocking
-the second instruction from using the shifter) and thus the following code
-takes 2 cycles to execute:
-\\
-\\
-ADD R1, R2, R3 LSL R5 \\
-ADD R4, R1, R9 LSL R2 \\
-\\
-\\
-Another feature of the pipeline is that it can issue memory operations with
-writeback in a single cycle. The following instructions takes 2 cycles to
-execute assuming a perfect cache.
-\\
-\\
-LDR R0, [R1, \#2]! \\
-ADD R1, R3, R4 LSL R1 \\
-\\
-\\
-The pipeline feedback unit is designed to reasonably minimize pipeline stalls.
-Note however that pipeline bubble squashing is available only across the
-instruction FIFO.
-
-\subsection{Features}
-
-\begin{itemize}
-\item Fully synthesizable Verilog-2001 core.
-\item Store buffer for improved performance.
-\item Can execute ARMv4T code at both the user and supervisor level.
-\item Wishbone B3 compatible interface. Cache unit supports burst access.
-\item 10-stage pipeline design. Pipeline has bypass network to resolve
- dependencies.
-\item 2 write ports for the register file to allow LDR/STR with
- writeback to execute as a single instruction. Note that the
- register file is implemented using flip-flops.
-\item Branch prediction supported. Uses a 2-bit state for each branch.
-\item Split I and D writeback cache (Size can be configured using parameters).
-\item Split I and D MMUs (TLB size can be configured using parameters).
-\item Base restored abort model to simplify data abort handling.
-\end{itemize}
-
-\subsection{Branch prediction mechanism}
-
-ZAP uses a relatively simple branch prediction mechanism (Note that the branch
-table block RAM is read in Fetch). Note that when using ARM code, the amount of
-branch table entries is cut by half since the lower 2 bits of PC are 0. A
-simple state machine is used to reinforce or modify the status of a branch. The
-pass and fail signals are generated from the ALU.
-
-\includegraphics{images/image008.png}
-\\
-\includegraphics{images/image010.png}
-
-\subsection{Cache/TLB Overview}
-
-ZAP uses direct mapped cache (separate I/D) that is virtual. For decent
-performance, the cache is writeback. To enable writeback, each cache line has
-a dirty bit. The size of each cache line is fixed at 16 bytes. Since ARMv4
-specifies three kinds of paging schemes: section, large and small pages, 3
-TLB block RAMs are employed which are also direct mapped. ZAP has independent
-instruction and data caches/TLBs. The cache/MMU setup is v4 compatible. The
-cache should be enabled as soon as possible for good performance because the
-memory subsystem is efficient for burst transactions.
-
-\includegraphics{images/image012.png}
-
-\subsection{Running Simulations}
-\subsubsection{Creating and Simulating Test Cases}
-
-To create a test case, create a some assembly(.s extension) and
-C files(.c extension) and a linker script(.ld extension) in the directory
-\texttt{src/ts/$\langle$TestCase$\rangle$/}
-\\
-\\
-Copy the \texttt{makefile} and \texttt{Config.cfg} from one of the existing test case directories
-to the directory \texttt{src/ts/$\langle$TestCase$\rangle$/}. Edit the \texttt{Config.cfg} to suit the testcase.
-\\
-\\
-To run simulations using the scripts provided, you will need Icarus
-Verilog 10.0 or higher and 32-bit libraries installed. Object files and
-waveform dumps can be found in the \texttt{obj/ts/$\langle$TestCase$\rangle$/} directory.
-\\
-\\
-Enter \texttt{src/ts/$\langle$TestCase$\rangle$} and type \texttt{make}.
-\\
-\\
-NOTE: Normally C files are directly converted to object files. To view the assembly code for a C file (say file.c), do \texttt{make c2asm X=file.c}.
-This will create a file called \texttt{file.c.asm} in the corresponding object directory.
-\\
-NOTE: To clean object files, enter \texttt{src/ts/$\langle$TestCase$\rangle$} and type \texttt{make clean}.
-\\
-NOTE: To clean object files and the extracted GCC files, enter \texttt{src/ts/$\langle$TestCase$\rangle$} and type \texttt{make cleanall}.
-\\
-\\
-NOTE: You can set the testbench and processor configuration in the \texttt{Config.cfg}
-file that contains a Perl hash. This file is present in the same directory as
-the test case.
-\\
-\\
-Here's a sample of what the \texttt{Config.cfg} file should contain.
-\\
-\\
-\begin{lstlisting}[frame=none] % Perl code block start.
-
-%Config = (
-# CPU configuration.
-DATA_CACHE_SIZE => 4096,# Data cache size in bytes
-CODE_CACHE_SIZE => 4096,# Instruction cache size in bytes
-CODE_SECTION_TLB_ENTRIES => 8, # Instruction section TLB entries.
-CODE_SPAGE_TLB_ENTRIES => 32, # Instruction small page TLB entries.
-CODE_LPAGE_TLB_ENTRIES => 16, # Instruction large page TLB entries.
-DATA_SECTION_TLB_ENTRIES => 8, # Data section TLB entries.
-DATA_SPAGE_TLB_ENTRIES => 32, # Data small page TLB entries.
-DATA_LPAGE_TLB_ENTRIES => 16, # Data large page TLB entries.
-BP_DEPTH => 1024,# Branch predictor depth.
-INSTR_FIFO_DEPTH => 4, # Instruction buffer depth.
-STORE_BUFFER_DEPTH => 8, # Store buffer depth.
-SYNTHESIS => 1, # Make this to 1 to simulate compile
- # from a synthesis perspective.
-
-# Testbench configuration.
-IRQ_EN => 1, # 1 Enables VIC connection to CPU in testbench.
-UART_TX_TERMINAL => 0, # 1 Enables UART TX terminal. 0 disables it.
-EXT_RAM_SIZE => 32768, # External RAM size in bytes.
-SEED => -1, # Seed. Use -1 to use random seed.
-DUMP_START => 2000, # Starting memory address from which to dump.
-DUMP_SIZE => 200, # Length of dump in bytes.
-MAX_CLOCK_CYCLES => 100000,# Clock cycles to run the simulation for.
-ALLOW_STALLS => 1, # Make this 1 to allow
- # external RAM to signal a stall.
-DEFINE_TLB_DEBUG => 0, # Make this 1 to define
- #TLB_DEBUG. Useful for debugging the TLB.
-
-# Make this an anonymous has with entries like
-# "r10" => "32'h0" etc. These represent register
-# values (expected) at the end of simulation.
-REG_CHECK => {"r1" => "32'h4",
- "r2" => "32'd3"},
-
-# Make this an anonymous hash with entries like
-# verilog_address => verilog_value etc. These
-# represent expected memory values at the end of
-# simulation.
-FINAL_CHECK => {"32'h100" => "32'd4",
- "32'h66" => "32'h4"}
-);
-
-\end{lstlisting}
-
-\section{IO Ports and Configuration}
-
-\begin{tabularx} {\linewidth}{|r|r|X|}
-\hline
-Signal Name & IO & Description \\ \hline
-
-I\_CLK &
-I &
-Core clock. \\ \hline
-
-I\_RESET &
-I &
-Core reset. \\ \hline
-
-O\_WB\_CYC &
-O &
-Wishbone CYC signal. \\ \hline
-
-O\_WB\_STB &
-O &
-Wishbone STB signal. \\ \hline
-
-O\_WB\_ADR[31:0] &
-O &
-Wishbone 32-bit address. \\ \hline
-
-O\_WB\_SEL[3:0] &
-O &
-Wishbone byte lane enables. \\ \hline
-
-O\_WB\_WE &
-O &
-Wishbone write enable. \\ \hline
-
-O\_WB\_DAT[31:0] &
-O &
-Wishbone write data. \\ \hline
-
-O\_WB\_CTI[2:0] &
-O &
-Wishbone cycle type indicator. \newline
-0b010 = Incrementing burst. \newline
-0b111 = End of burst. \newline
-The interface shall only generate one of the above 2 codes.
-A single transfer is effectively a burst of length 1.\\ \hline
-
-O\_WB\_BTE[1:0] &
-O &
-Burst type extension tag. This always reads 0x0 to indicate that
-the processor can only perform incrementing linear bursts (32-bit width).
-\\ \hline
-
-I\_WB\_DAT[31:0] &
-I &
-Wishbone read data. \\ \hline
-
-I\_WB\_ACK &
-I &
-Wishbone acknowledge. \\ \hline
-
-I\_IRQ &
-I &
-IRQ Interrupt. \\ \hline
-
-I\_FIQ &
-I &
-FIQ Interrupt. \\ \hline
-\end{tabularx}
-\\
-\\
-Verilog parameters can be used to statically configure the processor instance
-as shown in the table below.
-\\
-\\
-\begin{tabularx}{\linewidth}{|r|X|X|}
-\hline
-Parameter &
-Description &
-Notes \\ \hline
-
-DATA\_CACHE\_SIZE[31:0] &
-Data cache size in bytes. &
-1 \\ \hline
-
-CODE\_CACHE\_SIZE[31:0] &
-Instruction cache size in bytes. &
-1 \\ \hline
-
-CODE\_SECTION\_TLB\_ENTRIES[31:0] &
-Section TLB entries (CODE). &
-2 \\ \hline
-
-CODE\_SPAGE\_TLB\_ENTRIES[31:0] &
-Small page TLB entries (CODE). &
-2 \\ \hline
-
-CODE\_LPAGE\_TLB\_ENTRIES[31:0] &
-Large page TLB entries (CODE). &
-2 \\ \hline
-
-DATA\_SECTION\_TLB\_ENTRIES[31:0] &
-Section TLB entries (DATA). &
-2 \\ \hline
-
-DATA\_SPAGE\_TLB\_ENTRIES[31:0] &
-Small page TLB entries (DATA). &
-2 \\ \hline
-
-DATA\_LPAGE\_TLB\_ENTRIES[31:0] &
-Large page TLB entries (DATA). &
-2 \\ \hline
-
-FIFO\_DEPTH[31:0] &
-Depth of the fetch buffer in the pipeline. &
-3 \\ \hline
-
-BP\_ENTRIES[31:0] &
-Depth of the branch predictor memory. &
-3 \\ \hline
-
-STORE\_BUFFER\_DEPTH[31:0] &
-Set the depth of the store buffer. Do not set it to a value less than 16. &
-4 \\ \hline
-\end{tabularx}
-
-NOTE. \\
-
-1. Should be a power of 2 and greater than 128 bytes. \\
-
-2. Should be a power of 2 and must be at least 2 entries. \\
-
-3. Should be a power of 2 and must be greater than 2. \\
-
-4. Depth must be 16 or more and a power of 2. \\
-\\
-
-\section{CP15 commands}
-
-ZAP features an ARMv4 compatible cache subsystem (cache and MMU). This subsystem
-may be configured by issuing commands to specific CP \#15 registers using
-coprocessor instructions. A list of supported CP \#15 commands/registers are
-listed in the table below:
-\\
-\\
-WARNING: In particular, cleaning and flushing of specific locations is not
-supported. The OS should avoid issuing such commands.
-\\
-\\
-\begin{longtable}{|p{0.5cm}|p{2cm}|p{6cm}|p{0.5cm}|}
-\hline
-
-Reg. & Name & Description & Note \\ \hline
-
-0 &
-ID &
-[23:16] – Always reads 0x01 to indicate a v4 implementation. \newline
-Other bits are UNDEFINED. &
-1 \\ \hline
-
-1 &
-CON &
-[0] – MMU enable. \newline
-[2] – Data cache enable. \newline
-[8] – S bit. \newline
-[9] – R bit. \newline
-[12] – Instruction cache enable. \newline
-READ ONLY bits are described in note 2. \newline
-Bits other than the ones specified here and in note 2 are UNDEFINED. \newline
-2 \\ \hline
-
-2 &
-TRBASE &
-Holds 16KB aligned base address of L1 table. &
- \\ \hline
-
-3 &
-DAC &
-Domain Access Control Register. &
- \\ \hline
-
-5 &
-FSR &
-Fault address register. &
-4 \\ \hline
-
-6 &
-FAR &
-Fault status register. &
-4 \\ \hline
-
-7 &
-CACHECON &
-Data written to this register should be zero else UNDEFINED operations can occur. \newline
-\begin{tiny}
-CACHECON control table. \newline
- {\begin{tabularx}{\linewidth}{|X|X|X|}
- \hline
- Opcode2 &
- CRm &
- Description \\ \hline
- \hline
- 000 &
- 0111 &
- Flush all caches. \\ \hline
-
- 000 &
- 0101 &
- Flush I cache. \\ \hline
-
- 000 &
- 0110 &
- Flush D cache. \\ \hline
-
- 000 &
- 1011 &
- Clean all caches. \\ \hline
-
- 000 &
- 1010 &
- Clean D cache. \\ \hline
-
- 000 &
- 1111 &
- Clean and flush all caches. \\ \hline
-
- 000 &
- 1110 &
- Clean and flush D cache. \\ \hline
- \end{tabularx}} \end{tiny} &
-
-3 \\ \hline
-
-8 &
-TLBCON &
-Data written to this register should be zero else UNDEFINED operations can occur. \newline
-TLBCON Control table.\newline
- {\begin{tabularx}{\linewidth}{|X|X|X|}
- \hline
- Opcode2 &
- CRm &
- Description \\ \hline
- \hline
-
- 000 &
- 0111 &
- Flush all TLBs \\ \hline
-
- 000 &
- 0101 &
- Flush I TLB. \\ \hline
-
- 000 &
- 0110 &
- Flush D TLB. \\ \hline
- \end{tabularx}} &
-
-3 \\ \hline
-\end{longtable}
-
-NOTE:
-
-1. Read only. Writes have NO effect. \newline
-
-2. Processor does not check for address alignment ([1] reads 0), only supports
-Little Endian access, full 32-bit, write buffer always enabled ([7:4] reads 0b0011),
-does not support high vectors ([13] reads 0) and always has a predictable cache
-strategy ([11] reads 1) i.e., direct mapped. \newline
-
-3. Reads are UNPREDICTABLE. \newline
-
-4. Only data MMU can update this. For debug purposes, these are RW registers. \newline
-
-\end{document}
-
Index: zap/trunk/src/doc/images/image010.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: zap/trunk/src/doc/images/image010.png
===================================================================
--- zap/trunk/src/doc/images/image010.png (revision 42)
+++ zap/trunk/src/doc/images/image010.png (nonexistent)
zap/trunk/src/doc/images/image010.png
Property changes :
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: zap/trunk/src/doc/images/image012.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: zap/trunk/src/doc/images/image012.png
===================================================================
--- zap/trunk/src/doc/images/image012.png (revision 42)
+++ zap/trunk/src/doc/images/image012.png (nonexistent)
zap/trunk/src/doc/images/image012.png
Property changes :
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: zap/trunk/src/doc/images/image004.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: zap/trunk/src/doc/images/image004.png
===================================================================
--- zap/trunk/src/doc/images/image004.png (revision 42)
+++ zap/trunk/src/doc/images/image004.png (nonexistent)
zap/trunk/src/doc/images/image004.png
Property changes :
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: zap/trunk/src/doc/images/image006.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: zap/trunk/src/doc/images/image006.png
===================================================================
--- zap/trunk/src/doc/images/image006.png (revision 42)
+++ zap/trunk/src/doc/images/image006.png (nonexistent)
zap/trunk/src/doc/images/image006.png
Property changes :
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: zap/trunk/src/doc/images/image008.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: zap/trunk/src/doc/images/image008.png
===================================================================
--- zap/trunk/src/doc/images/image008.png (revision 42)
+++ zap/trunk/src/doc/images/image008.png (nonexistent)
zap/trunk/src/doc/images/image008.png
Property changes :
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: zap/trunk/src/doc/images/image001.jpg
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: zap/trunk/src/doc/images/image001.jpg
===================================================================
--- zap/trunk/src/doc/images/image001.jpg (revision 42)
+++ zap/trunk/src/doc/images/image001.jpg (nonexistent)
zap/trunk/src/doc/images/image001.jpg
Property changes :
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: zap/trunk/src/doc/images/image002.jpg
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: zap/trunk/src/doc/images/image002.jpg
===================================================================
--- zap/trunk/src/doc/images/image002.jpg (revision 42)
+++ zap/trunk/src/doc/images/image002.jpg (nonexistent)
zap/trunk/src/doc/images/image002.jpg
Property changes :
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: zap/trunk/src/rtl/cpu/zap_alu_main.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_alu_main.v (revision 42)
+++ zap/trunk/src/rtl/cpu/zap_alu_main.v (revision 43)
@@ -38,13 +38,6 @@
parameter [31:0] FLAG_WDT = 32'd32 // Width of active CPSR.
)
(
- /**********************************************************************
- *
- * INPUTS
- *
- *********************************************************************/
-
-
// ------------------------------------------------------------------
// Decompile Interface. Only for debug.
// ------------------------------------------------------------------
@@ -131,12 +124,6 @@
input wire [zap_clog2(ALU_OPS)-1:0] i_alu_operation_ff, // Operation to perform.
input wire i_flag_update_ff, // Update flags if 1.
- /**********************************************************************
- *
- * OUTPUTS
- *
- *********************************************************************/
-
// -----------------------------------------------------------------
// ALU result
// -----------------------------------------------------------------
@@ -202,40 +189,21 @@
);
// ----------------------------------------------------------------------------
+// Includes
+// ----------------------------------------------------------------------------
`include "zap_defines.vh"
`include "zap_localparams.vh"
`include "zap_functions.vh"
-wire [31:0] mem_srcdest_value_nxt;
-wire [3:0] ben_nxt;
+// -----------------------------------------------------------------------------
+// Localparams
+// -----------------------------------------------------------------------------
-// Address about to be output. Used to drive tag RAMs etc.
-reg [31:0] mem_address_nxt;
-
/*
- For memory stores, we must generate correct byte enables. This is done
- by examining access type inputs. For loads, always 1111 is generated.
- If there is neither a load or a store, the old value is preserved.
-*/
-assign ben_nxt = /*i_mem_store_ff ?*/ generate_ben (
- i_mem_unsigned_byte_enable_ff,
- i_mem_signed_byte_enable_ff,
- i_mem_unsigned_halfword_enable_ff,
- i_mem_unsigned_halfword_enable_ff,
- mem_address_nxt) /*: i_mem_load_ff ? 4'b1111 : o_ben_ff*/;
-
-assign mem_srcdest_value_nxt = duplicate (
- i_mem_unsigned_byte_enable_ff,
- i_mem_signed_byte_enable_ff,
- i_mem_unsigned_halfword_enable_ff,
- i_mem_unsigned_halfword_enable_ff,
- i_mem_srcdest_value_ff );
-
-/*
- These override global N,Z,C,V definitions which are on CPSR. These params
- are localized over the 4-bit flag structure.
-*/
+ * These override global N,Z,C,V definitions which are on CPSR. These params
+ * are localized over the 4-bit flag structure.
+ */
localparam [1:0] _N = 2'd3;
localparam [1:0] _Z = 2'd2;
localparam [1:0] _C = 2'd1;
@@ -247,6 +215,19 @@
localparam [1:0] WT = 2'd2;
localparam [1:0] ST = 2'd3;
+// ------------------------------------------------------------------------------
+// Variables
+// ------------------------------------------------------------------------------
+
+// Memory srcdest value (i.e., data)
+wire [31:0] mem_srcdest_value_nxt;
+
+// Byte enable generator.
+wire [3:0] ben_nxt;
+
+// Address about to be output. Used to drive tag RAMs etc.
+reg [31:0] mem_address_nxt;
+
/*
Sleep flop. When 1 unit sleeps i.e., does not produce any output except on
the first clock cycle where LR is calculated using the ALU.
@@ -268,6 +249,58 @@
reg [5:0] clz_rm; // Count leading zeros in Rm.
+// Destination index about to be output.
+reg [zap_clog2(PHY_REGS)-1:0] o_destination_index_nxt;
+
+// 1s complement of Rm and Rn.
+wire [31:0] not_rm = ~rm;
+wire [31:0] not_rn = ~rn;
+
+// Wires which connect to an adder.
+reg [31:0] op1, op2;
+reg cin;
+
+// 32-bit adder with carry input and carry output.
+wire [32:0] sum = {1'd0, op1} + {1'd0, op2} + {32'd0, cin};
+
+reg [31:0] tmp_flags, tmp_sum;
+
+// Opcode.
+wire [zap_clog2(ALU_OPS)-1:0] opcode = i_alu_operation_ff;
+
+// -------------------------------------------------------------------------------
+// Assigns
+// -------------------------------------------------------------------------------
+
+/*
+ For memory stores, we must generate correct byte enables. This is done
+ by examining access type inputs. For loads, always 1111 is generated.
+ If there is neither a load or a store, the old value is preserved.
+*/
+assign ben_nxt = generate_ben (
+ i_mem_unsigned_byte_enable_ff,
+ i_mem_signed_byte_enable_ff,
+ i_mem_unsigned_halfword_enable_ff,
+ i_mem_unsigned_halfword_enable_ff,
+ mem_address_nxt);
+
+assign mem_srcdest_value_nxt = duplicate (
+ i_mem_unsigned_byte_enable_ff,
+ i_mem_signed_byte_enable_ff,
+ i_mem_unsigned_halfword_enable_ff,
+ i_mem_unsigned_halfword_enable_ff,
+ i_mem_srcdest_value_ff );
+
+/*
+ Hijack interface. Data aborts use the hijack interface to find return
+ address. The writeback drives the ALU inputs to find the final output.
+*/
+assign o_hijack_sum = sum;
+
+// -------------------------------------------------------------------------------
+// CLZ logic.
+// -------------------------------------------------------------------------------
+
always @* // CLZ implementation.
begin
casez(rm)
@@ -307,32 +340,9 @@
endcase
end
-// Destination index about to be output.
-reg [zap_clog2(PHY_REGS)-1:0] o_destination_index_nxt;
-
-// 1s complement of Rm and Rn.
-wire [31:0] not_rm = ~rm;
-wire [31:0] not_rn = ~rn;
-
-// Wires which connect to an adder.
-reg [31:0] op1, op2;
-reg cin;
-
-// 32-bit adder with carry input and carry output.
-wire [32:0] sum = {1'd0, op1} + {1'd0, op2} + {32'd0, cin};
-
-reg [31:0] tmp_flags, tmp_sum;
-
-// Opcode.
-wire [zap_clog2(ALU_OPS)-1:0] opcode = i_alu_operation_ff;
-
-/*
- Hijack interface. Data aborts use the hijack interface to find return
- address. The writeback drives the ALU inputs to find the final output.
-*/
-assign o_hijack_sum = sum;
-
// ----------------------------------------------------------------------------
+// Aliases
+// ----------------------------------------------------------------------------
always @*
begin
@@ -342,15 +352,16 @@
o_flags_nxt = flags_nxt;
end
+// -----------------------------------------------------------------------------
// Sequential logic.
+// -----------------------------------------------------------------------------
+
always @ (posedge i_clk)
begin
if ( i_reset )
begin
- //
// On reset, processor enters supervisory mode with interrupts
// masked.
- //
clear ( {1'd1,1'd1,1'd0,SVC} );
end
else if ( i_clear_from_writeback )
@@ -415,7 +426,7 @@
// ----------------------------------------------------------------------------
-always @ (posedge i_clk) // Wishbone flops.
+always @ ( posedge i_clk ) // Wishbone flops.
begin
// Wishbone updates.
o_data_wb_cyc_ff <= o_data_wb_cyc_nxt;
@@ -426,7 +437,11 @@
o_mem_address_ff <= o_address_nxt;
end
-always @* // Wishbone next state logic.
+// -----------------------------------------------------------------------------
+// WB next state logic.
+// -----------------------------------------------------------------------------
+
+always @*
begin
// Preserve values.
o_data_wb_cyc_nxt = o_data_wb_cyc_ff;
@@ -446,9 +461,12 @@
o_data_wb_cyc_nxt = 0;
o_data_wb_stb_nxt = 0;
end
- else if ( i_data_stall ) begin end
+ else if ( i_data_stall )
+ begin
+ // Save state.
+ end
else if ( i_data_mem_fault || sleep_ff )
- begin
+ begin
o_data_wb_cyc_nxt = 0;
o_data_wb_stb_nxt = 0;
end
@@ -464,61 +482,40 @@
end
// ----------------------------------------------------------------------------
+// Used to generate access address.
+// ----------------------------------------------------------------------------
-always @*
-begin:pre_post_index
- // Memory address output based on pre or post index.
- if ( i_mem_pre_index_ff == 0 ) // Post-index. Update is done after memory access.
- mem_address_nxt = rn;
- else // Pre-index. Update is done before memory access.
- mem_address_nxt = o_alu_result_nxt;
-
- //
- // If a force 32 align is set, make the lower 2 bits as zero.
- // Force 32 align is valid for Thumb.
- //
- if ( i_force32align_ff )
- mem_address_nxt[1:0] = 2'b00;
-
- //
- // Do not change address if not needed.
- // If not a load OR a store. Preserve this value. Power saving.
- //
+always @ (*)
+begin:pre_post_index_address_generator
+ /*
+ * Do not change address if not needed.
+ * If not a load OR a store. Preserve this value. Power saving.
+ */
if (!( (i_mem_load_ff || i_mem_store_ff) && o_dav_nxt ))
mem_address_nxt = o_mem_address_ff;
+ else
+ begin
+ /*
+ * Memory address output based on pre or post index.
+ * For post-index, update is done after memory access.
+ * For pre-index, update is done before memory access.
+ */
+ if ( i_mem_pre_index_ff == 0 )
+ mem_address_nxt = rn; // Postindex;
+ else
+ mem_address_nxt = o_alu_result_nxt; // Preindex.
+
+ // If a force 32 align is set, make the lower 2 bits as zero.
+ if ( i_force32align_ff )
+ mem_address_nxt[1:0] = 2'b00;
+ end
end
-// ----------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------
+// Used to generate ALU result + Flags
+// ---------------------------------------------------------------------------------
-`ifndef SYNTHESIS
-
-reg [64*8-1:0] OPCODE;
-
always @*
-case(opcode)
-AND:begin OPCODE = "AND"; end
-EOR:begin OPCODE = "EOR"; end
-MOV:begin OPCODE = "MOV"; end
-MVN:begin OPCODE = "MVN"; end
-BIC:begin OPCODE = "BIC"; end
-ORR:begin OPCODE = "ORR"; end
-TST:begin OPCODE = "TST"; end
-TEQ:begin OPCODE = "TEQ"; end
-CLZ:begin OPCODE = "CLZ"; end
-FMOV:begin OPCODE = "FMOV"; end
-ADD:begin OPCODE = "ADD"; end
-ADC:begin OPCODE = "ADC"; end
-SUB:begin OPCODE = "SUB"; end
-RSB:begin OPCODE = "RSB"; end
-SBC:begin OPCODE = "SBC"; end
-RSC:begin OPCODE = "RSC"; end
-CMP:begin OPCODE = "CMP"; end
-CMN:begin OPCODE = "CMN"; end
-endcase
-
-`endif
-
-always @*
begin: alu_result
// Default value.
@@ -543,11 +540,11 @@
);
end
- //
- // Flag MOV i.e., MOV to CPSR or MMOV.
- // FMOV moves to CPSR and flushes the pipeline.
- // MMOV moves to SPSR and does not flush the pipeline.
- //
+ /*
+ * Flag MOV(FMOV) i.e., MOV to CPSR and MMOV handler.
+ * FMOV moves to CPSR and flushes the pipeline.
+ * MMOV moves to SPSR and does not flush the pipeline.
+ */
else if ( opcode == FMOV || opcode == MMOV )
begin: fmov_mmov
integer i;
@@ -566,11 +563,11 @@
tmp_sum[i] = rm[i];
end
- //
- // FMOV moves to the CPSR in ALU and writeback.
- // No register is changed. The MSR out of this will have
- // a target to CPSR.
- //
+ /*
+ * FMOV moves to the CPSR in ALU and writeback.
+ * No register is changed. The MSR out of this will have
+ * a target to CPSR.
+ */
if ( opcode == FMOV )
begin
tmp_flags = tmp_sum;
@@ -584,7 +581,7 @@
op = opcode;
- // Assign output of adder to flags.
+ // Assign output of adder to flags after some minimal logic.
c = sum[32];
z = (sum[31:0] == 0);
n = sum[31];
@@ -591,21 +588,13 @@
// Overflow.
if ( ( op == ADD || op == ADC || op == CMN ) && (rn[31] == rm[31]) && (sum[31] != rn[31]) )
- begin
v = 1;
- end
else if ( (op == RSB || op == RSC) && (rm[31] == !rn[31]) && (sum[31] != rm[31] ) )
- begin
v = 1;
- end
else if ( (op == SUB || op == SBC || op == CMP) && (rn[31] == !rm[31]) && (sum[31] != rn[31]) )
- begin
v = 1;
- end
else
- begin
v = 0;
- end
//
// If you choose not to update flags, do not change the flags.
@@ -623,6 +612,8 @@
end
// ----------------------------------------------------------------------------
+// Flag propagation and branch prediction feedback unit
+// ----------------------------------------------------------------------------
always @*
begin: flags_bp_feedback
@@ -641,9 +632,8 @@
begin
//
// Any sign of an interrupt is present, put unit to sleep.
- // The current instruction will not be executed ultimately
- // but rather a SUB LR, PC, 4 will be which will be stored in
- // the link register.
+ // The current instruction will not be executed ultimately.
+ // However o_dav_nxt = 1 since interrupt must be carried on.
//
o_dav_nxt = 1'd1;
sleep_nxt = 1'd1;
@@ -658,10 +648,10 @@
end
else if ( i_destination_index_ff == ARCH_PC && (i_condition_code_ff != NV))
begin
- if ( i_flag_update_ff && o_dav_nxt )
- // PC update with S bit.
- // Will restore CPU mode from SPSR. USR no change.
+ if ( i_flag_update_ff && o_dav_nxt ) // PC update with S bit. Context restore.
begin
+ $display($time, " - %m :: Saw PC update with S bit set. Context restore initiated.");
+
o_destination_index_nxt = PHY_RAZ_REGISTER;
o_clear_from_alu = 1'd1;
o_pc_from_alu = tmp_sum;
@@ -670,16 +660,23 @@
end
else if ( o_dav_nxt ) // Branch taken and no flag update.
begin
- if ( i_taken_ff == SNT || i_taken_ff == WNT )
- // Incorrectly predicted as not-taken.
+ if ( i_taken_ff == SNT || i_taken_ff == WNT ) // Incorrectly predicted.
begin
// Quick branches - Flush everything before.
-
- // Dumping ground since PC change is done.
+ // Dumping ground since PC change is done. Jump to branch target for fast switching.
o_destination_index_nxt = PHY_RAZ_REGISTER;
o_clear_from_alu = 1'd1;
o_pc_from_alu = tmp_sum;
- flags_nxt[T] = i_switch_ff ? tmp_sum[0] : flags_ff[T]; // Thumb/ARM state if i_switch_ff = 1.
+
+ if ( i_switch_ff )
+ begin
+ flags_nxt[T] = tmp_sum[0];
+
+ if ( tmp_sum[0] )
+ $display($time, " - %m :: Entering T state.");
+ else
+ $display($time, " - %m :: Entering A state.");
+ end
end
else // Correctly predicted.
begin
@@ -686,31 +683,28 @@
// If thumb bit changes, flush everything before
if ( i_switch_ff )
begin
- //
// Quick branches! PC goes to RAZ register since
// change is done.
- //
+
o_destination_index_nxt = PHY_RAZ_REGISTER;
-
o_clear_from_alu = 1'd1;
- o_pc_from_alu = tmp_sum;
- flags_nxt[T] = i_switch_ff ? tmp_sum[0] : flags_ff[T];
- // Thumb/ARM state if i_switch_ff = 1.
+ o_pc_from_alu = tmp_sum; // Jump to branch target.
+ flags_nxt[T] = tmp_sum[0];
+
+ if ( tmp_sum[0] )
+ $display($time, " - %m :: Entering T state.");
+ else
+ $display($time, " - %m :: Entering A state.");
end
else
begin
- //
- // No mode change, do not change
- // anything.
- //
+ // No mode change, do not change anything.
+
o_destination_index_nxt = PHY_RAZ_REGISTER;
- o_clear_from_alu = 1'd0;
- flags_nxt[T] = i_switch_ff ? tmp_sum[0]: flags_ff[T];
+ o_clear_from_alu = 1'd0;
- //
- // Send confirmation message to branch
- // predictor.
- //
+ // Send confirmation message to branch predictor.
+
o_pc_from_alu = 32'd0;
o_confirm_from_alu = 1'd1;
end
@@ -719,15 +713,16 @@
else // Branch not taken
begin
if ( i_taken_ff == WT || i_taken_ff == ST )
- // Wrong prediction as taken...
+ // Wrong prediction as taken. Go back to the same
+ // branch. Non branches are always predicted as not-taken.
+ // GO BACK TO THE SAME BRANCH AND INFORM PREDICTOR OF ITS
+ // MISTAKE - THE NEXT TIME THE PREDICTION WILL BE NOT-TAKEN.
begin
- // Go to the same branch.
o_clear_from_alu = 1'd1;
o_pc_from_alu = i_pc_ff;
end
- else
+ else // Correct prediction.
begin
- // Correct prediction.
o_clear_from_alu = 1'd0;
o_pc_from_alu = 32'd0;
end
@@ -736,6 +731,7 @@
else if ( i_mem_srcdest_index_ff == ARCH_PC && o_dav_nxt && i_mem_load_ff)
begin
// Loads to PC also puts the unit to sleep.
+ $display($time, " - %m :: ALU saw a load to R15. Sleeping to prevent further instructions from executing.");
sleep_nxt = 1'd1;
end
@@ -745,6 +741,8 @@
end
// ----------------------------------------------------------------------------
+// MUX structure on the inputs of the adder.
+// ----------------------------------------------------------------------------
// These are adder connections. Data processing and FMOV use these.
always @*
@@ -774,6 +772,7 @@
// Target is not written.
CMP: begin op1 = rn ; op2 = not_rm ; cin = 32'd1; end
CMN: begin op1 = rn ; op2 = rm ; cin = 32'd0; end
+
default:
begin
op1 = 0;
@@ -784,11 +783,18 @@
end
// ----------------------------------------------------------------------------
+// Functions
+// ----------------------------------------------------------------------------
// Process logical instructions.
function [35:0] process_logical_instructions
-( input [31:0] rn, rm, input [3:0] flags, input [zap_clog2(ALU_OPS)-1:0] op,
- input i_flag_upd, input nozero );
+(
+ input [31:0] rn,
+ input [31:0] rm,
+ input [3:0] flags,
+ input [zap_clog2(ALU_OPS)-1:0] op,
+ input i_flag_upd, input nozero
+);
begin: blk2
reg [31:0] rd;
reg [3:0] flags_out;
@@ -825,10 +831,8 @@
flags_out[_C] = i_shift_carry_ff;
if ( nozero )
- //
// This specifically states that we must NOT set the
// ZERO flag under any circumstance.
- //
flags_out[_Z] = 1'd0;
else
flags_out[_Z] = (rd == 0);
@@ -840,8 +844,11 @@
end
endfunction
-// ----------------------------------------------------------------------------
-
+/*
+ * This task clears out the flip-flops in this module.
+ * The flag input is used to preserve/force flags to
+ * a specific state.
+ */
task clear ( input [31:0] flags );
begin
o_dav_ff <= 0;
@@ -857,14 +864,18 @@
end
endtask
-// ----------------------------------------------------------------------------
+/*
+ * The reason we use the duplicate function is to copy value over the memory
+ * bus for memory stores. If we have a byte write to address 1, then the
+ * memory controller basically takes address 0 and byte enable 0010 and writes
+ * to address 1. This enables implementation of a 32-bit memory controller
+ * with byte enables to control updates as is commonly done. Basically this
+ * is to faciliate byte and halfword based writes on a 32-bit aligned memory
+ * bus using byte enables. The rules are simple:
+ * For a byte access - duplicate the lower byte of the register 4 times.
+ * For halfword access - duplicate the lower 16-bit of the register twice.
+ */
-// The reason we use the duplicate function is to copy value over the memory
-// bus for memory stores. If we have a byte write to address 1, then the
-// memory controller basically takes address 0 and byte enable 0010 and writes
-// to address 1. This enables implementation of a 32-bit memory controller
-// with byte enables to control updates as is common.
-
function [31:0] duplicate ( input ub, // Unsigned byte.
input sb, // Signed byte.
input uh, // Unsigned halfword.
@@ -891,9 +902,19 @@
end
endfunction
-// ----------------------------------------------------------------------------
-
-// Generate byte enables based on access mode.
+/*
+ * Generate byte enables based on access mode.
+ * This function is similar in spirit to the previous one. The
+ * byte enables are generated in such a way that along with
+ * duplicate - byte and halfword accesses are possible.
+ * Rules -
+ * For a byte access, generate a byte enable with a 1 at the
+ * position that the lower 2-bits read (0,1,2,3).
+ * For a halfword access, based on lower 2-bits, if it is 00,
+ * make no change to byte enable (0011) else if it is 10, then
+ * make byte enable as (1100) which is basically the 32-bit
+ * address + 2 (and 3) which will be written.
+ */
function [3:0] generate_ben ( input ub, // Unsigned byte.
input sb, // Signed byte.
input uh, // Unsigned halfword.
@@ -926,19 +947,48 @@
end
endfunction // generate_ben
-`ifndef SYNTHESIS
+// assertions_start
+ /*
+ * This assertion ensures that no privilege escalation is possible.
+ * It does so by ensuring that the flag register cannot change out
+ * of USR during normal operation.
+ */
always @*
begin
if ( flags_nxt[`CPSR_MODE] != USR && flags_ff[`CPSR_MODE] == USR )
begin
- $display($time, "Error: %m CPU is changing out of USR mode without an exception...");
+ $display($time, " - %m :: Error: Privilege Escalation Error.");
$stop;
end
end
-`endif
+ reg [64*8-1:0] OPCODE;
+
+ always @*
+ case(opcode)
+ AND:begin OPCODE = "AND"; end
+ EOR:begin OPCODE = "EOR"; end
+ MOV:begin OPCODE = "MOV"; end
+ MVN:begin OPCODE = "MVN"; end
+ BIC:begin OPCODE = "BIC"; end
+ ORR:begin OPCODE = "ORR"; end
+ TST:begin OPCODE = "TST"; end
+ TEQ:begin OPCODE = "TEQ"; end
+ CLZ:begin OPCODE = "CLZ"; end
+ FMOV:begin OPCODE = "FMOV"; end
+ ADD:begin OPCODE = "ADD"; end
+ ADC:begin OPCODE = "ADC"; end
+ SUB:begin OPCODE = "SUB"; end
+ RSB:begin OPCODE = "RSB"; end
+ SBC:begin OPCODE = "SBC"; end
+ RSC:begin OPCODE = "RSC"; end
+ CMP:begin OPCODE = "CMP"; end
+ CMN:begin OPCODE = "CMN"; end
+ endcase
+// assertions_end
+
endmodule // zap_alu_main.v
`default_nettype wire
/zap/trunk/src/rtl/cpu/zap_cache.v
1,7 → 1,7
// ----------------------------------------------------------------------------- |
// -- -- |
// -- (C) 2016-2018 Revanth Kamaraj. -- |
// -- -- |
// -- -- |
// -- -------------------------------------------------------------------------- |
// -- -- |
// -- This program is free software; you can redistribute it and/or -- |
20,9 → 20,9
// -- 02110-1301, USA. -- |
// -- -- |
// ----------------------------------------------------------------------------- |
// -- -- |
// -- -- |
// -- This is the top level cache module that contains the MMU and cache. -- |
// -- This will be instantiated twice in the processor TOP, once for -- |
// -- This will be instantiated twice in the processor TOP, once for -- |
// -- instruction and the other for data. -- |
// -- -- |
// ----------------------------------------------------------------------------- |
87,193 → 87,174
`include "zap_localparams.vh" |
`include "zap_functions.vh" |
|
wire [2:0] wb_stb; |
wire [2:0] wb_cyc; |
wire [2:0] wb_wen; |
wire [3:0] wb_sel [2:0]; |
wire [31:0] wb_dat [2:0]; |
wire [31:0] wb_adr [2:0]; |
wire [2:0] wb_cti [2:0]; |
localparam S0=0; |
localparam S1=1; |
localparam S2=2; |
|
assign wb_cti[2] = 0; |
wire [2:0] wb_stb; |
wire [2:0] wb_cyc; |
wire [2:0] wb_wen; |
wire [3:0] wb_sel [2:0]; |
wire [31:0] wb_dat [2:0]; |
wire [31:0] wb_adr [2:0]; |
wire [2:0] wb_cti [2:0]; |
wire [31:0] wb_dat0_cachefsm, wb_dat1_tagram, wb_dat2_tlb; |
wire [31:0] tlb_phy_addr; |
wire [7:0] tlb_fsr; |
wire [31:0] tlb_far; |
wire tlb_fault; |
wire tlb_cacheable; |
wire tlb_busy; |
wire [127:0] tr_cache_line; |
wire [127:0] cf_cache_line; |
wire [15:0] cf_cache_line_ben; |
wire cf_cache_tag_wr_en; |
wire [`CACHE_TAG_WDT-1:0] tr_cache_tag, cf_cache_tag; |
wire tr_cache_tag_valid; |
wire tr_cache_tag_dirty, cf_cache_tag_dirty; |
wire cf_cache_clean_req, cf_cache_inv_req; |
wire tr_cache_inv_done, tr_cache_clean_done; |
reg [2:0] wb_ack; |
reg [1:0] state_ff, state_nxt; |
|
wire [31:0] wb_dat0_cachefsm, wb_dat1_tagram, wb_dat2_tlb; |
wire [31:0] unused_dat = wb_dat0_cachefsm | wb_dat1_tagram | wb_dat2_tlb; |
// Data from each Wishbone master. |
assign wb_dat0_cachefsm = wb_dat[0]; |
assign wb_dat1_tagram = wb_dat[1]; |
assign wb_dat2_tlb = wb_dat[2]; |
assign wb_dat1_tagram = wb_dat[1]; |
assign wb_dat2_tlb = wb_dat[2]; |
|
wire [31:0] tlb_phy_addr; |
wire [7:0] tlb_fsr; |
wire [31:0] tlb_far; |
wire tlb_fault; |
wire tlb_cacheable; |
wire tlb_busy; |
// Bit 2 of Wishbone CTI is always on all CPU supported modes. |
assign wb_cti[2] = 0; |
|
wire [127:0] tr_cache_line; |
wire [127:0] cf_cache_line; |
wire [15:0] cf_cache_line_ben; |
wire cf_cache_tag_wr_en; |
|
wire [`CACHE_TAG_WDT-1:0] tr_cache_tag, cf_cache_tag; |
wire tr_cache_tag_valid; |
wire tr_cache_tag_dirty, cf_cache_tag_dirty; |
|
wire cf_cache_clean_req, cf_cache_inv_req; |
|
wire tr_cache_inv_done, tr_cache_clean_done; |
|
zap_cache_fsm #(.CACHE_SIZE(CACHE_SIZE)) |
u_zap_cache_fsm ( |
.i_clk (i_clk), |
.i_reset (i_reset), |
.i_address (i_address), |
.i_rd (i_rd), |
.i_wr (i_wr), |
.i_din (i_dat), |
.i_ben (i_ben), |
.o_dat (o_dat), |
.o_ack (o_ack), |
.o_err (o_err), |
.o_fsr (o_fsr), |
.o_far (o_far), |
.i_cache_en (i_cache_en), |
.i_cache_inv (i_cache_inv_req), |
.i_cache_clean (i_cache_clean_req), |
.o_cache_inv_done (o_cache_inv_done), |
.o_cache_clean_done (o_cache_clean_done), |
|
.i_cache_line (tr_cache_line), |
|
.i_cache_tag_dirty (tr_cache_tag_dirty), |
.i_cache_tag (tr_cache_tag), |
.i_cache_tag_valid (tr_cache_tag_valid), |
.o_cache_tag (cf_cache_tag), |
.o_cache_tag_dirty (cf_cache_tag_dirty), |
.o_cache_tag_wr_en (cf_cache_tag_wr_en), |
.o_cache_line (cf_cache_line), |
.o_cache_line_ben (cf_cache_line_ben), |
|
.o_cache_clean_req (cf_cache_clean_req), |
.i_cache_clean_done (tr_cache_clean_done), |
.o_cache_inv_req (cf_cache_inv_req), |
.i_cache_inv_done (tr_cache_inv_done), |
|
.i_phy_addr (tlb_phy_addr), |
.i_fsr (tlb_fsr), |
.i_far (tlb_far), |
.i_fault (tlb_fault), |
.i_cacheable (tlb_cacheable), |
.i_busy (tlb_busy), |
|
.o_wb_cyc_ff (), |
.o_wb_cyc_nxt (wb_cyc[0]), |
.o_wb_stb_ff (), |
.o_wb_stb_nxt (wb_stb[0]), |
.o_wb_adr_ff (), |
.o_wb_adr_nxt (wb_adr[0]), |
.o_wb_dat_ff (), |
.o_wb_dat_nxt (wb_dat[0]), |
.o_wb_sel_ff (), |
.o_wb_sel_nxt (wb_sel[0]), |
.o_wb_wen_ff (), |
.o_wb_wen_nxt (wb_wen[0]), |
.o_wb_cti_ff (), |
.o_wb_cti_nxt (wb_cti[0]), |
.i_wb_dat (i_wb_dat), |
.i_wb_ack (wb_ack[0]) |
// Basic cache FSM - serves as Master 0. |
zap_cache_fsm #(.CACHE_SIZE(CACHE_SIZE)) u_zap_cache_fsm ( |
.i_clk (i_clk), |
.i_reset (i_reset), |
.i_address (i_address), |
.i_rd (i_rd), |
.i_wr (i_wr), |
.i_din (i_dat), |
.i_ben (i_ben), |
.o_dat (o_dat), |
.o_ack (o_ack), |
.o_err (o_err), |
.o_fsr (o_fsr), |
.o_far (o_far), |
.i_cache_en (i_cache_en), |
.i_cache_inv (i_cache_inv_req), |
.i_cache_clean (i_cache_clean_req), |
.o_cache_inv_done (o_cache_inv_done), |
.o_cache_clean_done (o_cache_clean_done), |
.i_cache_line (tr_cache_line), |
.i_cache_tag_dirty (tr_cache_tag_dirty), |
.i_cache_tag (tr_cache_tag), |
.i_cache_tag_valid (tr_cache_tag_valid), |
.o_cache_tag (cf_cache_tag), |
.o_cache_tag_dirty (cf_cache_tag_dirty), |
.o_cache_tag_wr_en (cf_cache_tag_wr_en), |
.o_cache_line (cf_cache_line), |
.o_cache_line_ben (cf_cache_line_ben), |
.o_cache_clean_req (cf_cache_clean_req), |
.i_cache_clean_done (tr_cache_clean_done), |
.o_cache_inv_req (cf_cache_inv_req), |
.i_cache_inv_done (tr_cache_inv_done), |
.i_phy_addr (tlb_phy_addr), |
.i_fsr (tlb_fsr), |
.i_far (tlb_far), |
.i_fault (tlb_fault), |
.i_cacheable (tlb_cacheable), |
.i_busy (tlb_busy), |
.o_wb_cyc_ff (), |
.o_wb_cyc_nxt (wb_cyc[0]), |
.o_wb_stb_ff (), |
.o_wb_stb_nxt (wb_stb[0]), |
.o_wb_adr_ff (), |
.o_wb_adr_nxt (wb_adr[0]), |
.o_wb_dat_ff (), |
.o_wb_dat_nxt (wb_dat[0]), |
.o_wb_sel_ff (), |
.o_wb_sel_nxt (wb_sel[0]), |
.o_wb_wen_ff (), |
.o_wb_wen_nxt (wb_wen[0]), |
.o_wb_cti_ff (), |
.o_wb_cti_nxt (wb_cti[0]), |
.i_wb_dat (i_wb_dat), |
.i_wb_ack (wb_ack[0]) |
); |
|
zap_cache_tag_ram #(.CACHE_SIZE(CACHE_SIZE)) |
u_zap_cache_tag_ram ( |
|
.i_clk (i_clk), |
.i_reset (i_reset), |
.i_address_nxt (i_address_nxt), |
.i_address (i_address), |
|
.i_cache_en (i_cache_en), |
|
.i_cache_line (cf_cache_line), |
.o_cache_line (tr_cache_line), |
|
.i_cache_line_ben (cf_cache_line_ben), |
.i_cache_tag_wr_en (cf_cache_tag_wr_en), |
|
.i_cache_tag (cf_cache_tag), |
.i_cache_tag_dirty (cf_cache_tag_dirty), |
|
.o_cache_tag (tr_cache_tag), |
.o_cache_tag_valid (tr_cache_tag_valid), |
.o_cache_tag_dirty (tr_cache_tag_dirty), |
|
.i_cache_inv_req (cf_cache_inv_req), |
.o_cache_inv_done (tr_cache_inv_done), |
.i_cache_clean_req (cf_cache_clean_req), |
.o_cache_clean_done (tr_cache_clean_done), |
|
// Cache clean operations occur through these ports. |
.o_wb_cyc_ff (), |
.o_wb_cyc_nxt (wb_cyc[1]), |
.o_wb_stb_ff (), |
.o_wb_stb_nxt (wb_stb[1]), |
.o_wb_adr_ff (), |
.o_wb_adr_nxt (wb_adr[1]), |
.o_wb_dat_ff (), |
.o_wb_dat_nxt (wb_dat[1]), |
.o_wb_sel_ff (), |
.o_wb_sel_nxt (wb_sel[1]), |
.o_wb_wen_ff (), |
.o_wb_wen_nxt (wb_wen[1]), |
.o_wb_cti_ff (), |
.o_wb_cti_nxt (wb_cti[1]), |
.i_wb_dat (i_wb_dat), |
.i_wb_ack (wb_ack[1]) |
// Cache Tag RAM - As a master - this performs cache clean - Master 1. |
zap_cache_tag_ram #(.CACHE_SIZE(CACHE_SIZE)) u_zap_cache_tag_ram ( |
.i_clk (i_clk), |
.i_reset (i_reset), |
.i_address_nxt (i_address_nxt), |
.i_address (i_address), |
.i_cache_en (i_cache_en), |
.i_cache_line (cf_cache_line), |
.o_cache_line (tr_cache_line), |
.i_cache_line_ben (cf_cache_line_ben), |
.i_cache_tag_wr_en (cf_cache_tag_wr_en), |
.i_cache_tag (cf_cache_tag), |
.i_cache_tag_dirty (cf_cache_tag_dirty), |
.o_cache_tag (tr_cache_tag), |
.o_cache_tag_valid (tr_cache_tag_valid), |
.o_cache_tag_dirty (tr_cache_tag_dirty), |
.i_cache_inv_req (cf_cache_inv_req), |
.o_cache_inv_done (tr_cache_inv_done), |
.i_cache_clean_req (cf_cache_clean_req), |
.o_cache_clean_done (tr_cache_clean_done), |
.o_wb_cyc_ff (), |
.o_wb_cyc_nxt (wb_cyc[1]), |
.o_wb_stb_ff (), |
.o_wb_stb_nxt (wb_stb[1]), |
.o_wb_adr_ff (), |
.o_wb_adr_nxt (wb_adr[1]), |
.o_wb_dat_ff (), |
.o_wb_dat_nxt (wb_dat[1]), |
.o_wb_sel_ff (), |
.o_wb_sel_nxt (wb_sel[1]), |
.o_wb_wen_ff (), |
.o_wb_wen_nxt (wb_wen[1]), |
.o_wb_cti_ff (), |
.o_wb_cti_nxt (wb_cti[1]), |
.i_wb_dat (i_wb_dat), |
.i_wb_ack (wb_ack[1]) |
); |
|
// ZAP TLB control module. Includes TLB RAM inside. |
zap_tlb #( |
.LPAGE_TLB_ENTRIES (LPAGE_TLB_ENTRIES), |
.SPAGE_TLB_ENTRIES (SPAGE_TLB_ENTRIES), |
.SECTION_TLB_ENTRIES (SECTION_TLB_ENTRIES)) |
.LPAGE_TLB_ENTRIES (LPAGE_TLB_ENTRIES), |
.SPAGE_TLB_ENTRIES (SPAGE_TLB_ENTRIES), |
.SECTION_TLB_ENTRIES (SECTION_TLB_ENTRIES)) |
u_zap_tlb ( |
.i_clk (i_clk), |
.i_reset (i_reset), |
.i_address (i_address), |
.i_address_nxt (i_address_nxt), |
.i_rd (i_rd), |
.i_wr (i_wr), |
.i_cpsr (i_cpsr), |
.i_sr (i_sr), |
.i_dac_reg (i_dac_reg), |
.i_baddr (i_baddr), |
.i_mmu_en (i_mmu_en), |
.i_inv (i_tlb_inv), |
|
.o_phy_addr (tlb_phy_addr), |
.o_fsr (tlb_fsr), |
.o_far (tlb_far), |
.o_fault (tlb_fault), |
.o_cacheable (tlb_cacheable), |
.o_busy (tlb_busy), |
|
.o_wb_stb_nxt (wb_stb[2]), |
.o_wb_cyc_nxt (wb_cyc[2]), |
.o_wb_adr_nxt (wb_adr[2]), |
.o_wb_wen_nxt (wb_wen[2]), |
.o_wb_sel_nxt (wb_sel[2]), |
.o_wb_dat_nxt (wb_dat[2]), |
.i_wb_dat (i_wb_dat), |
.i_wb_ack (wb_ack[2]) |
.i_clk (i_clk), |
.i_reset (i_reset), |
.i_address (i_address), |
.i_address_nxt (i_address_nxt), |
.i_rd (i_rd), |
.i_wr (i_wr), |
.i_cpsr (i_cpsr), |
.i_sr (i_sr), |
.i_dac_reg (i_dac_reg), |
.i_baddr (i_baddr), |
.i_mmu_en (i_mmu_en), |
.i_inv (i_tlb_inv), |
.o_phy_addr (tlb_phy_addr), |
.o_fsr (tlb_fsr), |
.o_far (tlb_far), |
.o_fault (tlb_fault), |
.o_cacheable (tlb_cacheable), |
.o_busy (tlb_busy), |
.o_wb_stb_nxt (wb_stb[2]), |
.o_wb_cyc_nxt (wb_cyc[2]), |
.o_wb_adr_nxt (wb_adr[2]), |
.o_wb_wen_nxt (wb_wen[2]), |
.o_wb_sel_nxt (wb_sel[2]), |
.o_wb_dat_nxt (wb_dat[2]), |
.i_wb_dat (i_wb_dat), |
.i_wb_ack (wb_ack[2]) |
); |
|
localparam S0=0; |
localparam S1=1; |
localparam S2=2; |
|
reg [2:0] wb_ack; |
reg [1:0] state_ff, state_nxt; |
|
always @ (posedge i_clk) |
// Sequential Block |
always @ ( posedge i_clk ) |
begin |
if ( i_reset ) |
begin |
299,6 → 280,7
end |
end |
|
// Next state logic. |
always @* |
begin |
state_nxt = state_ff; |
315,6 → 297,7
end |
end |
|
// Route ACKs to respective masters. |
always @* |
begin |
wb_ack = 0; |
338,20 → 321,21
o_wb_wen_nxt = wb_wen[state_nxt]; |
end |
|
// synopsys translate_off |
reg xerr; |
initial xerr = 0; |
|
always @ (posedge i_clk) |
begin // Check if data delivered to processor is x. |
if ( o_dat[0] === 1'dx && o_ack && i_rd ) |
begin |
$display($time, "Error : %m Data went to x when giving data to core..."); |
xerr = xerr + 1; |
$stop; |
// assertions_start |
reg xerr = 0; |
|
always @ (posedge i_clk) |
begin |
// Check if data delivered to processor is 'x'. |
if ( o_dat[0] === 1'dx && o_ack && i_rd ) |
begin |
$display($time, "Error : %m Data went to x when giving data to core."); |
xerr = xerr + 1; |
$stop; |
end |
end |
end |
// synopsys translate_on |
// assertions_end |
|
endmodule |
endmodule // zap_cache |
|
`default_nettype wire |
/zap/trunk/src/rtl/cpu/zap_cache_fsm.v
32,9 → 32,15
`include "zap_defines.vh" |
|
module zap_cache_fsm #( |
parameter CACHE_SIZE = 1024 // Bytes. |
) /* Port List */ ( |
parameter CACHE_SIZE = 1024 // Bytes. |
) |
|
// ---------------------------------------------- |
// Port List |
// ---------------------------------------------- |
|
( |
|
/* Clock and reset */ |
input wire i_clk, |
input wire i_reset, |
99,14 → 105,14
|
); |
|
// ------------------------------------------------------------- |
// Includes and Localparams |
// ------------------------------------------------------------- |
|
`include "zap_localparams.vh" |
`include "zap_defines.vh" |
`include "zap_functions.vh" |
|
/* Signal aliases */ |
wire cache_cmp = (i_cache_tag[`CACHE_TAG__TAG] == i_address[`VA__CACHE_TAG]); |
wire cache_dirty = i_cache_tag_dirty; |
|
/* States */ |
localparam IDLE = 0; /* Resting state. */ |
localparam UNCACHEABLE = 1; /* Uncacheable access. */ |
116,39 → 122,53
localparam REFRESH = 5; /* Cache refresh parent state */ |
localparam INVALIDATE = 6; /* Cache invalidate parent state */ |
localparam CLEAN = 7; /* Cache clean parent state */ |
|
localparam NUMBER_OF_STATES = 8; |
|
/* Flops */ |
reg [$clog2(NUMBER_OF_STATES)-1:0] state_ff, state_nxt; |
reg [31:0] buf_ff [3:0]; |
reg [31:0] buf_nxt[3:0]; |
reg cache_clean_req_nxt, cache_clean_req_ff; |
reg cache_inv_req_nxt, cache_inv_req_ff; |
// --------------------------------------------------------------- |
// Signal aliases |
// --------------------------------------------------------------- |
|
/* Address Counter */ |
reg [2:0] adr_ctr_ff, adr_ctr_nxt; // Needs to take on 0,1,2,3 AND 4(nxt). |
wire cache_cmp = (i_cache_tag[`CACHE_TAG__TAG] == i_address[`VA__CACHE_TAG]); |
wire cache_dirty = i_cache_tag_dirty; |
|
reg hit; // debug. |
// --------------------------------------------------------------- |
// Variables |
// --------------------------------------------------------------- |
|
reg [$clog2(NUMBER_OF_STATES)-1:0] state_ff, state_nxt; |
reg [31:0] buf_ff [3:0]; |
reg [31:0] buf_nxt[3:0]; |
reg cache_clean_req_nxt, |
cache_clean_req_ff; |
reg cache_inv_req_nxt, |
cache_inv_req_ff; |
reg [2:0] adr_ctr_ff, adr_ctr_nxt; // Needs to take on 0,1,2,3 AND 4(nxt). |
reg hit; // For debug only. |
|
// ---------------------------------------------------------------- |
// Logic |
// ---------------------------------------------------------------- |
|
/* Tie flops to the output */ |
always @* o_cache_clean_req = cache_clean_req_ff; // Tie req flop to output. |
always @* o_cache_inv_req = cache_inv_req_ff; |
always @* o_cache_inv_req = cache_inv_req_ff; // Tie inv flop to output. |
|
/* Sequential Block */ |
always @ (posedge i_clk) |
begin |
if ( i_reset ) |
begin |
o_wb_cyc_ff <= 0; |
o_wb_stb_ff <= 0; |
o_wb_wen_ff <= 0; |
o_wb_sel_ff <= 0; |
o_wb_dat_ff <= 0; |
o_wb_cti_ff <= CTI_CLASSIC; |
o_wb_adr_ff <= 0; |
cache_clean_req_ff <= 0; |
cache_inv_req_ff <= 0; |
adr_ctr_ff <= 0; |
state_ff <= IDLE; |
o_wb_cyc_ff <= 0; |
o_wb_stb_ff <= 0; |
o_wb_wen_ff <= 0; |
o_wb_sel_ff <= 0; |
o_wb_dat_ff <= 0; |
o_wb_cti_ff <= CTI_CLASSIC; |
o_wb_adr_ff <= 0; |
cache_clean_req_ff <= 0; |
cache_inv_req_ff <= 0; |
adr_ctr_ff <= 0; |
state_ff <= IDLE; |
end |
else |
begin |
170,6 → 190,7
end |
end |
|
/* Combo block */ |
always @* |
begin |
/* Default values */ |
184,23 → 205,23
o_wb_sel_nxt = o_wb_sel_ff; |
cache_clean_req_nxt = cache_clean_req_ff; |
cache_inv_req_nxt = cache_clean_req_ff; |
o_fsr = 0; |
o_far = 0; |
o_cache_tag = 0; |
o_cache_inv_done = 0; |
o_cache_clean_done = 0; |
o_cache_tag_dirty = 0; |
o_cache_tag_wr_en = 0; |
o_cache_line = 0; |
o_cache_line_ben = 0; |
o_dat = 0; |
o_ack = 0; |
o_err = 0; |
buf_nxt[0] = buf_ff[0]; |
buf_nxt[1] = buf_ff[1]; |
buf_nxt[2] = buf_ff[2]; |
buf_nxt[3] = buf_ff[3]; |
hit = 0; |
o_fsr = 0; |
o_far = 0; |
o_cache_tag = 0; |
o_cache_inv_done = 0; |
o_cache_clean_done = 0; |
o_cache_tag_dirty = 0; |
o_cache_tag_wr_en = 0; |
o_cache_line = 0; |
o_cache_line_ben = 0; |
o_dat = 0; |
o_ack = 0; |
o_err = 0; |
buf_nxt[0] = buf_ff[0]; |
buf_nxt[1] = buf_ff[1]; |
buf_nxt[2] = buf_ff[2]; |
buf_nxt[3] = buf_ff[3]; |
hit = 0; |
|
case(state_ff) |
|
448,6 → 469,10
endcase |
end |
|
// ------------------------------------------------------------------------ |
// Tasks and functions. |
// ------------------------------------------------------------------------ |
|
function [31:0] adapt_cache_data |
(input [1:0] shift, input [127:0] cd); |
begin: blk1 |
473,8 → 498,6
end |
endfunction |
|
// ---------------------------------------------------------------------------- |
|
/* Function to generate Wishbone read signals. */ |
task wb_prpr_read; |
input [31:0] i_address; |
492,8 → 515,6
end |
endtask |
|
// ---------------------------------------------------------------------------- |
|
/* Function to generate Wishbone write signals */ |
task wb_prpr_write; |
input [31:0] i_data; |
513,8 → 534,6
end |
endtask |
|
// ---------------------------------------------------------------------------- |
|
/* Disables Wishbone */ |
task kill_access; |
begin |
531,10 → 550,13
// ---------------------------------------------------------------------------- |
|
// synopsys translate_off |
|
wire [31:0] buf0_ff, buf1_ff, buf2_ff; |
|
assign buf0_ff = buf_ff[0]; |
assign buf1_ff = buf_ff[1]; |
assign buf2_ff = buf_ff[2]; |
|
wire [31:0] buf3_ff = buf_ff[3]; |
wire [31:0] buf0_nxt = buf_nxt[0]; |
wire [31:0] buf1_nxt = buf_nxt[1]; |
548,5 → 570,6
|
// synopsys translate_on |
|
endmodule |
endmodule // zap_cache_fsm |
|
`default_nettype wire |
/zap/trunk/src/rtl/cpu/zap_cache_tag_ram.v
31,98 → 31,65
// ----------------------------------------------------------------------------- |
|
`default_nettype none |
`include "zap_defines.vh" |
|
module zap_cache_tag_ram ( // Verilog 1995 port syntax. Need to convert to 2001. |
module zap_cache_tag_ram #( |
|
i_clk, |
i_reset, |
parameter CACHE_SIZE = 1024 // Bytes. |
|
i_address_nxt, |
i_address, |
)( |
|
i_cache_en, |
input wire i_clk, |
input wire i_reset, |
input wire [31:0] i_address_nxt, |
input wire [31:0] i_address, |
input wire i_cache_en, |
input wire [127:0] i_cache_line, |
input wire [15:0] i_cache_line_ben, |
output reg [127:0] o_cache_line, |
input wire i_cache_tag_wr_en, |
input wire [`CACHE_TAG_WDT-1:0] i_cache_tag, |
input wire i_cache_tag_dirty, |
|
i_cache_line, |
o_cache_line, |
output reg [`CACHE_TAG_WDT-1:0] o_cache_tag, |
output reg o_cache_tag_valid, |
output reg o_cache_tag_dirty, |
input wire i_cache_clean_req, |
output reg o_cache_clean_done, |
input wire i_cache_inv_req, |
output reg o_cache_inv_done, |
|
i_cache_line_ben, |
/* |
* Cache clean operations occur through these ports. |
* Memory access ports, both NXT and FF. Usually you'll be connecting NXT ports |
*/ |
output reg o_wb_cyc_ff, o_wb_cyc_nxt, |
output reg o_wb_stb_ff, o_wb_stb_nxt, |
output reg [31:0] o_wb_adr_ff, o_wb_adr_nxt, |
output reg [31:0] o_wb_dat_ff, o_wb_dat_nxt, |
output reg [3:0] o_wb_sel_ff, o_wb_sel_nxt, |
output reg o_wb_wen_ff, o_wb_wen_nxt, |
output reg [2:0] o_wb_cti_ff, o_wb_cti_nxt, /* Cycle Type Indicator - 010, 111 */ |
input wire [31:0] i_wb_dat, |
input wire i_wb_ack |
|
i_cache_tag_wr_en, |
i_cache_tag, |
i_cache_tag_dirty, |
|
o_cache_tag, |
o_cache_tag_valid, |
o_cache_tag_dirty, |
|
i_cache_inv_req, |
o_cache_inv_done, |
|
i_cache_clean_req, |
o_cache_clean_done, |
|
// Cache clean operations occur through these ports. |
o_wb_stb_nxt, o_wb_stb_ff, |
o_wb_cyc_nxt, o_wb_cyc_ff, |
o_wb_adr_nxt, o_wb_adr_ff, |
o_wb_wen_nxt, o_wb_wen_ff, |
o_wb_sel_nxt, o_wb_sel_ff, |
o_wb_dat_nxt, o_wb_dat_ff, |
o_wb_cti_nxt, o_wb_cti_ff, |
i_wb_ack, i_wb_dat |
|
); |
|
// ---------------------------------------------------------------------------- |
|
`include "zap_localparams.vh" |
`include "zap_defines.vh" |
|
parameter CACHE_SIZE = 1024; // Bytes. |
localparam NUMBER_OF_DIRTY_BLOCKS = ((CACHE_SIZE/16)/16); // Keep cache size > 16 bytes. |
|
input wire i_clk; |
input wire i_reset; |
// States. |
localparam IDLE = 0; |
localparam CACHE_CLEAN_GET_ADDRESS = 1; |
localparam CACHE_CLEAN_WRITE = 2; |
localparam CACHE_INV = 3; |
|
input wire [31:0] i_address_nxt; |
input wire [31:0] i_address; |
|
input wire i_cache_en; |
|
input wire [127:0] i_cache_line; |
input wire [15:0] i_cache_line_ben; |
output reg [127:0] o_cache_line; |
|
input wire i_cache_tag_wr_en; |
input wire [`CACHE_TAG_WDT-1:0] i_cache_tag; |
input wire i_cache_tag_dirty; |
|
output reg [`CACHE_TAG_WDT-1:0] o_cache_tag; |
output reg o_cache_tag_valid; |
output reg o_cache_tag_dirty; |
|
input wire i_cache_clean_req; |
output reg o_cache_clean_done; |
|
input wire i_cache_inv_req; |
output reg o_cache_inv_done; |
|
/* Memory access ports, both NXT and FF. Usually you'll be connecting NXT ports */ |
output reg o_wb_cyc_ff, o_wb_cyc_nxt; |
output reg o_wb_stb_ff, o_wb_stb_nxt; |
output reg [31:0] o_wb_adr_ff, o_wb_adr_nxt; |
output reg [31:0] o_wb_dat_ff, o_wb_dat_nxt; |
output reg [3:0] o_wb_sel_ff, o_wb_sel_nxt; |
output reg o_wb_wen_ff, o_wb_wen_nxt; |
output reg [2:0] o_wb_cti_ff, o_wb_cti_nxt; /* Cycle Type Indicator - 010, 111 */ |
input wire [31:0] i_wb_dat; |
input wire i_wb_ack; |
|
// ---------------------------------------------------------------------------- |
|
localparam NUMBER_OF_DIRTY_BLOCKS = ((CACHE_SIZE/16)/16); // Keep cache size > 16 bytes. |
|
// ---------------------------------------------------------------------------- |
|
reg [(CACHE_SIZE/16)-1:0] dirty; |
reg [(CACHE_SIZE/16)-1:0] valid; |
reg [`CACHE_TAG_WDT-1:0] tag_ram [(CACHE_SIZE/16)-1:0]; |
138,13 → 105,18
|
// ---------------------------------------------------------------------------- |
|
reg [1:0] state_ff, state_nxt; |
|
// ---------------------------------------------------------------------------- |
|
reg [$clog2(NUMBER_OF_DIRTY_BLOCKS)-1:0] blk_ctr_ff, blk_ctr_nxt; |
reg [2:0] adr_ctr_ff, adr_ctr_nxt; |
reg [2:0] adr_ctr_ff, adr_ctr_nxt; |
|
// ---------------------------------------------------------------------------- |
|
initial |
begin: blk1 |
// FPGA anyway initializes to 0 on start. |
integer i; |
|
for(i=0;i<CACHE_SIZE/16;i=i+1) |
194,8 → 166,6
|
// ---------------------------------------------------------------------------- |
|
//integer i; |
|
always @ (posedge i_clk) |
begin |
o_cache_tag_dirty <= dirty [ tag_ram_rd_addr ]; |
220,27 → 190,20
|
// ---------------------------------------------------------------------------- |
|
localparam IDLE = 0; |
localparam CACHE_CLEAN_GET_ADDRESS = 1; |
localparam CACHE_CLEAN_WRITE = 2; |
localparam CACHE_INV = 3; |
|
reg [1:0] state_ff, state_nxt; |
|
always @ (posedge i_clk) |
begin |
if ( i_reset ) |
begin |
o_wb_cyc_ff <= 0; |
o_wb_stb_ff <= 0; |
o_wb_wen_ff <= 0; |
o_wb_sel_ff <= 0; |
o_wb_dat_ff <= 0; |
o_wb_cti_ff <= CTI_CLASSIC; |
o_wb_adr_ff <= 0; |
adr_ctr_ff <= 0; |
blk_ctr_ff <= 0; |
state_ff <= IDLE; |
o_wb_cyc_ff <= 0; |
o_wb_stb_ff <= 0; |
o_wb_wen_ff <= 0; |
o_wb_sel_ff <= 0; |
o_wb_dat_ff <= 0; |
o_wb_cti_ff <= CTI_CLASSIC; |
o_wb_adr_ff <= 0; |
adr_ctr_ff <= 0; |
blk_ctr_ff <= 0; |
state_ff <= IDLE; |
end |
else |
begin |
253,23 → 216,12
o_wb_adr_ff <= o_wb_adr_nxt; |
adr_ctr_ff <= adr_ctr_nxt; |
blk_ctr_ff <= blk_ctr_nxt; |
state_ff <= state_nxt; |
state_ff <= state_nxt; |
end |
end |
|
// ---------------------------------------------------------------------------- |
|
|
|
function [4:0] baggage ( input [CACHE_SIZE/16-1:0] dirty, input [31:0] blk_ctr_ff ); |
reg [31:0] shamt; |
integer i; |
begin |
shamt = blk_ctr_ff << 4; |
baggage = pri_enc1(dirty >> shamt); |
end |
endfunction |
|
always @* |
begin |
|
313,18 → 265,16
tag_ram_wr_en = 0; |
blk_ctr_nxt = 0; |
|
`ifndef SYNTHESIS |
$display($time, "%m :: INFO :: Cache clean requested..."); |
// assertions_start |
|
$display($time, " - %m :: Cache clean requested..."); |
|
for(i=0;i<CACHE_SIZE/16;i=i+1) |
begin |
$display("Line %d : %x %d", i, dat_ram[i], dirty[i]); |
$display($time, " - %m :: Line %d : %x %d", i, dat_ram[i], dirty[i]); |
end |
|
`ifdef CACHE_DEBUG |
$stop; |
`endif |
`endif |
// assertions_end |
|
|
state_nxt = CACHE_CLEAN_GET_ADDRESS; |
403,6 → 353,8
endcase |
end |
|
// ----------------------------------------------------------------------------- |
|
// Priority encoder. |
function [4:0] pri_enc1 ( input [15:0] in ); |
begin: priEncFn |
428,6 → 380,8
end |
endfunction |
|
// ----------------------------------------------------------------------------- |
|
function [31:0] get_tag_ram_rd_addr ( |
input [31:0] blk_ctr, |
input [CACHE_SIZE/16-1:0] dirty |
450,7 → 404,7
input [31:0] i_address; |
input [2:0] i_cti; |
begin |
$display($time, "%m :: Reading from address %x", i_address); |
$display($time, " - %m :: Reading from address %x", i_address); |
|
o_wb_cyc_nxt = 1'd1; |
o_wb_stb_nxt = 1'd1; |
458,7 → 412,7
o_wb_sel_nxt = 4'b1111; |
o_wb_adr_nxt = i_address; |
o_wb_cti_nxt = i_cti; |
o_wb_dat_nxt = 0; |
o_wb_dat_nxt = 0; |
end |
endtask |
|
498,5 → 452,14
|
// ---------------------------------------------------------------------------- |
|
function [4:0] baggage ( input [CACHE_SIZE/16-1:0] dirty, input [31:0] blk_ctr_ff ); |
reg [31:0] shamt; |
integer i; |
begin |
shamt = blk_ctr_ff << 4; |
baggage = pri_enc1(dirty >> shamt); |
end |
endfunction |
|
endmodule // zap_cache_tag_ram.v |
`default_nettype wire |
/zap/trunk/src/rtl/cpu/zap_core.v
34,14 → 34,20
|
// Depth of FIFO. |
parameter [31:0] FIFO_DEPTH = 4 |
) |
) |
( |
|
// Clock and reset. |
input wire i_clk, // ZAP clock. |
input wire i_reset, // Active high synchronous reset. |
// ------------------------------------------------ |
// Clock and reset. Reset is synchronous. |
// ------------------------------------------------ |
|
input wire i_clk, |
input wire i_reset, |
|
// ------------------------------------------------- |
// Wishbone memory access for data. |
// ------------------------------------------------- |
|
output wire o_data_wb_we, |
output wire o_data_wb_cyc, |
output wire o_data_wb_stb, |
63,11 → 69,17
// Force user view. |
output wire o_mem_translate, |
|
// -------------------------------------------------- |
// Interrupts. Active high. |
// -------------------------------------------------- |
|
input wire i_fiq, // FIQ signal. |
input wire i_irq, // IRQ signal. |
|
// --------------------------------------------------- |
// Wishbone instruction access ports. |
// --------------------------------------------------- |
|
output wire [31:0] o_instr_wb_adr, // Code address. |
output wire o_instr_wb_cyc, // Always 1. |
output wire o_instr_wb_stb, // Always 1. |
84,7 → 96,10
// Determines user or supervisory mode. Cache must use this for VM. |
output wire [31:0] o_cpsr, |
|
// ----------------------------------------------------- |
// For MMU/cache connectivity. |
// ----------------------------------------------------- |
|
input wire [31:0] i_fsr, |
input wire [31:0] i_far, |
output wire [31:0] o_dac, |
91,6 → 106,7
output wire [31:0] o_baddr, |
output wire o_mmu_en, |
output wire [1:0] o_sr, |
output wire o_pid, |
output wire o_dcache_inv, |
output wire o_icache_inv, |
output wire o_dcache_clean, |
102,17 → 118,7
input wire i_dcache_inv_done, |
input wire i_icache_inv_done, |
input wire i_dcache_clean_done, |
input wire i_icache_clean_done, |
|
// Pipeline stall and clear signals. Hi to lo priority order. Sent out of the |
// core for use outside. These are generally not used. |
// |
output wire o_clear_from_writeback, // | |
output wire o_clear_from_alu, // | |
output wire o_stall_from_shifter, // | |
output wire o_stall_from_issue, // | |
output wire o_stall_from_decode, // | Low Priority. |
output wire o_clear_from_decode // V |
input wire i_icache_clean_done |
); |
|
// ---------------------------------------------------------------------------- |
131,7 → 137,7
|
// Low Bandwidth Coprocessor (COP) I/F to CP15 control block. |
wire copro_done; // COP done. |
wire copro_dav; // COP command valid. |
wire copro_dav; // COP command valid. |
wire [31:0] copro_word; // COP command. |
wire copro_reg_en; // COP controls registers. |
wire [$clog2(PHY_REGS)-1:0] copro_reg_wr_index;// Reg. file write index. |
139,48 → 145,60
wire [31:0] copro_reg_wr_data; // Reg. file write data. |
wire [31:0] copro_reg_rd_data; // Reg. file read data. |
|
wire reset; // From reset synchronizer. |
wire reset; // Tied to i_reset. |
wire shelve; // From writeback. |
wire fiq; // Tied to FIQ. |
wire irq; // Tied to IRQ. |
|
// From writeback. |
wire shelve; |
|
// Interrupt synchronizer. |
wire fiq; |
wire irq; |
|
// Clear and stall signals. |
wire stall_from_decode; |
wire clear_from_alu; |
wire stall_from_issue; |
wire clear_from_writeback; |
wire stall_from_decode; |
wire clear_from_alu; |
wire stall_from_issue; |
wire clear_from_writeback; |
wire data_stall; |
wire code_stall; |
wire instr_valid; |
wire pipeline_is_not_empty; |
|
// Fetch |
wire [31:0] fetch_instruction; // Instruction from the fetch unit. |
wire fetch_valid; // Instruction valid from the fetch unit. |
wire fetch_instr_abort; // abort indicator. |
wire [31:0] fetch_pc_plus_8_ff; // PC + 8 generated from the fetch unit. |
wire [31:0] fetch_pc_ff; // PC generated from fetch unit. |
wire [1:0] fetch_bp_state; |
wire [31:0] fetch_instruction; // Instruction from the fetch unit. |
wire fetch_valid; // Instruction valid from the fetch unit. |
wire fetch_instr_abort; // abort indicator. |
wire [31:0] fetch_pc_plus_8_ff; // PC + 8 generated from the fetch unit. |
wire [31:0] fetch_pc_ff; // PC generated from fetch unit. |
wire [1:0] fetch_bp_state; |
|
// FIFO. |
wire [31:0] fifo_pc_plus_8; |
wire fifo_valid; |
wire fifo_instr_abort; |
wire [31:0] fifo_instruction; |
wire [1:0] fifo_bp_state; |
wire [31:0] fifo_pc_plus_8; |
wire fifo_valid; |
wire fifo_instr_abort; |
wire [31:0] fifo_instruction; |
wire [1:0] fifo_bp_state; |
|
// Predecode |
wire [31:0] predecode_pc_plus_8; |
wire [31:0] predecode_pc; |
wire predecode_irq; |
wire predecode_fiq; |
wire predecode_abt; |
wire [35:0] predecode_inst; |
wire predecode_val; |
wire predecode_force32; |
wire predecode_und; |
wire [1:0] predecode_taken; |
wire [31:0] predecode_pc_plus_8; |
wire [31:0] predecode_pc; |
wire predecode_irq; |
wire predecode_fiq; |
wire predecode_abt; |
wire [35:0] predecode_inst; |
wire predecode_val; |
wire predecode_force32; |
wire predecode_und; |
wire [1:0] predecode_taken; |
|
// Compressed decoder. |
wire thumb_irq; |
wire thumb_fiq; |
wire thumb_iabort; |
wire [34:0] thumb_instruction; |
wire thumb_valid; |
wire thumb_und; |
wire thumb_force32; |
wire [1:0] thumb_bp_state; |
wire [31:0] thumb_pc_ff; |
wire [31:0] thumb_pc_plus_8_ff; |
|
// Decode |
wire [3:0] decode_condition_code; |
wire [$clog2(PHY_REGS)-1:0] decode_destination_index; |
329,44 → 347,46
wire memory_data_abt_ff; |
|
// Writeback |
wire [31:0] rd_data_0; |
wire [31:0] rd_data_1; |
wire [31:0] rd_data_2; |
wire [31:0] rd_data_3; |
wire [31:0] cpsr_nxt, cpsr; |
wire [31:0] rd_data_0; |
wire [31:0] rd_data_1; |
wire [31:0] rd_data_2; |
wire [31:0] rd_data_3; |
wire [31:0] cpsr_nxt, cpsr; |
|
wire wb_hijack; |
wire [31:0] wb_hijack_op1; |
wire [31:0] wb_hijack_op2; |
wire wb_hijack_cin; |
wire [31:0] alu_hijack_sum; |
// Hijack interface - related to Writeback - ALU interaction. |
wire wb_hijack; |
wire [31:0] wb_hijack_op1; |
wire [31:0] wb_hijack_op2; |
wire wb_hijack_cin; |
wire [31:0] alu_hijack_sum; |
|
// ---------------------------------------------------------------------------- |
// Decompile chain for debugging. |
wire [64*8-1:0] decode_decompile; |
wire [64*8-1:0] issue_decompile; |
wire [64*8-1:0] shifter_decompile; |
wire [64*8-1:0] alu_decompile; |
wire [64*8-1:0] memory_decompile; |
wire [64*8-1:0] rb_decompile; |
|
assign o_cpsr = alu_flags_ff; |
|
// Pipeline controls exposed. |
assign o_clear_from_writeback = clear_from_writeback; |
assign o_clear_from_alu = clear_from_alu; |
assign o_stall_from_shifter = stall_from_shifter; |
assign o_stall_from_issue = stall_from_issue; |
assign o_stall_from_decode = stall_from_decode; |
assign o_clear_from_decode = clear_from_decode; |
|
|
// Data wishbone signals (defaults). |
assign o_data_wb_adr = {alu_address_ff[31:2], 2'd0}; |
assign o_data_wb_adr_nxt = {alu_address_nxt[31:2], 2'd0}; |
|
// Default Wishbone values (Code). |
assign o_instr_wb_we = 1'd0; |
assign o_instr_wb_sel = 4'b1111; |
|
// ---------------------------------------------------------------------------- |
|
assign reset = i_reset; // Assume external synchronizer. |
assign irq = i_irq; // Assume externally synchronized to core clock. |
assign fiq = i_fiq; // Assume externally synchronized to core clock. |
assign o_cpsr = alu_flags_ff; |
assign o_data_wb_adr = {alu_address_ff[31:2], 2'd0}; |
assign o_data_wb_adr_nxt = {alu_address_nxt[31:2], 2'd0}; |
assign o_instr_wb_we = 1'd0; |
assign o_instr_wb_sel = 4'b1111; |
assign reset = i_reset; |
assign irq = i_irq; |
assign fiq = i_fiq; |
assign data_stall = o_data_wb_stb && o_data_wb_cyc && !i_data_wb_ack; |
assign code_stall = (!o_instr_wb_stb && !o_instr_wb_cyc) || !i_instr_wb_ack; |
assign instr_valid = o_instr_wb_stb && o_instr_wb_cyc && i_instr_wb_ack & !shelve; |
assign pipeline_is_not_empty = predecode_val || |
(decode_condition_code != NV) || |
(issue_condition_code_ff != NV) || |
(shifter_condition_code_ff!= NV) || |
alu_dav_ff || |
memory_dav_ff; |
|
// ---------------------------------------------------------------------------- |
|
382,7 → 402,7
.i_clk (i_clk), |
.i_reset (reset), |
|
.i_code_stall ((!o_instr_wb_stb && !o_instr_wb_cyc) || !i_instr_wb_ack), |
.i_code_stall (code_stall), |
|
.i_clear_from_writeback (clear_from_writeback), |
.i_clear_from_decode (clear_from_decode), |
397,7 → 417,7
|
.i_pc_ff (o_instr_wb_adr), |
.i_instruction (i_instr_wb_dat), |
.i_valid (o_instr_wb_stb && o_instr_wb_cyc && i_instr_wb_ack & !shelve), |
.i_valid (instr_valid), |
.i_instr_abort (i_instr_wb_err), |
|
.i_cpsr_ff_t (alu_flags_ff[T]), |
413,7 → 433,7
.i_confirm_from_alu (confirm_from_alu), |
.i_pc_from_alu (shifter_pc_ff), |
.i_taken (shifter_taken_ff), |
.o_taken_ff (fetch_bp_state) |
.o_taken (fetch_bp_state) |
); |
|
// ========================= |
421,84 → 441,63
// ========================= |
zap_fifo |
#( .WDT(67), .DEPTH(FIFO_DEPTH) ) U_ZAP_FIFO ( |
.i_clk(i_clk), |
.i_reset(i_reset), |
.i_clear_from_writeback(clear_from_writeback), |
.i_clk (i_clk), |
.i_reset (i_reset), |
.i_clear_from_writeback (clear_from_writeback), |
|
.i_write_inhibit ( (!o_instr_wb_stb && !o_instr_wb_cyc) || !i_instr_wb_ack ), |
.i_write_inhibit ( code_stall ), |
.i_data_stall ( data_stall ), |
|
.i_data_stall( |
o_data_wb_stb && |
o_data_wb_cyc && |
!i_data_wb_ack |
), |
.i_clear_from_alu (clear_from_alu), |
.i_stall_from_shifter (stall_from_shifter), |
.i_stall_from_issue (stall_from_issue), |
.i_stall_from_decode (stall_from_decode), |
.i_clear_from_decode (clear_from_decode), |
|
.i_clear_from_alu(clear_from_alu), |
.i_stall_from_shifter(stall_from_shifter), |
.i_stall_from_issue(stall_from_issue), |
.i_stall_from_decode(stall_from_decode), |
.i_clear_from_decode(clear_from_decode), |
.i_instr ({fetch_pc_plus_8_ff, fetch_instr_abort, fetch_instruction, fetch_bp_state}), |
.i_valid (fetch_valid), |
.o_instr ({fifo_pc_plus_8, fifo_instr_abort, fifo_instruction, fifo_bp_state}), |
.o_valid (fifo_valid), |
|
.i_instr({fetch_pc_plus_8_ff, fetch_instr_abort, fetch_instruction, fetch_bp_state}), |
.i_valid(fetch_valid), |
|
.o_instr({fifo_pc_plus_8, fifo_instr_abort, fifo_instruction, fifo_bp_state}), |
.o_valid(fifo_valid), |
|
.o_wb_stb(o_instr_wb_stb), |
.o_wb_stb_nxt(o_instr_wb_stb_nxt), |
.o_wb_cyc(o_instr_wb_cyc) |
.o_wb_stb (o_instr_wb_stb), |
.o_wb_stb_nxt (o_instr_wb_stb_nxt), |
.o_wb_cyc (o_instr_wb_cyc) |
); |
|
wire thumb_irq; |
wire thumb_fiq; |
wire thumb_iabort; |
wire [34:0] thumb_instruction; |
wire thumb_valid; |
wire thumb_und; |
wire thumb_force32; |
wire [1:0] thumb_bp_state; |
wire [31:0] thumb_pc_ff; |
wire [31:0] thumb_pc_plus_8_ff; |
|
// ========================= |
// COMPRESSED DECODER STAGE |
// ========================= |
zap_thumb_decoder u_zap_thumb_decoder ( |
.i_clk (i_clk), |
.i_reset (i_reset), |
.i_clear_from_writeback(clear_from_writeback), |
.i_data_stall ( |
o_data_wb_stb && |
o_data_wb_cyc && |
!i_data_wb_ack |
), |
.i_clear_from_alu(clear_from_alu), |
.i_stall_from_shifter(stall_from_shifter), |
.i_stall_from_issue(stall_from_issue), |
.i_stall_from_decode(stall_from_decode), |
.i_clear_from_decode(clear_from_decode), |
.i_clk (i_clk), |
.i_reset (i_reset), |
.i_clear_from_writeback (clear_from_writeback), |
.i_data_stall (data_stall), |
.i_clear_from_alu (clear_from_alu), |
.i_stall_from_shifter (stall_from_shifter), |
.i_stall_from_issue (stall_from_issue), |
.i_stall_from_decode (stall_from_decode), |
.i_clear_from_decode (clear_from_decode), |
|
.i_taken (fifo_bp_state), |
.i_instruction (fifo_instruction), |
.i_instruction_valid(fifo_valid), |
.i_irq (fifo_valid ? irq && !alu_flags_ff[I] : 1'd0), // Pass interrupt only if mask = 0 and instruction exists. |
.i_fiq (fifo_valid ? fiq && !alu_flags_ff[F] : 1'd0), // Pass interrupt only if mask = 0 and instruction exists. |
.i_iabort (fifo_instr_abort), |
.o_iabort (thumb_iabort), |
.i_cpsr_ff_t (alu_flags_ff[T]), |
.i_pc_ff (alu_flags_ff[T] ? fifo_pc_plus_8 - 32'd4 : fifo_pc_plus_8 - 32'd8), |
.i_pc_plus_8_ff (fifo_pc_plus_8), |
.i_taken (fifo_bp_state), |
.i_instruction (fifo_instruction), |
.i_instruction_valid (fifo_valid), |
.i_irq (fifo_valid ? irq && !alu_flags_ff[I] : 1'd0), // Pass interrupt only if mask = 0 and instruction exists. |
.i_fiq (fifo_valid ? fiq && !alu_flags_ff[F] : 1'd0), // Pass interrupt only if mask = 0 and instruction exists. |
.i_iabort (fifo_instr_abort), |
.o_iabort (thumb_iabort), |
.i_cpsr_ff_t (alu_flags_ff[T]), |
.i_pc_ff (alu_flags_ff[T] ? fifo_pc_plus_8 - 32'd4 : fifo_pc_plus_8 - 32'd8), |
.i_pc_plus_8_ff (fifo_pc_plus_8), |
|
.o_instruction (thumb_instruction), |
.o_instruction_valid (thumb_valid), |
.o_und (thumb_und), |
.o_force32_align(thumb_force32), |
.o_pc_ff (thumb_pc_ff), |
.o_pc_plus_8_ff (thumb_pc_plus_8_ff), |
.o_irq (thumb_irq), |
.o_fiq (thumb_fiq), |
.o_taken_ff (thumb_bp_state) |
.o_instruction (thumb_instruction), |
.o_instruction_valid (thumb_valid), |
.o_und (thumb_und), |
.o_force32_align (thumb_force32), |
.o_pc_ff (thumb_pc_ff), |
.o_pc_plus_8_ff (thumb_pc_plus_8_ff), |
.o_irq (thumb_irq), |
.o_fiq (thumb_fiq), |
.o_taken_ff (thumb_bp_state) |
); |
|
// ========================= |
518,9 → 517,7
.i_reset (reset), |
|
.i_clear_from_writeback (clear_from_writeback), |
.i_data_stall (o_data_wb_stb && |
o_data_wb_cyc && |
!i_data_wb_ack), |
.i_data_stall (data_stall), |
.i_clear_from_alu (clear_from_alu), |
.i_stall_from_shifter (stall_from_shifter), |
.i_stall_from_issue (stall_from_issue), |
543,14 → 540,7
.i_und (thumb_und), |
|
.i_copro_done (copro_done), |
.i_pipeline_dav ( |
predecode_val || |
(decode_condition_code != NV) || |
(issue_condition_code_ff != NV) || |
(shifter_condition_code_ff!= NV) || |
alu_dav_ff || |
memory_dav_ff |
), |
.i_pipeline_dav (pipeline_is_not_empty), |
|
// Output. |
.o_stall_from_decode (stall_from_decode), |
576,8 → 566,6
.o_taken_ff (predecode_taken) |
); |
|
wire [64*8-1:0] decode_decompile; |
|
// ===================== |
// DECODE STAGE |
// ===================== |
596,9 → 584,7
.i_reset (reset), |
|
.i_clear_from_writeback (clear_from_writeback), |
.i_data_stall (o_data_wb_cyc && |
o_data_wb_stb && |
!i_data_wb_ack), |
.i_data_stall (data_stall), |
.i_clear_from_alu (clear_from_alu), |
.i_stall_from_shifter (stall_from_shifter), |
.i_stall_from_issue (stall_from_issue), |
652,8 → 638,6
// ISSUE |
// ================== |
|
wire [64*8-1:0] issue_decompile; |
|
zap_issue_main #( |
.PHY_REGS(PHY_REGS), |
.SHIFT_OPS(SHIFT_OPS), |
679,9 → 663,7
.i_reset (reset), |
.i_clear_from_writeback (clear_from_writeback), |
.i_stall_from_shifter (stall_from_shifter), |
.i_data_stall (o_data_wb_cyc && |
o_data_wb_stb && |
!i_data_wb_ack), |
.i_data_stall (data_stall), |
.i_clear_from_alu (clear_from_alu), |
.i_pc_plus_8_ff (decode_pc_plus_8_ff), |
.i_condition_code_ff (decode_condition_code), |
779,8 → 761,6
// SHIFTER STAGE |
// ======================= |
|
wire [64*8-1:0] shifter_decompile; |
|
zap_shifter_main #( |
.PHY_REGS(PHY_REGS), |
.ALU_OPS(ALU_OPS), |
788,27 → 768,25
) |
u_zap_shifter_main |
( |
.i_decompile(issue_decompile), |
.o_decompile(shifter_decompile), |
.i_decompile (issue_decompile), |
.o_decompile (shifter_decompile), |
|
.i_pc_ff(issue_pc_ff), |
.o_pc_ff(shifter_pc_ff), |
.i_pc_ff (issue_pc_ff), |
.o_pc_ff (shifter_pc_ff), |
|
.i_taken_ff(issue_taken_ff), |
.o_taken_ff(shifter_taken_ff), |
.i_taken_ff (issue_taken_ff), |
.o_taken_ff (shifter_taken_ff), |
|
.i_und_ff(issue_und_ff), |
.o_und_ff(shifter_und_ff), |
.i_und_ff (issue_und_ff), |
.o_und_ff (shifter_und_ff), |
|
.o_nozero_ff(shifter_nozero_ff), |
.o_nozero_ff (shifter_nozero_ff), |
|
// Inputs. |
.i_clk (i_clk), |
.i_reset (reset), |
|
.i_clear_from_writeback (clear_from_writeback), |
.i_data_stall (o_data_wb_cyc && |
o_data_wb_stb && |
!i_data_wb_ack), |
.i_data_stall (data_stall), |
.i_clear_from_alu (clear_from_alu), |
.i_condition_code_ff (issue_condition_code_ff), |
.i_destination_index_ff (issue_destination_index_ff), |
891,8 → 869,6
// ALU STAGE |
// =============== |
|
wire [64*8-1:0] alu_decompile; |
|
zap_alu_main #( |
.PHY_REGS(PHY_REGS), |
.SHIFT_OPS(SHIFT_OPS), |
900,33 → 876,30
) |
u_zap_alu_main |
( |
.i_decompile (shifter_decompile), |
.o_decompile (alu_decompile), |
.i_decompile (shifter_decompile), |
.o_decompile (alu_decompile), |
|
.i_hijack (wb_hijack ), |
.i_hijack_op1 ( wb_hijack_op1 ), |
.i_hijack_op2 ( wb_hijack_op2 ), |
.i_hijack_cin ( wb_hijack_cin ), |
.o_hijack_sum ( alu_hijack_sum ), |
.i_hijack ( wb_hijack ), |
.i_hijack_op1 ( wb_hijack_op1 ), |
.i_hijack_op2 ( wb_hijack_op2 ), |
.i_hijack_cin ( wb_hijack_cin ), |
.o_hijack_sum ( alu_hijack_sum ), |
|
.i_taken_ff (shifter_taken_ff), |
.o_confirm_from_alu (confirm_from_alu), |
.i_taken_ff (shifter_taken_ff), |
.o_confirm_from_alu (confirm_from_alu), |
|
.i_pc_ff (shifter_pc_ff), |
|
.i_und_ff(shifter_und_ff), |
.o_und_ff(alu_und_ff), |
.i_und_ff (shifter_und_ff), |
.o_und_ff (alu_und_ff), |
|
.i_nozero_ff ( shifter_nozero_ff ), |
.i_nozero_ff ( shifter_nozero_ff ), |
|
.i_clk (i_clk),// & i_instr_wb_ack), |
.i_clk (i_clk), |
.i_reset (reset), |
.i_clear_from_writeback (clear_from_writeback), // | High Pri |
.i_data_stall (o_data_wb_cyc && |
o_data_wb_stb && |
!i_data_wb_ack), // V Low Pri |
|
.i_cpsr_nxt (cpsr_nxt), // FROM WB |
.i_clear_from_writeback (clear_from_writeback), |
.i_data_stall (data_stall), |
.i_cpsr_nxt (cpsr_nxt), |
.i_flag_update_ff (shifter_flag_update_ff), |
.i_switch_ff (shifter_switch_ff), |
|
1014,18 → 987,16
// MEMORY |
// ==================== |
|
wire [64*8-1:0] memory_decompile; // For debug. Goes to RB DC ip. |
|
zap_memory_main #( |
.PHY_REGS(PHY_REGS) |
) |
u_zap_memory_main |
( |
.i_decompile(alu_decompile), |
.o_decompile(memory_decompile), |
.i_decompile (alu_decompile), |
.o_decompile (memory_decompile), |
|
.i_und_ff (alu_und_ff), |
.o_und_ff (memory_und_ff), |
.i_und_ff (alu_und_ff), |
.o_und_ff (memory_und_ff), |
|
.i_mem_address_ff (alu_address_ff), |
|
1039,8 → 1010,7
.i_uhalf_ff (alu_uhalf_ff), // Unsigned half word. |
|
.i_clear_from_writeback (clear_from_writeback), |
.i_data_stall (o_data_wb_cyc && o_data_wb_stb |
&& !i_data_wb_ack), |
.i_data_stall (data_stall), |
.i_alu_result_ff (alu_alu_result_ff), |
.i_flags_ff (alu_flags_ff), |
|
1089,8 → 1059,6
.o_mem_rd_data (memory_mem_rd_data) |
); |
|
wire [64*8-1:0] rb_decompile; |
|
// ================== |
// WRITEBACK |
// ================== |
1110,8 → 1078,7
|
.i_reset (reset), // ZAP reset. |
.i_valid (memory_dav_ff), |
.i_data_stall (o_data_wb_cyc && o_data_wb_stb |
&& !i_data_wb_ack), |
.i_data_stall (data_stall), |
.i_clear_from_alu (clear_from_alu), |
.i_pc_from_alu (pc_from_alu), |
.i_stall_from_decode (stall_from_decode), |
1123,7 → 1090,7
.i_clear_from_decode (clear_from_decode), |
.i_pc_from_decode (pc_from_decode), |
|
.i_code_stall ((!o_instr_wb_stb && !o_instr_wb_cyc) || (!i_instr_wb_ack)), |
.i_code_stall (code_stall), |
|
// Used to valid writes on i_wr_index1. |
.i_mem_load_ff (memory_mem_load_ff), |
1196,6 → 1163,7
.o_baddr (o_baddr), |
.o_mmu_en (o_mmu_en), |
.o_sr (o_sr), |
.o_pid (o_pid), |
.o_dcache_inv (o_dcache_inv), |
.o_icache_inv (o_icache_inv), |
.o_dcache_clean (o_dcache_clean), |
1210,22 → 1178,21
.i_icache_clean_done (i_icache_clean_done) |
); |
|
`ifndef SYNTHESIS |
|
reg [(8*8)-1:0] CPU_MODE; // Max 8 characters i.e. 64-bit string. |
|
always @* |
case(o_cpsr[`CPSR_MODE]) |
FIQ: CPU_MODE = "FIQ"; |
IRQ: CPU_MODE = "IRQ"; |
USR: CPU_MODE = "USR"; |
UND: CPU_MODE = "UND"; |
SVC: CPU_MODE = "SVC"; |
ABT: CPU_MODE = "ABT"; |
SYS: CPU_MODE = "SYS"; |
FIQ: CPU_MODE = "FIQ"; |
IRQ: CPU_MODE = "IRQ"; |
USR: CPU_MODE = "USR"; |
UND: CPU_MODE = "UND"; |
SVC: CPU_MODE = "SVC"; |
ABT: CPU_MODE = "ABT"; |
SYS: CPU_MODE = "SYS"; |
default: CPU_MODE = "???"; |
endcase |
|
`endif |
|
endmodule // zap_core.v |
|
`default_nettype wire |
/zap/trunk/src/rtl/cpu/zap_cp15_cb.v
35,26 → 35,31
parameter PHY_REGS = 64 |
) |
( |
// ---------------------------------------------------------------- |
// Clock and reset. |
// ---------------------------------------------------------------- |
|
input wire i_clk, |
input wire i_reset, |
|
// |
// Coprocessor bus. |
// |
// ---------------------------------------------------------------- |
// Coprocessor instruction and done signal. |
// ---------------------------------------------------------------- |
|
// Coprocessor instruction. |
input wire [31:0] i_cp_word, |
|
// Coprocessor instruction valid. |
input wire i_cp_dav, |
|
// Coprocessor done. |
output reg o_cp_done, |
|
// ---------------------------------------------------------------- |
// CPSR from processor. |
// ---------------------------------------------------------------- |
|
input wire [31:0] i_cpsr, |
|
// ---------------------------------------------------------------- |
// Register file RW interface |
// ---------------------------------------------------------------- |
|
// Asserted if we want to control of the register file. |
// Controls a MUX that selects signals. |
output reg o_reg_en, |
69,21 → 74,17
output reg [$clog2(PHY_REGS)-1:0] o_reg_wr_index, |
o_reg_rd_index, |
|
// |
// ---------------------------------------------------------------- |
// From MMU. |
// |
// ---------------------------------------------------------------- |
|
// The FSR stands for "Fault Status Register" |
// The FAR stands for "Fault Address Register" |
input wire [31:0] i_fsr, |
input wire [31:0] i_far, |
|
// |
// These go to the MMU |
// |
// ----------------------------------------------------------------- |
// MMU configuration signals. |
// ----------------------------------------------------------------- |
|
// COMMON TO BOTH DATA AND CODE MMU. |
|
// Domain Access Control Register. |
output reg [31:0] o_dac, |
|
96,8 → 97,13
// SR register. |
output reg [1:0] o_sr, |
|
// SEPARATE SIGNALS FOR DATA AND CODE MMU. |
// FCSE register. |
output reg [7:0] o_pid, |
|
// ----------------------------------------------------------------- |
// Invalidate and clean controls. |
// ----------------------------------------------------------------- |
|
// Cache invalidate signal. |
output reg o_dcache_inv, |
output reg o_icache_inv, |
127,38 → 133,17
`include "zap_defines.vh" |
`include "zap_functions.vh" |
|
// --------------------------------------------- |
// Variables |
// --------------------------------------------- |
|
reg [31:0] r [6:0]; // Coprocessor registers. R7 is write-only. |
reg [31:0] r [13:0];// Coprocessor registers. R7, R8 is write-only. |
reg [3:0] state; // State variable. |
|
`ifndef SYNTHESIS |
integer ops; |
initial ops = 0; |
`endif |
// --------------------------------------------- |
// Localparams |
// --------------------------------------------- |
|
// Ties registers to output ports via a register. |
always @ (posedge i_clk) |
begin |
if ( i_reset ) |
begin |
o_dcache_en <= 0; |
o_icache_en <= 0; |
o_mmu_en <= 0; |
o_dac <= 32'dx; |
o_baddr <= 32'dx; |
o_sr <= 2'dx; |
end |
else |
begin |
o_dcache_en <= r[1][2]; // Data cache enable. |
o_icache_en <= r[1][12]; // Instruction cache enable. |
o_mmu_en <= r[1][0]; // MMU enable. |
o_dac <= r[3]; // DAC register. |
o_baddr <= r[2]; // Base address. |
o_sr <= {r[1][8],r[1][9]}; // SR register. |
end |
end |
|
// States. |
localparam IDLE = 0; |
localparam ACTIVE = 1; |
179,6 → 164,7
localparam FAR_REG = 6; |
localparam CACHE_REG = 7; |
localparam TLB_REG = 8; |
localparam FCSE_REG = 13; |
|
//{opcode_2, crm} values that are valid for this implementation. |
localparam CASE_FLUSH_ID_CACHE = 7'b000_0111; |
192,16 → 178,40
localparam CASE_FLUSH_I_TLB = 7'b000_0101; |
localparam CASE_FLUSH_D_TLB = 7'b000_0110; |
|
// Instruction fields. |
`define opcode_2 7:5 |
`define crm 3:0 |
`define crn 19:16 |
`define cp_id 11:8 |
// --------------------------------------------- |
// Sequential Logic |
// --------------------------------------------- |
|
always @ (posedge i_clk) |
// Ties registers to output ports via a register. |
always @ ( posedge i_clk ) |
begin |
if ( i_reset ) |
begin |
o_dcache_en <= 1'd0; |
o_icache_en <= 1'd0; |
o_mmu_en <= 1'd0; |
o_dac <= 32'dx; |
o_baddr <= 32'dx; |
o_sr <= 2'dx; |
o_pid <= 8'd0; |
end |
else |
begin |
o_dcache_en <= r[1][2]; // Data cache enable. |
o_icache_en <= r[1][12]; // Instruction cache enable. |
o_mmu_en <= r[1][0]; // MMU enable. |
o_dac <= r[3]; // DAC register. |
o_baddr <= r[2]; // Base address. |
o_sr <= {r[1][8],r[1][9]}; // SR register. |
o_pid <= {1'd0, r[13][31:25]}; // PID register. |
end |
end |
|
// Core logic. |
always @ ( posedge i_clk ) |
begin |
if ( i_reset ) |
begin |
state <= IDLE; |
o_dcache_inv <= 1'd0; |
o_icache_inv <= 1'd0; |
214,7 → 224,6
o_reg_wr_data <= 0; |
o_reg_wr_index <= 0; |
o_reg_rd_index <= 0; |
|
r[0] <= 32'h0; |
r[1] <= 32'd0; |
r[2] <= 32'd0; |
222,21 → 231,19
r[4] <= 32'd0; |
r[5] <= 32'd0; |
r[6] <= 32'd0; |
r[13] <= 32'd0; //FCSE |
|
// Default values. |
r[0][23:16] <= 32'h1; |
// R0 override. |
generate_r0; |
|
// R1 override. |
r[1][1] <= 1'd1; |
r[1][3] <= 1'd1; // Write buffer always enabled. |
r[1][7:4] <= 4'b0011; // 0 = Little Endian, 0 = 0, 1 = 32-bit address range, 1 = 32-bit handlers enabled. |
r[1][3] <= 1'd1; |
r[1][6:4] <= 3'b111; |
r[1][11] <= 1'd1; |
r[1][13] <= 1'd0; |
end |
else |
begin |
`ifndef SYNTHESIS |
ops <= 0; |
`endif |
|
// Default assignments. |
o_itlb_inv <= 1'd0; |
o_dtlb_inv <= 1'd0; |
309,9 → 316,6
|
CASE_FLUSH_ID_TLB: |
begin |
`ifndef SYNTHESIS |
ops <= 1; |
`endif |
o_itlb_inv <= 1'd1; |
o_dtlb_inv <= 1'd1; |
end |
318,24 → 322,18
|
CASE_FLUSH_I_TLB: |
begin |
`ifndef SYNTHESIS |
ops <= 2; |
`endif |
o_itlb_inv <= 1'd1; |
end |
|
CASE_FLUSH_D_TLB: |
begin |
`ifndef SYNTHESIS |
ops <= 3; |
`endif |
o_dtlb_inv <= 1'd1; |
end |
|
default: |
begin |
$display("Bad TLB command!"); |
$finish; |
o_itlb_inv <= 1'd1; |
o_dtlb_inv <= 1'd1; |
end |
|
endcase |
345,9 → 343,6
case({i_cp_word[`opcode_2], i_cp_word[`crm]}) |
CASE_FLUSH_ID_CACHE: |
begin |
`ifndef SYNTHESIS |
ops <= 4; |
`endif |
// Invalidate caches. |
o_dcache_inv <= 1'd1; |
state <= CLR_D_CACHE_AND; |
355,9 → 350,6
|
CASE_FLUSH_D_CACHE: |
begin |
`ifndef SYNTHESIS |
ops <= 5; |
`endif |
|
// Invalidate data cache. |
o_dcache_inv <= 1'd1; |
366,9 → 358,6
|
CASE_FLUSH_I_CACHE: |
begin |
`ifndef SYNTHESIS |
ops <= 6; |
`endif |
|
// Invalidate instruction cache. |
o_icache_inv <= 1'd1; |
377,9 → 366,6
|
CASE_CLEAN_ID_CACHE, CASE_CLEAN_D_CACHE: |
begin |
`ifndef SYNTHESIS |
ops <= 7; |
`endif |
|
o_dcache_clean <= 1'd1; |
state <= CLEAN_D_CACHE; |
387,9 → 373,6
|
CASE_CLFLUSH_D_CACHE: |
begin |
`ifndef SYNTHESIS |
ops <= 8; |
`endif |
|
o_dcache_clean <= 1'd1; |
state <= CLFLUSH_D_CACHE; |
397,9 → 380,6
|
CASE_CLFLUSH_ID_CACHE: |
begin |
`ifndef SYNTHESIS |
ops <= 9; |
`endif |
|
o_dcache_clean <= 1'd1; |
state <= CLFLUSH_ID_CACHE; |
407,8 → 387,8
|
default: |
begin |
$display($time, "Error: Bad coprocessor instruction %b", i_cp_word); |
$finish; |
o_dcache_clean <= 1'd1; |
state <= CLFLUSH_ID_CACHE; |
end |
|
endcase |
451,13 → 431,13
if ( i_dcache_inv_done && state == CLR_D_CACHE ) |
begin |
o_dcache_inv <= 1'd0; |
state <= DONE; |
state <= DONE; |
end |
else if ( state == CLR_D_CACHE_AND && i_dcache_inv_done ) |
begin |
o_dcache_inv <= 1'd0; |
o_icache_inv <= 1'd1; |
state <= CLR_I_CACHE; |
state <= CLR_I_CACHE; |
end |
end |
|
468,7 → 448,7
if ( i_icache_inv_done ) |
begin |
o_icache_inv <= 1'd0; |
state <= DONE; |
state <= DONE; |
end |
end |
|
478,7 → 458,7
begin |
if ( i_cp_word[20] ) // Load to CPU reg. |
begin |
// Register write command. |
// Generate CPU Register write command. CP read. |
o_reg_en <= 1'd1; |
o_reg_wr_index <= translate( i_cp_word[15:12], i_cpsr[4:0] ); |
o_reg_wr_data <= r[ i_cp_word[19:16] ]; |
486,7 → 466,7
end |
else // Store to CPU register. |
begin |
// Generate register read command. |
// Generate CPU register read command. CP write. |
o_reg_en <= 1'd1; |
o_reg_rd_index <= translate(i_cp_word[15:12], i_cpsr[4:0]); |
o_reg_wr_index <= 16; |
497,29 → 477,63
begin |
state <= DONE; |
end |
|
// Process unconditional words to CP15. |
casez ( i_cp_word ) |
MCR2, MRC2, LDC2, STC2: |
begin |
if ( i_cp_word[20] ) // Load to CPU reg. |
begin |
// Register write command. |
o_reg_en <= 1'd1; |
o_reg_wr_index <= translate( i_cp_word[15:12], i_cpsr[4:0] ); |
o_reg_wr_data <= r[ i_cp_word[19:16] ]; |
state <= DONE; |
end |
else // Store to CPU register. |
begin |
// Generate register read command. |
o_reg_en <= 1'd1; |
o_reg_rd_index <= translate(i_cp_word[15:12], i_cpsr[4:0]); |
o_reg_wr_index <= 16; |
state <= READ_DLY; |
end |
end |
endcase |
end |
endcase |
|
// Default assignments. These bits are UNCHANGEABLE. |
r[0][23:16] <= 32'h1; |
// Default assignments. These bits are unchangeable. |
generate_r0; |
|
r[1][1] <= 1'd1; |
r[1][3] <= 1'd1; // Write buffer always enabled. |
r[1][7:4] <= 4'b0011; // 0 = Little Endian, 0 = 0, 1 = 32-bit address range, 1 = 32-bit handlers enabled. |
r[1][3] <= 1'd1; // Write buffer always enabled. |
r[1][6:4] <= 3'b111; // 0 = Little Endian, 0 = 0, 1 = 32-bit address range, |
// 1 = 32-bit handlers enabled. |
r[1][11] <= 1'd1; |
r[1][13] <= 1'd0; |
end |
end |
|
`ifndef SYNTHESIS |
// Debug only. |
wire [31:0] r0 = r[0]; |
wire [31:0] r1 = r[1]; |
wire [31:0] r2 = r[2]; |
wire [31:0] r3 = r[3]; |
wire [31:0] r4 = r[4]; |
wire [31:0] r5 = r[5]; |
wire [31:0] r6 = r[6]; |
`endif |
// CPU info register. |
task generate_r0; |
begin |
r[0][3:0] <= 4'd0; |
r[0][15:4] <= 12'hAAA; |
r[0][19:16] <= 4'h4; |
r[0][23:20] <= 4'd0; |
r[0][31:24] <= 8'd0; |
end |
endtask |
|
// assertions_start |
wire [31:0] r0 = r[0]; |
wire [31:0] r1 = r[1]; |
wire [31:0] r2 = r[2]; |
wire [31:0] r3 = r[3]; |
wire [31:0] r4 = r[4]; |
wire [31:0] r5 = r[5]; |
wire [31:0] r6 = r[6]; |
// assertions_end |
|
endmodule |
`default_nettype wire |
/zap/trunk/src/rtl/cpu/zap_decode.v
124,54 → 124,54
localparam [1:0] UNSIGNED_HALF_WORD = 2'd1; |
localparam [1:0] SIGNED_HALF_WORD = 2'd2; |
|
`ifndef SYNTHESIS |
// assertions_start |
|
// Debug only. |
reg bx, dp, br, mrs, msr, ls, mult, halfword_ls, swi, dp1, dp2, dp3, lmult, clz; |
|
always @* |
begin |
bx = 0; |
dp = 0; |
br = 0; |
mrs = 0; |
msr = 0; |
ls = 0; |
mult = 0; |
halfword_ls = 0; |
swi = 0; |
dp1 = 0; |
dp2 = 0; |
dp3 = 0; |
|
// |
// Debugging purposes. |
// |
if ( i_instruction_valid ) |
casez ( i_instruction[31:0] ) |
CLZ_INSTRUCTION: clz = 1; |
BX_INST: bx = 1; |
MRS: mrs = 1; |
MSR,MSR_IMMEDIATE: msr = 1; |
DATA_PROCESSING_IMMEDIATE, |
DATA_PROCESSING_REGISTER_SPECIFIED_SHIFT, |
DATA_PROCESSING_INSTRUCTION_SPECIFIED_SHIFT: dp = 1; |
BRANCH_INSTRUCTION: br = 1; |
LS_INSTRUCTION_SPECIFIED_SHIFT,LS_IMMEDIATE: |
// Debug only. |
reg bx, dp, br, mrs, msr, ls, mult, halfword_ls, swi, dp1, dp2, dp3, lmult, clz; |
|
always @* |
begin |
if ( i_instruction[20] ) |
ls = 1; // Load |
else |
ls = 2; // Store |
bx = 0; |
dp = 0; |
br = 0; |
mrs = 0; |
msr = 0; |
ls = 0; |
mult = 0; |
halfword_ls = 0; |
swi = 0; |
dp1 = 0; |
dp2 = 0; |
dp3 = 0; |
|
// |
// Debugging purposes. |
// |
if ( i_instruction_valid ) |
casez ( i_instruction[31:0] ) |
CLZ_INSTRUCTION: clz = 1; |
BX_INST: bx = 1; |
MRS: mrs = 1; |
MSR,MSR_IMMEDIATE: msr = 1; |
DATA_PROCESSING_IMMEDIATE, |
DATA_PROCESSING_REGISTER_SPECIFIED_SHIFT, |
DATA_PROCESSING_INSTRUCTION_SPECIFIED_SHIFT: dp = 1; |
BRANCH_INSTRUCTION: br = 1; |
LS_INSTRUCTION_SPECIFIED_SHIFT,LS_IMMEDIATE: |
begin |
if ( i_instruction[20] ) |
ls = 1; // Load |
else |
ls = 2; // Store |
end |
MULT_INST: mult = 1; |
LMULT_INST: lmult = 1; |
HALFWORD_LS: halfword_ls = 1; |
SOFTWARE_INTERRUPT: swi = 1; |
endcase |
end |
MULT_INST: mult = 1; |
LMULT_INST: lmult = 1; |
HALFWORD_LS: halfword_ls = 1; |
SOFTWARE_INTERRUPT: swi = 1; |
endcase |
end |
|
`endif |
// assertions_end |
|
// ---------------------------------------------------------------------------- |
|
693,9 → 693,7
// |
task process_immediate ( input [34:0] instruction ); |
begin |
`ifndef SYNTHESIS |
dp1 = 1; |
`endif |
dp1 = 1; |
|
o_shift_length = instruction[11:8] << 1'd1; |
o_shift_length[32] = IMMED_EN; |
713,9 → 711,7
// |
task process_instruction_specified_shift ( input [34:0] instruction ); |
begin |
`ifndef SYNTHESIS |
dp2 = 1; |
`endif |
dp2 = 1; |
|
// ROR #0 = RRC, ASR #0 = ASR #32, LSL #0 = LSL #0, LSR #0 = LSR #32 |
// ROR #n = ROR_1 #n ( n > 0 ) |
755,9 → 751,7
$display("%m Process register specified shift..."); |
`endif |
|
`ifndef SYNTHESIS |
dp3 = 1; |
`endif |
dp3 = 1; |
|
o_shift_length = instruction[11:8]; |
o_shift_length[32] = INDEX_EN; |
/zap/trunk/src/rtl/cpu/zap_decode_main.v
381,7 → 381,6
|
// Decompile |
|
`ifndef SYNTHESIS |
|
zap_decompile u_zap_decompile ( |
.i_instruction (i_instruction), |
389,11 → 388,6
.o_decompile (decompile_tmp) |
); |
|
`else |
|
assign decompile_tmp = 0; |
|
`endif |
|
endmodule // zap_decode_main.v |
`default_nettype wire |
/zap/trunk/src/rtl/cpu/zap_decompile.v
31,62 → 31,30
`default_nettype none |
|
module zap_decompile #(parameter INS_WDT = 36) ( |
input wire [36-1:0] i_instruction, // 36-bit instruction. |
input wire [36-1:0] i_instruction, // 36-bit instruction into decode. |
input wire i_dav, // Instruction valid. |
output reg [64*8-1:0] o_decompile // 1024 bytes max of assembler string. |
); |
|
`ifndef SYNTHESIS // if simulating... |
`ifndef SYNTHESIS |
|
`include "zap_defines.vh" |
`include "zap_localparams.vh" |
`include "zap_functions.vh" |
|
|
// These defines can be wrapped around a single `ifndef instead of several of |
// them as shown. |
|
`ifndef CCC |
`define CCC cond_code(i_instruction[31:28]) |
`endif |
|
`ifndef CRB |
`define CRB arch_reg_num({i_instruction[`DP_RB_EXTEND], i_instruction[`DP_RB]}) |
`endif |
|
`ifndef CRD |
`define CRD arch_reg_num({i_instruction[`DP_RD_EXTEND], i_instruction[`DP_RD]}) |
`endif |
|
`ifndef CDR1 |
`define CRD1 arch_reg_num({i_instruction[`SRCDEST_EXTEND], i_instruction[`SRCDEST]}) |
`endif |
|
`ifndef CRN |
`define CRN arch_reg_num({i_instruction[`DP_RA_EXTEND], i_instruction[`DP_RA]}) |
`endif |
|
`ifndef CRN1 |
`define CRN1 arch_reg_num({i_instruction[`BASE_EXTEND], i_instruction[`BASE]}) |
`endif |
|
`ifndef COPCODE |
`ifndef ZAP_DECOMPILE_DEFINES |
`define CCC cond_code(i_instruction[31:28]) |
`define CRB arch_reg_num({i_instruction[`DP_RB_EXTEND], i_instruction[`DP_RB]}) |
`define CRD arch_reg_num({i_instruction[`DP_RD_EXTEND], i_instruction[`DP_RD]}) |
`define CRD1 arch_reg_num({i_instruction[`SRCDEST_EXTEND], i_instruction[`SRCDEST]}) |
`define CRN arch_reg_num({i_instruction[`DP_RA_EXTEND], i_instruction[`DP_RA]}) |
`define CRN1 arch_reg_num({i_instruction[`BASE_EXTEND], i_instruction[`BASE]}) |
`define COPCODE get_opcode({i_instruction[`OPCODE_EXTEND], i_instruction[24:21]}) |
`endif |
|
`ifndef CSHTYPE |
`define CSHTYPE get_shtype(i_instruction[6:5]) |
`define CRS arch_reg_num(i_instruction[11:8]); |
`define CRM arch_reg_num({i_instruction[`DP_RB_EXTEND], i_instruction[`DP_RB]}); |
`endif |
|
`ifndef CRS |
`define CRS arch_reg_num(i_instruction[11:8]); |
`endif |
|
`ifndef CRM |
`define CRM arch_reg_num({i_instruction[`DP_RB_EXTEND], i_instruction[`DP_RB]}); |
`endif |
|
// Decompile block. Makes task calls. |
always @* |
begin |
if ( !i_dav ) |
493,7 → 461,6
|
`else |
|
// `ifdef SYNTHESIS |
always @* |
o_decompile = 0; // In synthesis mode. |
|
/zap/trunk/src/rtl/cpu/zap_defines.vh
44,6 → 44,12
`define OPCODE_EXTEND 35 // To differentiate lower and higher -> |
// 1 means higher, 0 lower. |
|
// Instruction fields in CP15 instruction. |
`define opcode_2 7:5 |
`define crm 3:0 |
`define crn 19:16 |
`define cp_id 11:8 |
|
// ---------------------------------------------------------------------------- |
|
// Generic defines. |
/zap/trunk/src/rtl/cpu/zap_fetch_main.v
77,7 → 77,7
input wire i_confirm_from_alu, // Confirm branch prediction from ALU. |
input wire [31:0] i_pc_from_alu, // Address of branch. |
input wire [1:0] i_taken, // Predicted status. |
output wire [1:0] o_taken_ff // Prediction. Not a flip-flop... |
output wire [1:0] o_taken // Prediction. Not a flip-flop... |
|
); |
|
95,7 → 95,7
wire [1:0] taken_v; |
|
// Predict non branches as not taken... |
assign o_taken_ff = i_instruction[28:26] == 3'b101 ? taken_v : SNT; |
assign o_taken = o_instruction[28:26] == 3'b101 ? taken_v : SNT; |
|
// ---------------------------------------------------------------------------- |
|
190,19 → 190,15
end |
end |
|
`ifndef SYNTHESIS |
|
always @ (negedge i_clk) |
begin |
if ( i_pc_ff[0] != 1'd0 ) |
begin |
$display($time, ": Error: PC LSB isn't zero. This is not legal! (Module_Src = %m)"); |
$display($time, " - %m :: Error: PC LSB isn't zero. This is not legal..."); |
$finish; |
end |
end |
|
`endif |
|
// ---------------------------------------------------------------------------- |
|
// |
301,8 → 297,6
|
// --------------------------------------------------------------------------------- |
|
`ifndef SYNTHESIS |
|
zap_decompile u_zap_decompile ( |
.i_instruction ({4'd0, o_instruction}), |
.i_dav (o_valid), |
309,7 → 303,6
.o_decompile () |
); |
|
`endif |
|
endmodule // zap_fetch_main.v |
`default_nettype wire |
/zap/trunk/src/rtl/cpu/zap_localparams.vh
102,7 → 102,7
|
localparam [4:0] CLZ = 24; // Count Leading zeros. |
|
// Conditionals defined as per v4 spec. |
// Conditionals defined as per v5T spec. |
localparam EQ = 4'h0; |
localparam NE = 4'h1; |
localparam CS = 4'h2; |
178,14 → 178,20
|
// Write to coprocessor. |
localparam [31:0] MCR = 32'b????_1110_???_0_????_????_1111_???_1_????; |
localparam [31:0] MCR2 = 32'b1111_1110???0_????????????_???1_????; |
|
// Read from coprocessor. |
localparam [31:0] MRC = 32'b????_1110_???_1_????_????_1111_???_1_????; |
localparam [31:0] MRC2 = 32'b1111_1110???1_????????????_???1_????; |
|
// LDC, STC |
localparam [31:0] LDC = 32'b????_110_????1_????_????_????_????????; |
localparam [31:0] STC = 32'b????_110_????0_????_????_????_????????; |
|
// LDC2, STC2 |
localparam [31:0] LDC2 = 32'b1111_110????1_????????????_????_????; |
localparam [31:0] STC2 = 32'b1111_110????0_????????????_????_????; |
|
// CDP |
localparam [31:0] CDP = 32'b????_1110_????????_????????_????????; |
|
/zap/trunk/src/rtl/cpu/zap_predecode_coproc.v
115,13 → 115,8
wire c3 = i_instruction[11:8] == 4'b1111; |
wire c4 = i_instruction[34:32] == 3'd0; |
wire c5 = c1 & c2 & c3 & c4; |
|
`ifndef SYNTHESIS |
|
reg eclass; |
|
`endif |
|
// Next state logic. |
always @* |
begin |
135,15 → 130,13
o_irq = i_irq; |
o_fiq = i_fiq; |
|
`ifndef SYNTHESIS |
eclass = 0; |
`endif |
eclass = 0; |
|
case ( state_ff ) |
IDLE: |
// Activate only if no thumb, not in USER mode and CP15 access is requested. |
casez ( (!i_cpsr_ff_t && (i_instruction[34:32] == 3'd0) && i_valid) ? i_instruction[31:0] : 35'd0 ) |
MRC, MCR, LDC, STC, CDP: |
MRC, MCR, LDC, STC, CDP, MRC2, MCR2, LDC2, STC2: |
begin |
if ( i_instruction[11:8] == 4'b1111 && i_cpsr_ff_mode != USR ) // CP15 and root access -- perfectly fine. |
begin |
177,7 → 170,6
end |
else // Warning... |
begin |
`ifndef SYNTHESIS |
|
if ( i_instruction[11:8] != 4'b1111 ) |
eclass = 1; |
184,7 → 176,6
else |
eclass = 2; |
|
`endif |
|
// Remain transparent since this is not a coprocessor |
// instruction. |
/zap/trunk/src/rtl/cpu/zap_predecode_mem_fsm.v
1,5 → 1,3
// TODO: Fix SWAP instruction. |
|
// ----------------------------------------------------------------------------- |
// -- -- |
// -- (C) 2016-2018 Revanth Kamaraj. -- |
83,33 → 81,28
|
/////////////////////////////////////////////////////////////////////////////// |
|
// |
// Instruction breakup |
// These assignments are repeated in the function. |
// |
wire [3:0] base = i_instruction[`BASE]; |
wire [3:0] srcdest = i_instruction[`SRCDEST]; |
wire [3:0] cc = i_instruction[31:28]; |
wire [2:0] id = i_instruction[27:25]; |
wire pre_index = i_instruction[24]; |
wire up = i_instruction[23]; |
wire s_bit = i_instruction[22]; |
wire writeback = i_instruction[21]; |
wire load = i_instruction[20]; |
wire store = !load; |
wire [15:0] reglist= i_instruction[15:0]; |
wire link = i_instruction[24]; |
wire [11:0] branch_offset = i_instruction[11:0]; |
wire [3:0] cc ; |
wire [2:0] id ; |
wire pre_index ; |
wire up ; |
wire s_bit ; |
wire writeback ; |
wire load ; |
wire [3:0] base ; |
wire [15:0] reglist ; |
|
// Ones counter offset. |
wire [11:0] oc_offset; |
// Instruction breakup assignment. |
assign {cc, id, pre_index, up, s_bit, writeback, load, base, reglist} = i_instruction; |
|
// Registers. |
reg [3:0] state_ff, state_nxt; |
reg [15:0] reglist_ff, reglist_nxt; |
wire store = !load; |
wire link = i_instruction[24]; |
wire [11:0] branch_offset = i_instruction[11:0]; |
|
// Const reg for BLX. |
reg [31:0] const_ff, const_nxt; |
wire [11:0] oc_offset; // Ones counter offset. |
reg [3:0] state_ff, state_nxt; // State. |
reg [15:0] reglist_ff, reglist_nxt; // Register list. |
reg [31:0] const_ff, const_nxt; // For BLX - const reg. |
|
/////////////////////////////////////////////////////////////////////////////// |
|
540,36 → 533,23
|
function [33:0] map ( input [31:0] instr, input [3:0] enc, input [15:0] list ); |
// These override the globals within the function scope. |
reg [3:0] base; |
reg [3:0] srcdest; |
reg [3:0] cc; |
reg [2:0] id; |
reg pre_index; |
reg up; |
reg s_bit; |
reg writeback; |
reg load; |
reg store; |
reg [15:0] reglist; |
reg restore; |
reg [3:0] cc; |
reg [2:0] id; |
reg pre_index; |
reg up; |
reg s_bit; |
reg writeback; |
reg load; |
reg [3:0] base; |
reg [15:0] reglist; |
reg store; |
reg restore; |
begin |
restore = 0; |
|
// All variables used inside the function depend solely on the i/p args. |
// Thus repeating the assignments. |
|
base = instr[`BASE]; |
srcdest = instr[`SRCDEST]; |
cc = instr[31:28]; |
id = instr[27:25]; |
pre_index = instr[24]; |
up = instr[23]; |
s_bit = instr[22]; |
writeback = instr[21]; |
load = instr[20]; |
store = !load; |
reglist = instr[15:0]; |
{cc, id, pre_index, up, s_bit, writeback, load, base, reglist} = instr; |
|
store = !load; |
map = instr; |
map = map & ~(1<<22); // No byte access. |
map = map & ~(1<<25); // Constant Offset (of 4). |
686,7 → 666,6
|
// Counts the number of ones and multiplies that by 4 to get final |
// address offset. |
// |
function [11:0] ones_counter ( |
input [15:0] i_word // Register list. |
); |
/zap/trunk/src/rtl/cpu/zap_register_file.v
70,7 → 70,7
|
reg [39:0] sel; |
|
`ifndef SYNTHESIS |
// assertions_start |
wire [31:0] r0; assign r0 = sel[0] ? MEM[0] : mem[0]; |
wire [31:0] r1; assign r1 = sel[1] ? MEM[1] : mem[1]; |
wire [31:0] r2; assign r2 = sel[2] ? MEM[2] : mem[2]; |
111,7 → 111,7
wire [31:0] r37; assign r37 = sel[37] ? MEM[37] : mem[37]; |
wire [31:0] r38; assign r38 = sel[38] ? MEM[38] : mem[38]; |
wire [31:0] r39; assign r39 = sel[39] ? MEM[39] : mem[39]; |
`endif |
// assertions_end |
|
always @ (posedge i_clk) |
begin |
/zap/trunk/src/rtl/cpu/zap_sync_fifo.v
1,7 → 1,7
// ----------------------------------------------------------------------------- |
// -- -- |
// -- (C) 2016-2018 Revanth Kamaraj. -- |
// -- -- |
// -- -- |
// -- -------------------------------------------------------------------------- |
// -- -- |
// -- This program is free software; you can redistribute it and/or -- |
20,21 → 20,33
// -- 02110-1301, USA. -- |
// -- -- |
// ----------------------------------------------------------------------------- |
// -- This is a simple synchronous FIFO. -- |
// ----------------------------------------------------------------------------- |
|
`default_nettype none |
|
// FWFT means "First Word Fall Through". |
module zap_sync_fifo #(parameter WIDTH = 32, parameter DEPTH = 32, parameter FWFT = 1) |
module zap_sync_fifo #( |
parameter WIDTH = 32, |
parameter DEPTH = 32, |
parameter FWFT = 1, |
parameter PROVIDE_NXT_DATA = 0 |
) |
( |
// Clock and reset |
input wire i_clk, |
input wire i_reset, |
|
// Flow control |
input wire i_ack, |
input wire i_wr_en, |
|
// Data busses |
input wire [WIDTH-1:0] i_data, |
output reg [WIDTH-1:0] o_data, |
output reg [WIDTH-1:0] o_data_nxt, |
|
// Flags |
output wire o_empty, |
output wire o_full, |
output wire o_empty_n, |
46,29 → 58,25
parameter PTR_WDT = $clog2(DEPTH) + 32'd1; |
parameter [PTR_WDT-1:0] DEFAULT = {PTR_WDT{1'd0}}; |
|
// |
// Initialize pointers, empty and full as a part of the FPGA reset. |
// All init to *ZERO*. |
// |
// Variables |
reg [PTR_WDT-1:0] rptr_ff; |
reg [PTR_WDT-1:0] rptr_nxt; |
reg [PTR_WDT-1:0] wptr_ff; |
reg empty, nempty; |
reg full, nfull; |
reg empty, nempty; |
reg full, nfull; |
reg [PTR_WDT-1:0] wptr_nxt; |
reg [WIDTH-1:0] mem [DEPTH-1:0]; // Block RAM. |
wire [WIDTH-1:0] dt; |
reg [WIDTH-1:0] dt1; |
reg [WIDTH-1:0] mem [DEPTH-1:0]; |
wire [WIDTH-1:0] dt; |
reg [WIDTH-1:0] dt1; |
reg sel_ff; |
reg [WIDTH-1:0] bram_ff; |
reg [WIDTH-1:0] dt_ff; |
|
reg sel_ff; |
reg [WIDTH-1:0] bram_ff; // Block RAM read register. |
reg [WIDTH-1:0] dt_ff; |
|
// Assigns |
assign o_empty = empty; |
assign o_full = full; |
assign o_empty_n = nempty; |
assign o_full_n = nfull; |
|
assign o_full_n_nxt = i_reset ? 1 : |
!( ( wptr_nxt[PTR_WDT-2:0] == rptr_nxt[PTR_WDT-2:0] ) && |
( wptr_nxt != rptr_nxt ) ); |
79,6 → 87,7
if ( i_wr_en && !o_full ) |
mem[wptr_ff[PTR_WDT-2:0]] <= i_data; |
|
// FIFO read logic |
generate |
begin:gb1 |
if ( FWFT == 1 ) |
95,6 → 104,7
always @* |
begin |
o_data = sel_ff ? dt_ff : bram_ff; |
o_data_nxt = 0; // Tied off. |
end |
end |
else |
106,6 → 116,21
o_data <= mem [ rptr_ff[PTR_WDT-2:0] ]; |
end |
end |
|
if ( PROVIDE_NXT_DATA ) |
begin: f11 |
always @ (*) |
begin |
if ( i_ack && nempty ) |
o_data_nxt = mem [ rptr_ff[PTR_WDT-2:0] ]; |
else |
o_data_nxt = o_data; |
end |
end |
else |
begin: f22 |
always @* o_data_nxt = 0; |
end |
end |
end |
endgenerate |
129,5 → 154,6
rptr_nxt = rptr_ff + (i_ack && !o_empty); |
end |
|
endmodule |
endmodule // zap_sync_fifo |
|
`default_nettype wire |
/zap/trunk/src/rtl/cpu/zap_thumb_decoder.v
173,16 → 173,14
end |
end |
|
`ifndef SYNTHESIS |
|
// Helpful for debug. |
zap_decompile u_zap_decompile ( |
.i_instruction(o_instruction), |
.i_dav(o_instruction_valid), |
.o_decompile() |
.i_instruction ({1'd0, o_instruction}), |
.i_dav (o_instruction_valid), |
.o_decompile () |
); |
|
`endif |
|
endmodule |
endmodule // zap_thumb_decoder |
|
`default_nettype wire |
/zap/trunk/src/rtl/cpu/zap_tlb_fsm.v
173,9 → 173,9
begin |
if ( i_walk ) |
begin |
$display($time, "%m :: Page fault! Need to page walk! i_walk = %b", i_walk); |
$display($time, "%m :: Core generated address %x", i_address); |
$display($time, "%m :: Moving to FETCH_L1_DESC. i_baddr = %x baddr_tran_base = %x addr_va_table_index = %x", |
$display($time, " - %m :: Page fault! Need to page walk! i_walk = %b", i_walk); |
$display($time, " - %m :: Core generated address %x", i_address); |
$display($time, " - %m :: Moving to FETCH_L1_DESC. i_baddr = %x baddr_tran_base = %x addr_va_table_index = %x", |
i_baddr, i_baddr[`VA__TRANSLATION_BASE], i_address[`VA__TABLE_INDEX]); |
|
`ifdef TLB_DEBUG |
195,7 → 195,7
end |
else if ( i_fsr[3:0] != 4'b0000 ) /* Access Violation. */ |
begin |
$display($time, "%m :: Access violation fsr = %x far = %x...", i_fsr, i_far); |
$display($time, " - %m :: Access violation fsr = %x far = %x...", i_fsr, i_far); |
|
`ifdef TLB_DEBUG |
$stop; |
209,7 → 209,7
else |
begin |
`ifdef DISP_TLB_SUCCESS |
$display($time, "TLB Hit for address = %x MMU enable = %x!", i_address, i_mmu_en); |
$display($time, " - %m :: TLB Hit for address = %x MMU enable = %x!", i_address, i_mmu_en); |
`endif |
|
`ifdef TLB_DEBUG |
221,7 → 221,7
|
FETCH_L1_DESC_0: |
begin |
$display($time, "%m :: In state FETCH_L1_DESC_0"); |
$display($time, " - %m :: In state FETCH_L1_DESC_0"); |
|
o_busy = 1; |
|
230,7 → 230,7
dnxt = i_wb_dat; |
state_nxt = FETCH_L1_DESC; |
|
$display($time, "%m :: Received %x from WB. Moving to FETCH_L1_DESC...", dnxt ); |
$display($time, " - %m :: Received %x from WB. Moving to FETCH_L1_DESC...", dnxt ); |
end |
else tsk_hold_wb_access; |
end |
242,13 → 242,13
* Examine it. dff holds the L1 descriptor. |
*/ |
|
$display($time, "%m :: In FETCH_L1_DESC state..."); |
$display($time, " - %m :: In FETCH_L1_DESC state..."); |
|
o_busy = 1'd1; |
|
if ( 1 ) |
begin |
$display($time, "%m :: ACK received. Read data is %x", i_wb_dat); |
$display($time, " - %m :: ACK received. Read data is %x", i_wb_dat); |
|
`ifdef TLB_DEBUG |
$stop; |
268,17 → 268,17
dff}; |
state_nxt = REFRESH_CYCLE; |
|
$display($time, "%m :: It is a section ID. Writing to section TLB as %x. Moving to refresh cycle...", o_setlb_wdata); |
$display($time, " - %m :: It is a section ID. Writing to section TLB as %x. Moving to refresh cycle...", o_setlb_wdata); |
|
$display("#########################################################"); |
$display(" SECTION DESCRIPTOR DETAILS #"); |
$display("#########################################################"); |
$display("# BASE ADDRESS = 0x%x ", o_setlb_wdata[`SECTION_TLB__BASE]); |
$display("# DAC = 0b%b", o_setlb_wdata[`SECTION_TLB__DAC_SEL]); |
$display("# AP bits = 0b%b", o_setlb_wdata[`SECTION_TLB__AP]); |
$display("# Cacheable = 0b%b", o_setlb_wdata[`SECTION_TLB__CB] >> 1); |
$display("# Bufferable = 0b%b", o_setlb_wdata[`SECTION_TLB__CB] & 2'b01); |
$display("#########################################################"); |
$display($time, " - %m :: #########################################################"); |
$display($time, " - %m :: SECTION DESCRIPTOR DETAILS #"); |
$display($time, " - %m :: #########################################################"); |
$display($time, " - %m :: # BASE ADDRESS = 0x%x ", o_setlb_wdata[`SECTION_TLB__BASE]); |
$display($time, " - %m :: # DAC = 0b%b", o_setlb_wdata[`SECTION_TLB__DAC_SEL]); |
$display($time, " - %m :: # AP bits = 0b%b", o_setlb_wdata[`SECTION_TLB__AP]); |
$display($time, " - %m :: # Cacheable = 0b%b", o_setlb_wdata[`SECTION_TLB__CB] >> 1); |
$display($time, " - %m :: # Bufferable = 0b%b", o_setlb_wdata[`SECTION_TLB__CB] & 2'b01); |
$display($time, " - %m :: #########################################################"); |
|
`ifdef TLB_DEBUG |
$stop; |
299,7 → 299,7
tsk_prpr_wb_rd({dff[`L1_PAGE__PTBR], |
i_address[`VA__L2_TABLE_INDEX], 2'd0}); |
|
$display($time, "%m :: L1 received Page ID."); |
$display($time, " - %m :: L1 received Page ID."); |
|
`ifdef TLB_DEBUG |
$stop; |
315,7 → 315,7
o_busy = 1'd0; |
state_nxt = IDLE; |
|
$display($time, "%m :: FSR section translation fault!"); |
$display($time, " - %m :: FSR section translation fault!"); |
|
`ifdef TLB_DEBUG |
$stop; |
361,15 → 361,15
o_sptlb_wdata[`SPAGE_TLB__CB] = dff[`L2_SPAGE__CB]; |
o_sptlb_wdata[`SPAGE_TLB__BASE] = dff[`L2_SPAGE__BASE]; |
|
$display("#########################################################"); |
$display(" SPAGE DESCRIPTOR DETAILS #"); |
$display("#########################################################"); |
$display("# BASE ADDRESS = 0x%x ", o_sptlb_wdata[`SPAGE_TLB__BASE]); |
$display("# DAC = 0b%b", o_sptlb_wdata[`SPAGE_TLB__DAC_SEL]); |
$display("# AP bits = 0b%b", o_sptlb_wdata[`SPAGE_TLB__AP]); |
$display("# Cacheable = 0b%b", o_sptlb_wdata[`SPAGE_TLB__CB] >> 1); |
$display("# Bufferable = 0b%b", o_sptlb_wdata[`SPAGE_TLB__CB] & 2'b01); |
$display("#########################################################"); |
$display($time, " - %m :: #########################################################"); |
$display($time, " - %m :: SPAGE DESCRIPTOR DETAILS #"); |
$display($time, " - %m :: #########################################################"); |
$display($time, " - %m :: # BASE ADDRESS = 0x%x ", o_sptlb_wdata[`SPAGE_TLB__BASE]); |
$display($time, " - %m :: # DAC = 0b%b", o_sptlb_wdata[`SPAGE_TLB__DAC_SEL]); |
$display($time, " - %m :: # AP bits = 0b%b", o_sptlb_wdata[`SPAGE_TLB__AP]); |
$display($time, " - %m :: # Cacheable = 0b%b", o_sptlb_wdata[`SPAGE_TLB__CB] >> 1); |
$display($time, " - %m :: # Bufferable = 0b%b", o_sptlb_wdata[`SPAGE_TLB__CB] & 2'b01); |
$display($time, " - %m :: #########################################################"); |
|
/* Go to REFRESH */ |
state_nxt = REFRESH_CYCLE; |
383,15 → 383,15
/* DAC is inserted in between to save bits */ |
o_lptlb_wdata = {i_address[`VA__LPAGE_TAG], dac_ff, dff}; |
|
$display("#########################################################"); |
$display(" LPAGE DESCRIPTOR DETAILS #"); |
$display("#########################################################"); |
$display("# BASE ADDRESS = 0x%x ", o_lptlb_wdata[`LPAGE_TLB__BASE]); |
$display("# DAC = 0b%b", o_lptlb_wdata[`LPAGE_TLB__DAC_SEL]); |
$display("# AP bits = 0b%b", o_lptlb_wdata[`LPAGE_TLB__AP]); |
$display("# Cacheable = 0b%b", o_lptlb_wdata[`LPAGE_TLB__CB] >> 1); |
$display("# Bufferable = 0b%b", o_lptlb_wdata[`LPAGE_TLB__CB] & 2'b01); |
$display("#########################################################"); |
$display($time, " - %m :: #########################################################"); |
$display($time, " - %m :: LPAGE DESCRIPTOR DETAILS #"); |
$display($time, " - %m :: #########################################################"); |
$display($time, " - %m :: # BASE ADDRESS = 0x%x ", o_lptlb_wdata[`LPAGE_TLB__BASE]); |
$display($time, " - %m :: # DAC = 0b%b", o_lptlb_wdata[`LPAGE_TLB__DAC_SEL]); |
$display($time, " - %m :: # AP bits = 0b%b", o_lptlb_wdata[`LPAGE_TLB__AP]); |
$display($time, " - %m :: # Cacheable = 0b%b", o_lptlb_wdata[`LPAGE_TLB__CB] >> 1); |
$display($time, " - %m :: # Bufferable = 0b%b", o_lptlb_wdata[`LPAGE_TLB__CB] & 2'b01); |
$display($time, " - %m :: #########################################################"); |
|
state_nxt = REFRESH_CYCLE; |
end |
412,7 → 412,7
|
REFRESH_CYCLE: |
begin |
$display($time, "%m :: Entered refresh cycle. Moving to IDLE..."); |
$display($time, " - %m :: Entered refresh cycle. Moving to IDLE..."); |
|
`ifdef TLB_DEBUG |
$stop; |
463,7 → 463,7
|
task tsk_prpr_wb_rd ( input [31:0] adr ); |
begin |
$display($time, "%m :: Reading from location %x", adr); |
$display($time, " - %m :: Reading from location %x", adr); |
|
`ifdef TLB_DEBUG |
$stop; |
478,27 → 478,19
|
// ---------------------------------------------------------------------------- |
|
`ifndef SYNTHESIS |
// assertions_start |
|
always @ (posedge i_mmu_en) |
begin |
$display($time, "%m :: MMU Enabled!"); |
|
`ifdef TLB_DEBUG |
$stop; |
`endif |
$display($time, " - %m :: MMU Enabled!"); |
end |
|
always @ (negedge i_mmu_en) |
begin |
$display($time, "%m :: MMU Disabled!"); |
|
`ifdef TLB_DEBUG |
$stop; |
`endif |
$display($time, " - %m :: MMU Disabled!"); |
end |
|
`endif |
// assertions_end |
|
endmodule // zap_tlb_fsm.v |
|
/zap/trunk/src/rtl/cpu/zap_top.v
31,7 → 31,10
|
module zap_top #( |
|
// Enable cache and MMU. |
// ----------------------------------- |
// BP entries, FIFO depths |
// ----------------------------------- |
|
parameter BP_ENTRIES = 1024, // Predictor depth. |
parameter FIFO_DEPTH = 4, // FIFO depth. |
parameter STORE_BUFFER_DEPTH = 16, // Depth of the store buffer. |
53,14 → 56,19
parameter [31:0] CODE_CACHE_SIZE = 32'd1024 // Cache size in bytes. |
|
)( |
// Clock. CPU uses posedge synchronous design. |
// -------------------------------------- |
// Clock and reset |
// -------------------------------------- |
|
input wire i_clk, |
|
// Active high and synchronous. Must be clean and synchronous. |
input wire i_reset, |
|
// --------------------------------------- |
// Interrupts. |
// Both of them are active high and level trigerred. |
// Both of them are active high and level |
// trigerred. |
// --------------------------------------- |
|
input wire i_irq, |
input wire i_fiq, |
|
67,8 → 75,12
// --------------------- |
// Wishbone interface. |
// --------------------- |
|
output wire o_wb_cyc, |
output wire o_wb_stb, |
output wire o_wb_stb_nxt, |
output wire o_wb_cyc_nxt, |
output wire [31:0] o_wb_adr_nxt, |
output wire [31:0] o_wb_adr, |
output wire o_wb_we, |
output wire [31:0] o_wb_dat, |
87,52 → 99,47
`include "zap_localparams.vh" |
`include "zap_functions.vh" |
|
wire wb_cyc, wb_stb, wb_we; |
wire [3:0] wb_sel; |
wire [31:0] wb_dat, wb_idat; |
wire [31:0] wb_adr; |
wire [2:0] wb_cti; |
wire wb_ack; |
wire wb_cyc, wb_stb, wb_we; |
wire [3:0] wb_sel; |
wire [31:0] wb_dat, wb_idat; |
wire [31:0] wb_adr; |
wire [2:0] wb_cti; |
wire wb_ack; |
reg reset; |
|
reg reset; // Drives global reset throughout the CPU. |
|
// |
// Reset synchrnonizer is assumed to be external to the CPU. |
// * EXTERNAL RESET MUST BE CLEAN AND SYNCHRONOUS * |
// |
// Synchronous reset signal flopped. |
always @ (posedge i_clk) |
begin |
reset <= i_reset; |
end |
|
wire cpu_mmu_en; |
wire [31:0] cpu_cpsr; |
wire cpu_mem_translate; |
wire cpu_mmu_en; |
wire [31:0] cpu_cpsr; |
wire cpu_mem_translate; |
|
wire [31:0] cpu_daddr, cpu_daddr_nxt; |
wire [31:0] cpu_iaddr, cpu_iaddr_nxt; |
wire [31:0] cpu_daddr, cpu_daddr_nxt; |
wire [31:0] cpu_iaddr, cpu_iaddr_nxt; |
|
wire [7:0] dc_fsr; |
wire [31:0] dc_far; |
wire [7:0] dc_fsr; |
wire [31:0] dc_far; |
|
wire cpu_dc_en, cpu_ic_en; |
wire cpu_dc_en, cpu_ic_en; |
|
wire [1:0] cpu_sr; |
wire [31:0] cpu_baddr, cpu_dac_reg; |
wire [1:0] cpu_sr; |
wire [7:0] cpu_pid; |
wire [31:0] cpu_baddr, cpu_dac_reg; |
|
wire cpu_dc_inv, cpu_ic_inv; |
wire cpu_dc_clean, cpu_ic_clean; |
wire cpu_dc_inv, cpu_ic_inv; |
wire cpu_dc_clean, cpu_ic_clean; |
|
wire dc_inv_done, ic_inv_done, dc_clean_done, ic_clean_done; |
wire dc_inv_done, ic_inv_done, dc_clean_done, ic_clean_done; |
|
wire cpu_dtlb_inv, cpu_itlb_inv; |
wire cpu_dtlb_inv, cpu_itlb_inv; |
|
wire data_ack, data_err, instr_ack, instr_err; |
wire data_ack, data_err, instr_ack, instr_err; |
|
wire [31:0] ic_data, dc_data, cpu_dc_dat; |
wire cpu_instr_stb; |
wire cpu_dc_we, cpu_dc_stb; |
wire [3:0] cpu_dc_sel; |
wire [31:0] ic_data, dc_data, cpu_dc_dat; |
wire cpu_instr_stb; |
wire cpu_dc_we, cpu_dc_stb; |
wire [3:0] cpu_dc_sel; |
|
wire c_wb_stb; |
wire c_wb_cyc; |
199,6 → 206,7
.o_baddr (cpu_baddr), |
.o_mmu_en (cpu_mmu_en), |
.o_sr (cpu_sr), |
.o_pid (cpu_pid), |
.o_dcache_inv (cpu_dc_inv), |
.o_icache_inv (cpu_ic_inv), |
.o_dcache_clean (cpu_dc_clean), |
212,16 → 220,8
.o_dcache_en (cpu_dc_en), |
.o_icache_en (cpu_ic_en), |
|
// Combo Outputs - UNUSED. |
.o_clear_from_alu (), |
.o_stall_from_shifter (), |
.o_stall_from_issue (), |
.o_stall_from_decode (), |
.o_clear_from_decode (), |
.o_clear_from_writeback (), |
|
// Data IF nxt. |
.o_data_wb_adr_nxt (cpu_daddr_nxt), // Data addr nxt. Used to drive address of data tag RAM. |
.o_data_wb_adr_nxt (cpu_daddr_nxt), // Data addr nxt. Used to drive address of data tag RAM. |
.o_data_wb_we_nxt (), |
.o_data_wb_cyc_nxt (), |
.o_data_wb_stb_nxt (), |
236,56 → 236,57
|
); |
|
zap_cache #(.CACHE_SIZE(DATA_CACHE_SIZE), |
.SPAGE_TLB_ENTRIES(DATA_SPAGE_TLB_ENTRIES), |
.LPAGE_TLB_ENTRIES(DATA_LPAGE_TLB_ENTRIES), |
.SECTION_TLB_ENTRIES(DATA_SECTION_TLB_ENTRIES)) |
zap_cache #( |
.CACHE_SIZE(DATA_CACHE_SIZE), |
.SPAGE_TLB_ENTRIES(DATA_SPAGE_TLB_ENTRIES), |
.LPAGE_TLB_ENTRIES(DATA_LPAGE_TLB_ENTRIES), |
.SECTION_TLB_ENTRIES(DATA_SECTION_TLB_ENTRIES)) |
u_data_cache ( |
.i_clk (i_clk), |
.i_reset (reset), |
.i_address (cpu_daddr), |
.i_address_nxt (cpu_daddr_nxt), |
.i_clk (i_clk), |
.i_reset (reset), |
.i_address (cpu_daddr + (cpu_pid << 25)), |
.i_address_nxt (cpu_daddr_nxt + (cpu_pid << 25)), |
|
.i_rd (!cpu_dc_we && cpu_dc_stb), |
.i_wr (cpu_dc_we), |
.i_ben (cpu_dc_sel), |
.i_dat (cpu_dc_dat), |
.o_dat (dc_data), |
.o_ack (data_ack), |
.o_err (data_err), |
.i_rd (!cpu_dc_we && cpu_dc_stb), |
.i_wr (cpu_dc_we), |
.i_ben (cpu_dc_sel), |
.i_dat (cpu_dc_dat), |
.o_dat (dc_data), |
.o_ack (data_ack), |
.o_err (data_err), |
|
.o_fsr (dc_fsr), |
.o_far (dc_far), |
.i_mmu_en (cpu_mmu_en), |
.i_cache_en (cpu_dc_en), |
.o_fsr (dc_fsr), |
.o_far (dc_far), |
.i_mmu_en (cpu_mmu_en), |
.i_cache_en (cpu_dc_en), |
.i_cache_inv_req (cpu_dc_inv), |
.i_cache_clean_req (cpu_dc_clean), |
.o_cache_inv_done (dc_inv_done), |
.o_cache_clean_done (dc_clean_done), |
.i_cpsr (cpu_mem_translate ? USR : cpu_cpsr), |
.i_sr (cpu_sr), |
.i_baddr (cpu_baddr), |
.i_dac_reg (cpu_dac_reg), |
.i_tlb_inv (cpu_dtlb_inv), |
.i_cpsr (cpu_mem_translate ? USR : cpu_cpsr), |
.i_sr (cpu_sr), |
.i_baddr (cpu_baddr), |
.i_dac_reg (cpu_dac_reg), |
.i_tlb_inv (cpu_dtlb_inv), |
|
.o_wb_stb (), |
.o_wb_cyc (), |
.o_wb_wen (), |
.o_wb_sel (), |
.o_wb_dat (), |
.o_wb_adr (), |
.o_wb_cti (), |
.o_wb_stb (), |
.o_wb_cyc (), |
.o_wb_wen (), |
.o_wb_sel (), |
.o_wb_dat (), |
.o_wb_adr (), |
.o_wb_cti (), |
|
.i_wb_dat (wb_dat), |
.i_wb_ack (d_wb_ack), |
.i_wb_dat (wb_dat), |
.i_wb_ack (d_wb_ack), |
|
.o_wb_stb_nxt (d_wb_stb), |
.o_wb_cyc_nxt (d_wb_cyc), |
.o_wb_wen_nxt (d_wb_wen), |
.o_wb_sel_nxt (d_wb_sel), |
.o_wb_dat_nxt (d_wb_dat), |
.o_wb_adr_nxt (d_wb_adr), |
.o_wb_cti_nxt (d_wb_cti) |
.o_wb_stb_nxt (d_wb_stb), |
.o_wb_cyc_nxt (d_wb_cyc), |
.o_wb_wen_nxt (d_wb_wen), |
.o_wb_sel_nxt (d_wb_sel), |
.o_wb_dat_nxt (d_wb_dat), |
.o_wb_adr_nxt (d_wb_adr), |
.o_wb_cti_nxt (d_wb_cti) |
); |
|
zap_cache #( |
296,8 → 297,8
u_code_cache ( |
.i_clk (i_clk), |
.i_reset (reset), |
.i_address (cpu_iaddr & 32'hFFFF_FFFC), // Cut off lower 2 bits. |
.i_address_nxt (cpu_iaddr_nxt & 32'hFFFF_FFFC), // Cut off lower 2 bits. |
.i_address ((cpu_iaddr & 32'hFFFF_FFFC) + (cpu_pid << 25)), // Cut off lower 2 bits. |
.i_address_nxt ((cpu_iaddr_nxt & 32'hFFFF_FFFC) + (cpu_pid << 25)), // Cut off lower 2 bits. |
|
.i_rd (cpu_instr_stb), |
.i_wr (1'd0), |
307,8 → 308,8
.o_ack (instr_ack), |
.o_err (instr_err), |
|
.o_fsr(), // UNCONNO. |
.o_far(), // UNCONNO. |
.o_fsr (), |
.o_far (), |
.i_mmu_en (cpu_mmu_en), |
.i_cache_en (cpu_ic_en), |
.i_cache_inv_req (cpu_ic_inv), |
397,8 → 398,17
.o_wb_adr(o_wb_adr), |
.o_wb_cti(o_wb_cti), |
.i_wb_dat(i_wb_dat), |
.i_wb_ack(i_wb_ack) |
.i_wb_ack(i_wb_ack), |
|
// CYC and STB nxt. |
.o_wb_stb_nxt (o_wb_stb_nxt), |
.o_wb_cyc_nxt (o_wb_cyc_nxt), |
.o_wb_adr_nxt (o_wb_adr_nxt), |
.o_wb_sel_nxt (), |
.o_wb_dat_nxt (), |
.o_wb_we_nxt () |
); |
|
endmodule // zap_top.v |
|
`default_nettype wire |
/zap/trunk/src/rtl/cpu/zap_wb_adapter.v
55,8 → 55,15
output wire [2:0] o_wb_cti, |
output wire o_wb_we, |
input wire [31:0] i_wb_dat, |
input wire i_wb_ack |
input wire i_wb_ack, |
|
output reg o_wb_stb_nxt, |
output reg o_wb_cyc_nxt, |
output wire [3:0] o_wb_sel_nxt, |
output wire [31:0] o_wb_dat_nxt, |
output wire [31:0] o_wb_adr_nxt, |
output wire o_wb_we_nxt |
|
); |
|
`include "zap_defines.vh" |
66,6 → 73,7
reg [69:0] fsm_write_data; |
wire w_eob; |
wire w_full; |
wire w_eob_nxt; |
|
assign o_wb_cti = {w_eob, 1'd1, w_eob}; |
|
72,13 → 80,14
wire w_emp; |
|
// {SEL, DATA, ADDR, EOB, WEN} = 4 + 64 + 1 + 1 = 70 bit. |
zap_sync_fifo #(.WIDTH(70), .DEPTH(DEPTH), .FWFT(1'd0)) U_STORE_FIFO ( |
zap_sync_fifo #(.WIDTH(70), .DEPTH(DEPTH), .FWFT(1'd0), .PROVIDE_NXT_DATA(1)) U_STORE_FIFO ( |
.i_clk (i_clk), |
.i_reset (i_reset), |
.i_ack ((i_wb_ack && o_wb_stb) || emp_ff), |
.i_wr_en (fsm_write_en), |
.i_data (fsm_write_data), |
.o_data ({o_wb_sel, o_wb_dat, o_wb_adr, w_eob, o_wb_we}), |
.o_data ({o_wb_sel, o_wb_dat, o_wb_adr, w_eob, o_wb_we}), |
.o_data_nxt ({o_wb_sel_nxt, o_wb_dat_nxt, o_wb_adr_nxt, w_eob_nxt, o_wb_we_nxt}), |
.o_empty (w_emp), |
.o_full (w_full), |
.o_empty_n (), |
86,6 → 95,7
.o_full_n_nxt () |
); |
|
reg emp_nxt; |
reg emp_ff; |
reg [31:0] ctr_nxt, ctr_ff; |
reg [31:0] dff, dnxt; |
102,23 → 112,34
|
reg [$clog2(NUMBER_OF_STATES)-1:0] state_ff, state_nxt; |
|
// FIFO pipeline register. |
always @ (posedge i_clk) |
// FIFO pipeline register and nxt state logic. |
always @ (*) |
begin |
if ( i_reset ) |
emp_nxt = emp_ff; |
o_wb_stb_nxt = o_wb_stb; |
o_wb_cyc_nxt = o_wb_cyc; |
|
if ( i_reset ) |
begin |
emp_ff <= 1'd1; |
o_wb_stb <= 1'd0; |
o_wb_cyc <= 1'd0; |
emp_nxt = 1'd1; |
o_wb_stb_nxt = 1'd0; |
o_wb_cyc_nxt = 1'd0; |
end |
else if ( emp_ff || (i_wb_ack && o_wb_stb) ) |
else if ( emp_ff || (i_wb_ack && o_wb_stb) ) |
begin |
emp_ff <= w_emp; |
o_wb_stb <= !w_emp; |
o_wb_cyc <= !w_emp; |
emp_nxt = w_emp; |
o_wb_stb_nxt = !w_emp; |
o_wb_cyc_nxt = !w_emp; |
end |
end |
|
always @ (posedge i_clk) |
begin |
emp_ff <= emp_nxt; |
o_wb_stb <= o_wb_stb_nxt; |
o_wb_cyc <= o_wb_cyc_nxt; |
end |
|
// Flip flop clocking block. |
always @ (posedge i_clk) |
begin |
186,9 → 207,7
if ( I_WB_CTI == CTI_BURST ) // Burst of 4 words. Each word is 4 byte. |
begin |
state_nxt = PRPR_RD_BURST; |
//state_nxt = PRPR_RD_SINGLE; //PRPR_RD_BURST; |
$display("Read burst requested! Address base = %x", I_WB_ADR); |
//$stop; |
$display($time, " - %m :: Read burst requested. Base address = %x", I_WB_ADR); |
end |
else // Single. |
begin |
216,8 → 235,7
if ( O_WB_ACK ) |
begin |
dnxt = dff + 1'd1; |
$display($time, "EARLY ACK READ BURST. DATA IS %x", O_WB_DAT); |
//$stop; |
$display($time, " - %m :: Early response received for read burst. Data received %x", O_WB_DAT); |
end |
|
if ( ctr_ff == BURST_LEN * 4 ) |
238,8 → 256,8
1'd0 }; |
ctr_nxt = ctr_ff + 4; |
|
$display($time, "READ_BURST :: Writing data SEL = %x DATA = %x ADDR = %x EOB = %x WEN = %x to the FIFO", fsm_write_data[69:66], fsm_write_data[65:34], fsm_write_data[33:2], fsm_write_data[1], fsm_write_data[0]); |
//$stop; |
$display($time, " - %m :: Read Burst. Writing data SEL = %x DATA = %x ADDR = %x EOB = %x WEN = %x to the FIFO", |
fsm_write_data[69:66], fsm_write_data[65:34], fsm_write_data[33:2], fsm_write_data[1], fsm_write_data[0]); |
end |
end |
|
274,8 → 292,7
if ( O_WB_ACK ) |
begin |
dnxt = dff + 1; |
$display("READ BURST! ACK sent. Data provided is %x", O_WB_DAT); |
//$stop; |
$display($time, " - %m :: Read Burst. ACK sent. Data provided is %x", O_WB_DAT); |
end |
|
if ( dff == BURST_LEN && !o_wb_stb ) |
/zap/trunk/src/rtl/cpu/zap_writeback.v
29,8 → 29,8
) |
( |
// Decompile. |
input wire [64*8-1:0] i_decompile, |
output reg [64*8-1:0] o_decompile, |
input wire [64*8-1:0] i_decompile, |
output reg [64*8-1:0] o_decompile, |
|
// Shelve output. |
output wire o_shelve, |
37,10 → 37,8
|
// Clock and reset. |
input wire i_clk, |
input wire i_reset, |
|
|
input wire i_reset, // ZAP reset. |
|
// Inputs from memory unit valid signal. |
input wire i_valid, |
|
88,12 → 86,9
|
// Coprocessor. |
input wire i_copro_reg_en, |
|
input wire [$clog2(PHY_REGS)-1:0] i_copro_reg_wr_index, |
input wire [$clog2(PHY_REGS)-1:0] i_copro_reg_rd_index, |
|
input wire [31:0] i_copro_reg_wr_data, |
|
output reg [31:0] o_copro_reg_rd_data_ff, |
|
// Read data from the register file. |
103,11 → 98,11
output wire [31:0] o_rd_data_3, |
|
// Program counter (dedicated port). |
output reg [31:0] o_pc, |
output reg [31:0] o_pc_nxt, |
output wire [31:0] o_pc, |
output wire [31:0] o_pc_nxt, |
|
// CPSR output |
output reg [31:0] o_cpsr_nxt, |
output wire [31:0] o_cpsr_nxt, |
|
// Clear from writeback |
output reg o_clear_from_writeback, |
120,48 → 115,18
input wire [31:0] i_hijack_sum |
); |
|
/////////////////////////////////////////////////////////////////////////////// |
`include "zap_defines.vh" |
`include "zap_localparams.vh" |
`include "zap_functions.vh" |
|
// ---------------------------------------------- |
// Localparams |
// ---------------------------------------------- |
|
`ifndef SYNTHESIS |
|
reg fiq_ack; |
reg irq_ack; |
reg und_ack; |
reg dabt_ack; |
reg iabt_ack; |
reg swi_ack; |
|
`ifndef ARM_MODE |
`define ARM_MODE (cpsr_ff[T] == 1'd0) |
`endif |
|
// PC and CPSR are separate registers. |
reg [31:0] cpsr_ff, cpsr_nxt; |
reg [31:0] pc_ff, pc_nxt; |
|
reg [$clog2(PHY_REGS)-1:0] wa1, wa2; |
reg [31:0] wdata1, wdata2; |
reg wen; |
|
reg [31:0] pc_shelve_ff, pc_shelve_nxt; |
reg shelve_ff, shelve_nxt; |
|
|
assign o_shelve = shelve_ff; |
|
`ifndef SYNTHESIS |
integer irq_addr = 0; |
`endif |
|
/////////////////////////////////////////////////////////////////////////////// |
|
// Coprocessor accesses. |
always @ (posedge i_clk) |
begin |
o_copro_reg_rd_data_ff <= i_reset ? 0 : o_rd_data_0; |
end |
|
/////////////////////////////////////////////////////////////////////////////// |
|
localparam RST_VECTOR = 32'h00000000; |
localparam UND_VECTOR = 32'h00000004; |
localparam SWI_VECTOR = 32'h00000008; |
170,23 → 135,38
localparam IRQ_VECTOR = 32'h00000018; |
localparam FIQ_VECTOR = 32'h0000001C; |
|
/////////////////////////////////////////////////////////////////////////////// |
// ---------------------------------------------- |
// Variables |
// ---------------------------------------------- |
|
`include "zap_defines.vh" |
`include "zap_localparams.vh" |
`include "zap_functions.vh" |
// assertions_start |
reg fiq_ack; |
reg irq_ack; |
reg und_ack; |
reg dabt_ack; |
reg iabt_ack; |
reg swi_ack; |
integer irq_addr = 0; |
reg temp_set = 0; |
reg error = 0; |
// assertions_end |
|
/////////////////////////////////////////////////////////////////////////////// |
reg [31:0] cpsr_ff, cpsr_nxt; |
reg [31:0] pc_ff, pc_nxt; |
reg [$clog2(PHY_REGS)-1:0] wa1, wa2; |
reg [31:0] wdata1, wdata2; |
reg wen; |
reg [31:0] pc_shelve_ff, pc_shelve_nxt; |
reg shelve_ff, shelve_nxt; |
|
// CPSR dedicated output. |
always @* |
begin |
o_pc = pc_ff; |
o_pc_nxt = pc_nxt & 32'hfffffffe; |
o_cpsr_nxt = cpsr_nxt; |
end |
assign o_shelve = shelve_ff; // Shelve the PC until it is needed. |
assign o_pc = pc_ff; |
assign o_pc_nxt = pc_nxt & 32'hfffffffe; |
assign o_cpsr_nxt = cpsr_nxt; |
|
/////////////////////////////////////////////////////////////////////////////// |
// ---------------------------------------------- |
// Register file |
// ---------------------------------------------- |
|
zap_register_file u_zap_register_file |
( |
212,57 → 192,46
.o_rd_data_d ( o_rd_data_3 ) |
); |
|
/////////////////////////////////////////////////////////////////////////////// |
// --------------------------------------------- |
// Combinational Logic |
// --------------------------------------------- |
|
`define ARM_MODE (cpsr_ff[T] == 1'd0) |
|
`ifndef SYNTHESIS |
reg temp_set; |
reg error; |
initial error = 0; |
initial temp_set = 0; |
`endif |
|
// The register file function. |
always @* |
always @ (*) |
begin: blk1 |
|
integer i; |
|
shelve_nxt = shelve_ff; |
shelve_nxt = shelve_ff; |
pc_shelve_nxt = pc_shelve_ff; |
|
|
|
`ifndef SYNTHESIS |
fiq_ack = 0; |
irq_ack = 0; |
und_ack = 0; |
// assertions_start |
fiq_ack = 0; |
irq_ack = 0; |
und_ack = 0; |
dabt_ack = 0; |
iabt_ack = 0; |
swi_ack = 0; |
`endif |
swi_ack = 0; |
// assertions_end |
|
o_hijack = 0; |
o_hijack = 0; |
o_hijack_op1 = 0; |
o_hijack_op2 = 0; |
o_hijack_cin = 0; |
|
wen = 1'd0; |
wa1 = PHY_RAZ_REGISTER; |
wa2 = PHY_RAZ_REGISTER; |
wdata1 = 32'd0; |
wdata2 = 32'd0; |
wen = 1'd0; |
wa1 = PHY_RAZ_REGISTER; |
wa2 = PHY_RAZ_REGISTER; |
wdata1 = 32'd0; |
wdata2 = 32'd0; |
|
o_clear_from_writeback = 0; |
|
pc_nxt = pc_ff; |
pc_nxt = pc_ff; |
cpsr_nxt = cpsr_ff; |
|
|
// PC control sequence. |
// Low priority PC control tree. |
|
|
if ( i_clear_from_alu ) |
begin |
pc_shelve(i_pc_from_alu); |
306,7 → 275,6
cpsr_nxt[T] = 1'd0; // Go to ARM mode. |
end |
|
|
if ( i_data_abt ) |
begin |
o_hijack = 1'd1; |
316,59 → 284,62
|
// Returns do LR - 8 to get back to the same instruction. |
pc_shelve( DABT_VECTOR ); |
wen = 1; |
wdata1 = `ARM_MODE ? i_pc_buf_ff : i_hijack_sum[31:0]; |
wa1 = PHY_ABT_R14; |
wa2 = PHY_ABT_SPSR; |
wdata2 = cpsr_ff; |
cpsr_nxt[`CPSR_MODE] = ABT; |
|
`ifndef SYNTHESIS |
wen = 1; |
wdata1 = `ARM_MODE ? i_pc_buf_ff : i_hijack_sum[31:0]; |
wa1 = PHY_ABT_R14; |
wa2 = PHY_ABT_SPSR; |
wdata2 = cpsr_ff; |
cpsr_nxt[`CPSR_MODE] = ABT; |
|
// assertions_start |
dabt_ack = 1'd1; |
`endif |
// assertions_end |
|
end |
else if ( i_fiq ) |
begin |
$display($time, " - %m :: FIQ detected."); |
|
// Returns do LR - 4 to get back to the same instruction. |
pc_shelve ( FIQ_VECTOR ); |
wen = 1; |
wdata1 = `ARM_MODE ? i_wr_data : i_pc_buf_ff ; |
wa1 = PHY_FIQ_R14; |
wa2 = PHY_FIQ_SPSR; |
wdata2 = cpsr_ff; |
cpsr_nxt[`CPSR_MODE] = FIQ; |
cpsr_nxt[F] = 1'd1; |
|
`ifndef SYNTHESIS |
wen = 1; |
wdata1 = `ARM_MODE ? i_wr_data : i_pc_buf_ff ; |
wa1 = PHY_FIQ_R14; |
wa2 = PHY_FIQ_SPSR; |
wdata2 = cpsr_ff; |
cpsr_nxt[`CPSR_MODE] = FIQ; |
cpsr_nxt[F] = 1'd1; |
|
// assertions_start |
fiq_ack = 1'd1; |
`endif |
// assertions_end |
end |
else if ( i_irq ) |
begin |
$display($time, " - %m :: IRQ detected."); |
|
pc_shelve (IRQ_VECTOR); |
|
wen = 1; |
wdata1 = `ARM_MODE ? i_wr_data : i_pc_buf_ff ; |
|
`ifndef SYNTHESIS |
irq_addr = wdata1; |
`endif |
|
wa1 = PHY_IRQ_R14; |
wa2 = PHY_IRQ_SPSR; |
wdata2 = cpsr_ff; |
cpsr_nxt[`CPSR_MODE] = IRQ; |
wen = 1; |
wdata1 = `ARM_MODE ? i_wr_data : i_pc_buf_ff ; |
wa1 = PHY_IRQ_R14; |
wa2 = PHY_IRQ_SPSR; |
wdata2 = cpsr_ff; |
cpsr_nxt[`CPSR_MODE] = IRQ; |
// Returns do LR - 4 to get back to the same instruction. |
|
`ifndef SYNTHESIS |
irq_ack = 1'd1; |
`endif |
// assertions_start |
irq_addr = wdata1; |
irq_ack = 1'd1; |
// assertions_end |
end |
else if ( i_instr_abt ) |
begin |
// Returns do LR - 4 to get back to the same instruction. |
pc_shelve (PABT_VECTOR); |
|
wen = 1; |
wdata1 = `ARM_MODE ? i_wr_data : i_pc_buf_ff ; |
wa1 = PHY_ABT_R14; |
376,48 → 347,50
wdata2 = cpsr_ff; |
cpsr_nxt[`CPSR_MODE] = ABT; |
|
`ifndef SYNTHESIS |
// assertions_start |
iabt_ack = 1'd1; |
`endif |
// assertions_end |
end |
else if ( i_swi ) |
begin |
// Returns do LR to return to the next instruction. |
pc_shelve(SWI_VECTOR); |
wen = 1; |
wdata1 = `ARM_MODE ? i_wr_data : i_pc_buf_ff ; |
wa1 = PHY_SVC_R14; |
wa2 = PHY_SVC_SPSR; |
wdata2 = cpsr_ff; |
cpsr_nxt[`CPSR_MODE] = SVC; |
|
`ifndef SYNTHESIS |
wen = 1; |
wdata1 = `ARM_MODE ? i_wr_data : i_pc_buf_ff ; |
wa1 = PHY_SVC_R14; |
wa2 = PHY_SVC_SPSR; |
wdata2 = cpsr_ff; |
cpsr_nxt[`CPSR_MODE] = SVC; |
|
// assertions_start |
swi_ack = 1'd1; |
`endif |
// assertions_end |
end |
else if ( i_und ) |
begin |
// Returns do LR to return to the next instruction. |
pc_shelve(UND_VECTOR); |
wen = 1; |
wdata1 = `ARM_MODE ? i_wr_data : i_pc_buf_ff ; |
wa1 = PHY_UND_R14; |
wa2 = PHY_UND_SPSR; |
wdata2 = cpsr_ff; |
cpsr_nxt[`CPSR_MODE] = UND; |
|
`ifndef SYNTHESIS |
wen = 1; |
wdata1 = `ARM_MODE ? i_wr_data : i_pc_buf_ff ; |
wa1 = PHY_UND_R14; |
wa2 = PHY_UND_SPSR; |
wdata2 = cpsr_ff; |
cpsr_nxt[`CPSR_MODE] = UND; |
|
// assertions_start |
und_ack = 1'd1; |
`endif |
// assertions_end |
end |
else if ( i_copro_reg_en ) |
begin |
// Write to register. |
// Write to register (Coprocessor command). |
wen = 1; |
wa1 = i_copro_reg_wr_index; |
wdata1 = i_copro_reg_wr_data; |
end |
else if ( i_valid ) |
else if ( i_valid ) // If valid, |
begin |
// Only then execute the instruction at hand... |
cpsr_nxt = i_flags; |
436,17 → 409,22
// Load to PC will trigger from writeback. |
if ( i_mem_load_ff && i_wr_index_1 == ARCH_PC) |
begin |
$display($time, " - %m :: Detected load to PC. Trigger a writeback."); |
|
pc_shelve (i_wr_data_1); |
o_clear_from_writeback = 1'd1; |
end |
end |
|
// Ensure lower 2 bits of PC are always tied to VSS. |
pc_nxt = pc_nxt & 32'hffff_fffe; |
end |
|
/////////////////////////////////////////////////////////////////////////////// |
// ---------------------------------------------- |
// Sequential Logic |
// ---------------------------------------------- |
|
always @ (posedge i_clk) |
always @ ( posedge i_clk ) |
begin |
if ( i_reset ) |
begin |
461,15 → 439,18
end |
else |
begin |
shelve_ff <= shelve_nxt; |
pc_shelve_ff <= pc_shelve_nxt; |
pc_ff <= pc_nxt; |
cpsr_ff <= cpsr_nxt; |
o_decompile <= i_decompile; |
shelve_ff <= shelve_nxt; |
pc_shelve_ff <= pc_shelve_nxt; |
pc_ff <= pc_nxt; |
cpsr_ff <= cpsr_nxt; |
o_decompile <= i_decompile; |
o_copro_reg_rd_data_ff <= o_rd_data_0; |
end |
end |
|
/////////////////////////////////////////////////////////////////////////////// |
// ---------------------------------------------- |
// Tasks |
// ---------------------------------------------- |
|
task pc_shelve (input [31:0] new_pc); |
begin |
487,30 → 468,30
end |
endtask |
|
`ifndef SYNTHESIS |
// assertions_start |
|
always @* |
if ( cpsr_nxt[`CPSR_MODE] != USR && cpsr_ff[`CPSR_MODE] == USR ) |
begin |
if ( |
i_data_abt || |
i_fiq || |
i_irq || |
i_instr_abt || |
i_swi || |
i_und |
) |
always @ (*) |
if ( cpsr_nxt[`CPSR_MODE] != USR && cpsr_ff[`CPSR_MODE] == USR ) |
begin |
// OKAY... |
if ( |
i_data_abt || |
i_fiq || |
i_irq || |
i_instr_abt || |
i_swi || |
i_und |
) |
begin |
// OKAY... |
end |
else |
begin |
$display($time, "Error : %m CPU is changing out of USR mode without an exception..."); |
$stop; |
end |
end |
else |
begin |
$display($time, "Error : %m CPU is changing out of USR mode without an exception..."); |
$stop; |
end |
end |
|
`endif |
// assertions_end |
|
endmodule // zap_register_file.v |
`default_nettype wire |
/zap/trunk/src/scripts/check_arc.sh
File deleted
/zap/trunk/src/scripts/Config.cfg_template
40,14 → 40,16
SYNTHESIS => 1, # Make this to 1 to simulate compile from a synthesis perspective. |
|
# Testbench configuration. |
UART_TX_TERMINAL => 1, # 1 Enables UART TX terminal. 0 disables it. |
WAVES => 0, # 1 Enables wave logging. |
UART0_TX_TERMINAL => 1, # 1 Enables UART TX terminal 0. 0 disables it. |
UART1_TX_TERMINAL => 1, # 1 Enables UART TX terminal 1. 0 disables it. |
UART0_RX_TERMINAL => 1, # RX terminal 0. Characters typed go to UART RX. |
UART1_RX_TERMINAL => 1, # RX terminal 1. Characters typed go to UART RX. |
EXT_RAM_SIZE => 32768, # External RAM size. |
SEED => -1, # Seed. Use -1 to use random seed. |
DUMP_START => 2000, # Starting memory address from which to dump. |
DUMP_SIZE => 200, # Length of dump in bytes. |
MAX_CLOCK_CYCLES => 100000, # Clock cycles to run the simulation for. |
ALLOW_STALLS => 1, # Make this 1 to allow external RAM to signal a stall. |
DEFINE_TLB_DEBUG => 0, # Make this 1 to define TLB_DEBUG. Useful for debugging the TLB. |
REG_CHECK => {"r1" => "32'h4", |
"r2" => "32'd3"}, # Make this an anonymous has with entries like "r10" => "32'h0" etc. |
FINAL_CHECK => {"32'h100" => "32'd4", |
/zap/trunk/src/scripts/makefile
36,11 → 36,9
.PHONY: c2asm |
.PHONY: compiler |
.PHONY: dirs |
.PHONY: cleanall |
|
ARCH := armv5t |
TC := $(shell basename `pwd`) |
GCC_PATH := ../../../obj/gcc-arm-none-eabi-*/bin/ |
SCRIPT_PATH := ../../scripts/ |
C_FILES := $(wildcard *.c) |
S_FILES := $(wildcard *.s) |
48,15 → 46,14
LD_FILE := $(wildcard *.ld) |
COBJFILES := $(patsubst %.c,../../../obj/ts/$(TC)/%_c.o,$(C_FILES)) |
AOBJFILES := $(patsubst %.s,../../../obj/ts/$(TC)/%_s.o,$(S_FILES)) |
GCC_SRC := ../../../sw/gcc-arm-none-eabi-*-linux.tar.* |
CFLAGS := -c -msoft-float -mfloat-abi=soft -march=$(ARCH) -g |
SFLAGS := -march=$(ARCH) -g |
LFLAGS := -T |
OFLAGS := -O binary |
CC := $(GCC_PATH)/arm-none-eabi-gcc |
AS := $(GCC_PATH)/arm-none-eabi-as |
LD := $(GCC_PATH)/arm-none-eabi-ld |
OB := $(GCC_PATH)/arm-none-eabi-objcopy |
CC := arm-none-eabi-gcc |
AS := arm-none-eabi-as |
LD := arm-none-eabi-ld |
OB := arm-none-eabi-objcopy |
|
# This rule will convert every ASM to file its corresponding object file. |
../../../obj/ts/$(TC)/%_s.o: %.s |
82,17 → 79,12
all: dirs $(CC) ../../../obj/ts/$(TC)/zap_mem.v |
perl $(SCRIPT_PATH)/run_sim.pl +test+$(TC) |
|
$(CC): |
$(AS): |
$(LD): |
$(OB): |
|
$(CC): $(GCC_SRC) |
mkdir -p ../../../obj/ts/$(TC)/ |
tar -xvf $(GCC_SRC) -C ../../../obj/ |
touch $@ |
|
dirs: |
bash ../../scripts/check_arc.sh |
mkdir -p ../../../obj/ts/$(TC)/ |
touch ../../../obj/ts/$(TC)/ |
|
100,10 → 92,6
mkdir -p ../../../obj/ts/$(TC)/ |
rm -fv ../../../obj/ts/$(TC)/* |
|
cleanall: |
rm -fv ../../../obj/ts/$(TC)/* |
rm -rfv ../../../obj/ts/$(TC)/../../gcc-arm-none-* |
|
c2asm: |
$(CC) -S $(CFLAGS) $(X) -o ../../../obj/ts/$(TC)/$(X).asm |
|
/zap/trunk/src/scripts/run_sim.pl
1,51 → 1,36
#!/usr/bin/perl -w |
|
#// ----------------------------------------------------------------------------- |
#// -- -- |
#// -- (C) 2016-2018 Revanth Kamaraj. -- |
#// -- -- |
#// -- -------------------------------------------------------------------------- |
#// -- -- |
#// -- This program is free software; you can redistribute it and/or -- |
#// -- modify it under the terms of the GNU General Public License -- |
#// -- as published by the Free Software Foundation; either version 2 -- |
#// -- of the License, or (at your option) any later version. -- |
#// -- -- |
#// -- This program is distributed in the hope that it will be useful, -- |
#// -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- |
#// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- |
#// -- GNU General Public License for more details. -- |
#// -- -- |
#// -- You should have received a copy of the GNU General Public License -- |
#// -- along with this program; if not, write to the Free Software -- |
#// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -- |
#// -- 02110-1301, USA. -- |
#// -- -- |
#// ----------------------------------------------------------------------------- |
# ----------------------------------------------------------------------------- |
# -- -- |
# -- (C) 2016-2018 Revanth Kamaraj. -- |
# -- -- |
# -- -------------------------------------------------------------------------- |
# -- -- |
# -- This program is free software; you can redistribute it and/or -- |
# -- modify it under the terms of the GNU General Public License -- |
# -- as published by the Free Software Foundation; either version 2 -- |
# -- of the License, or (at your option) any later version. -- |
# -- -- |
# -- This program is distributed in the hope that it will be useful, -- |
# -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- |
# -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- |
# -- GNU General Public License for more details. -- |
# -- -- |
# -- You should have received a copy of the GNU General Public License -- |
# -- along with this program; if not, write to the Free Software -- |
# -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -- |
# -- 02110-1301, USA. -- |
# -- -- |
# ----------------------------------------------------------------------------- |
|
|
my $HELP = " |
############################################################################### |
|
Perl script to simulate the ZAP processor. This script itself calls other |
scripts and programs. |
|
Usage : |
perl run_sim.pl |
+test+<test_case> -- Run a specific test case. |
+irq_en -- Configure TB to use IRQ. |
|
############################################################################### |
"; |
|
use strict; |
use warnings; |
|
my $FH; |
|
my %Config = do "./Config.cfg"; |
|
# Env setup. |
# Extract from config |
my $WAVES = $Config{'WAVES'}; |
my $RAM_SIZE = $Config{'EXT_RAM_SIZE'}; |
my $SEED = $Config{'SEED'}; |
my $SYNTHESIS = $Config{'SYNTHESIS'}; |
53,11 → 38,12
my $DUMP_SIZE = $Config{'DUMP_SIZE'}; |
my $MAX_CLOCK_CYCLES = $Config{'MAX_CLOCK_CYCLES'}; |
my $TLB_DEBUG = $Config{'DEFINE_TLB_DEBUG'}; |
my $STALL = $Config{'ALLOW_STALLS'}; |
my $TX_TERM = $Config{'UART_TX_TERMINAL'}; |
my $TX_TERM0 = $Config{'UART0_TX_TERMINAL'}; |
my $TX_TERM1 = $Config{'UART1_TX_TERMINAL'}; |
my $RX_TERM0 = $Config{'UART0_RX_TERMINAL'}; |
my $RX_TERM1 = $Config{'UART1_RX_TERMINAL'}; |
my $IRQ_EN = $Config{'IRQ_EN'}; |
|
# System configuration. |
my $FIQ_EN = $Config{'FIQ_EN'}; |
my $DATA_CACHE_SIZE = $Config{'DATA_CACHE_SIZE'}; |
my $CODE_CACHE_SIZE = $Config{'CODE_CACHE_SIZE'}; |
my $CODE_SECTION_TLB_ENTRIES = $Config{'CODE_SECTION_TLB_ENTRIES'}; |
74,57 → 60,59
my $ZAP_HOME = "../../../"; |
my $TEST = "null"; |
my $SCRATCH = "/dev/null"; |
my $FIQ_EN = 0; |
|
# Generate a random seed if needed |
if ( $SEED == -1 ) { |
$SEED = randSeed(); |
$SEED = int rand (0xffffffff); |
} |
|
sub randSeed { |
return int rand (0xffffffff); |
} |
|
# Parse arguments. |
foreach(@ARGV) { |
if (/^\+test\+(.*)/) |
{ |
if (/^\+test\+(.*)/) { |
$SCRATCH = "$ZAP_HOME/obj/ts/$1"; $TEST = $1; |
} else { |
die "Unrecognized option to run_sim.pl\n"; |
} |
elsif (/help/) |
{ |
print "$HELP"; exit 0 |
} |
else |
{ |
die "Unrecognized $_ $HELP"; |
} |
} |
|
if ( $TEST eq "null" ) { |
print "$HELP"; |
die "ERROR: +test+<testname> not specified!"; |
} |
# Log file - the final file is compressed. |
my $LOG_FILE_PATH = "$SCRATCH/zap.log"; |
my $COMPRESSED_LOG_FILE_PATH = "$SCRATCH/zap.log.gz"; |
|
my $LOG_FILE_PATH = "$SCRATCH/zap.log"; |
my $VVP_PATH = "$SCRATCH/zap.vvp"; |
my $VCD_PATH = "$SCRATCH/zap.vcd"; |
my $PROG_PATH = "$SCRATCH/zap_mem.v"; |
my $TARGET_BIN_PATH = "$SCRATCH/zap.bin"; |
my $UART_PATH = "$SCRATCH/zapuart.fifo"; |
# VCD file - the final file is compressed. |
my $VCD_PATH = "$SCRATCH/zap.vcd"; |
my $COMPRESSED_VCD_PATH = "$SCRATCH/zap.vcd.gz"; |
|
# Generate IVL options. |
my $IVL_OPTIONS .= |
" -I$ZAP_HOME/src/rtl/cpu -I$ZAP_HOME/obj/ts/$TEST -I$ZAP_HOME/src/testbench/cpu/uart16550/rtl $ZAP_HOME/src/testbench/cpu/uart16550/rtl/*.v $ZAP_HOME/src/testbench/cpu/timer/timer.v $ZAP_HOME/src/testbench/cpu/vic/vic.v"; |
# Paths |
my $VVP_PATH = "$SCRATCH/zap.vvp"; |
my $PROG_PATH = "$SCRATCH/zap_mem.v"; |
my $TARGET_BIN_PATH = "$SCRATCH/zap.bin"; |
my $UART0_PATH_TX = "$SCRATCH/zapuart0.tx"; |
my $UART1_PATH_TX = "$SCRATCH/zapuart1.tx"; |
my $UART0_PATH_RX = "$SCRATCH/zapuart0.rx"; |
my $UART1_PATH_RX = "$SCRATCH/zapuart1.rx"; |
|
$IVL_OPTIONS .= " $ZAP_HOME/src/rtl/*/*.v $ZAP_HOME/src/testbench/cpu/*.v -o $VVP_PATH -gstrict-ca-eval -Wall -g2001 -Winfloop -DSEED=$SEED -DMEMORY_IMAGE=\\\"$PROG_PATH\\\" "; |
# Generate IVL options including VCD generation path. |
my $IVL_OPTIONS = ""; |
|
$IVL_OPTIONS .= " -DVCD_FILE_PATH=\\\"$VCD_PATH\\\" "; |
# Compile CPU |
$IVL_OPTIONS .= " -I$ZAP_HOME/src/rtl/cpu -I$ZAP_HOME/obj/ts/$TEST "; |
$IVL_OPTIONS .= " $ZAP_HOME/src/rtl/cpu/*.v "; |
|
if ( $TX_TERM) { |
$IVL_OPTIONS .= " -DUART_FILE_PATH=\\\"$UART_PATH\\\" "; |
} else { |
$IVL_OPTIONS .= " -DUART_FILE_PATH=\\\"/dev/null\\\" "; |
} |
# Compile other TB components |
$IVL_OPTIONS .= " -I$ZAP_HOME/src/testbench/External_IP/uart16550/rtl "; |
$IVL_OPTIONS .= " $ZAP_HOME/src/testbench/External_IP/uart16550/rtl/*.v "; |
$IVL_OPTIONS .= " $ZAP_HOME/src/testbench/*.v "; |
$IVL_OPTIONS .= " -o $VVP_PATH -gstrict-ca-eval -Wall -g2001 -Winfloop -DSEED=$SEED -DMEMORY_IMAGE=\\\"$PROG_PATH\\\" "; |
$IVL_OPTIONS .= " -DVCD_FILE_PATH=\\\"$VCD_PATH\\\" "; |
|
# Generate UART related defines for both the UARTs. |
if ( $TX_TERM0 ) { $IVL_OPTIONS .= " -DUART0_FILE_PATH_TX=\\\"$UART0_PATH_TX\\\" "; } else { $IVL_OPTIONS .= " -DUART0_FILE_PATH_TX=\\\"/dev/null\\\" "; } |
if ( $TX_TERM1 ) { $IVL_OPTIONS .= " -DUART1_FILE_PATH_TX=\\\"$UART1_PATH_TX\\\" "; } else { $IVL_OPTIONS .= " -DUART1_FILE_PATH_TX=\\\"/dev/null\\\" "; } |
if ( $RX_TERM0 ) { $IVL_OPTIONS .= " -DUART0_FILE_PATH_RX=\\\"$UART0_PATH_RX\\\" "; } else { $IVL_OPTIONS .= " -DUART0_FILE_PATH_RX=\\\"/dev/null\\\" "; } |
if ( $RX_TERM1 ) { $IVL_OPTIONS .= " -DUART1_FILE_PATH_RX=\\\"$UART1_PATH_RX\\\" "; } else { $IVL_OPTIONS .= " -DUART1_FILE_PATH_RX=\\\"/dev/null\\\" "; } |
|
# CPU / TB configuration related parameters. |
$IVL_OPTIONS .= " -Pzap_test.RAM_SIZE=$RAM_SIZE -Pzap_test.START=$DUMP_START -Pzap_test.COUNT=$DUMP_SIZE -DLINUX -Pzap_test.STORE_BUFFER_DEPTH=$SBUF_DEPTH "; |
$IVL_OPTIONS .= " -Pzap_test.BP_ENTRIES=$BP -Pzap_test.FIFO_DEPTH=$FIFO "; |
$IVL_OPTIONS .= " -Pzap_test.DATA_SECTION_TLB_ENTRIES=$DATA_SECTION_TLB_ENTRIES "; |
131,30 → 119,33
$IVL_OPTIONS .= " -Pzap_test.DATA_LPAGE_TLB_ENTRIES=$DATA_LPAGE_TLB_ENTRIES -Pzap_test.DATA_SPAGE_TLB_ENTRIES=$DATA_SPAGE_TLB_ENTRIES -Pzap_test.DATA_CACHE_SIZE=$DATA_CACHE_SIZE "; |
$IVL_OPTIONS .= " -Pzap_test.CODE_SECTION_TLB_ENTRIES=$CODE_SECTION_TLB_ENTRIES -Pzap_test.CODE_LPAGE_TLB_ENTRIES=$CODE_LPAGE_TLB_ENTRIES -Pzap_test.CODE_SPAGE_TLB_ENTRIES=$CODE_SPAGE_TLB_ENTRIES "; |
$IVL_OPTIONS .= " -Pzap_test.CODE_CACHE_SIZE=$CODE_CACHE_SIZE "; |
$IVL_OPTIONS .= "-DMAX_CLOCK_CYCLES=$MAX_CLOCK_CYCLES "; |
|
if ( $IRQ_EN ) { print "Script: IRQ defined.\n" ; $IVL_OPTIONS .= "-DIRQ_EN "; } |
if ( $FIQ_EN ) { $IVL_OPTIONS .= "-DFIQ_EN "; } |
if ( $STALL ) { print "Script: Stall defined.\n" ; $IVL_OPTIONS .= "-DSTALL "; } |
if ( $SYNTHESIS ) { $IVL_OPTIONS .= "-DSYNTHESIS ";} |
# Defines |
if ( 1 ) { $IVL_OPTIONS .= " -DMAX_CLOCK_CYCLES=$MAX_CLOCK_CYCLES " } |
if ( $IRQ_EN ) { $IVL_OPTIONS .= "-DIRQ_EN "; } |
if ( $FIQ_EN ) { $IVL_OPTIONS .= "-DFIQ_EN "; } |
if ( $SYNTHESIS ) { $IVL_OPTIONS .= "-DSYNTHESIS "; } |
if ( $TLB_DEBUG ) { $IVL_OPTIONS .= "-DTLB_DEBUG "; } |
if ( $WAVES ) { $IVL_OPTIONS .= "-DWAVES "; } |
|
if ( $MAX_CLOCK_CYCLES == 0 ) { die "*E: MAX_CLOCK_CYCLES set to 0. Ending script..."; } |
if ( $TLB_DEBUG ) { print "Warning: TLB_DEBUG defined. Do not use for unattended systems!"; $IVL_OPTIONS .= "-DTLB_DEBUG ";} |
########################################################################################################################################### |
# Create checker assertion verilog include file. |
########################################################################################################################################### |
|
open(HH, ">$ZAP_HOME/obj/ts/$TEST/zap_check.vh") or die "Could not write to ../../../obj/ts/$TEST/zap_check.vh"; |
|
my $REG_HIER = "u_chip_top.u_zap_top.u_zap_core.u_zap_writeback.u_zap_register_file"; |
my $RAM_HIER = "u_chip_top.u_ram.ram"; |
my $X = $Config{'FINAL_CHECK'}; |
|
foreach(keys (%$X)) { |
my $string = "$_, $$X{$_}, U_MODEL_RAM_DATA.ram[$_]"; |
print "if ( U_MODEL_RAM_DATA.ram[$_/4] != ", $$X{"$_"}, ') begin $display("Error: Memory values not matched. PTR = %d EXP = %x REC = %x", ', $string , ' ); $finish; end else $display("RAM check passed!");',"\n"; |
print HH "if ( U_MODEL_RAM_DATA.ram[$_/4] != ", $$X{"$_"}, ') begin $display("Error: Memory values not matched. PTR = %d EXP = %x REC = %x", ', $string , ' ); $finish; end else $display("RAM check passed!");',"\n"; |
my $string = "$_, $$X{$_}, ${RAM_HIER}[$_/4]"; |
print "if ( ${RAM_HIER}[$_/4] != ", $$X{"$_"}, ') begin $display("Error: Memory values not matched. PTR = %d EXP = %x REC = %x", ', $string , ' ); $finish; end else $display("RAM check passed!");',"\n"; |
print HH "if ( ${RAM_HIER}[$_/4] != ", $$X{"$_"}, ') begin $display("Error: Memory values not matched. PTR = %d EXP = %x REC = %x", ', $string , ' ); $finish; end else $display("RAM check passed!");',"\n"; |
} |
|
$X = $Config{'REG_CHECK'}; |
|
my $REG_HIER = "u_zap_top.u_zap_core.u_zap_writeback.u_zap_register_file"; |
|
foreach(keys (%$X)) { |
my $string = "\"$_\", $$X{$_}, $REG_HIER.$_"; |
print "if ( $REG_HIER.$_ != ", $$X{"$_"}, ') begin $display("Error: Register values not matched. PTR = %s EXP = %x REC = %x", ', $string , ' ); $finish; end else $display("Reg check passed!");',"\n"; |
163,29 → 154,67
|
print HH '$display("Simulation Complete. All checks (if any) passed.");$finish;'; |
|
print "*I: Rand is $SEED...\n"; |
print "iverilog $IVL_OPTIONS\n"; |
############################################################################################################################################ |
# Set up UART terminals |
############################################################################################################################################ |
|
if ( $TX_TERM ) { |
system("rm -f $UART_PATH"); # Remove UART file. |
system("mknod $UART_PATH p"); # Create a UART output FIFO file. |
if ( $TX_TERM0 ) { |
system1("rm -f $UART0_PATH_TX"); # Remove UART file. |
system1("mknod $UART0_PATH_TX p"); # Create a UART output FIFO file. |
} |
|
# UART output monitor. |
if ( $TX_TERM1 ) { |
system1("rm -f $UART1_PATH_TX"); # Remove UART file. |
system1("mknod $UART1_PATH_TX p"); # Create a UART output FIFO file. |
} |
|
if ( $RX_TERM0 ) { |
system1("rm -f $UART0_PATH_RX"); # Remove UART file. |
system1("touch $UART0_PATH_RX"); # Create file. |
} |
|
if ( $RX_TERM1 ) { |
system1("rm -f $UART1_PATH_RX"); # Remove UART file. |
system1("touch $UART1_PATH_RX"); # Create file. |
} |
|
die "Error: XTerm could not be found!" if system("which xterm"); |
die "Error: Icarus Verilog could not be found!" if system("which iverilog"); |
|
if ( $TX_TERM == 1 ) { |
print "Setting up UART output monitor\n"; |
system("xterm -T 'TB UART Output' -hold -e 'cat $UART_PATH ; echo ; echo ------------------ ; echo UART_Output_Complete ; echo ------------------' &"); |
if ( $TX_TERM0 ) { die "Failed to open UART TX terminal 0." if system1("xterm -T 'TB UART Output' -hold -e 'cat $UART0_PATH_TX' &"); } |
if ( $TX_TERM1 ) { die "Failed to open UART TX terminal 1." if system1("xterm -T 'TB UART Output' -hold -e 'cat $UART1_PATH_TX' &"); } |
if ( $RX_TERM0 ) { die "Failed to open UART RX terminal 0." if system1("xterm -T 'TB UART Input' -hold -e 'bash $ZAP_HOME/src/scripts/uart_input.bash $UART0_PATH_RX' &"); } |
if ( $RX_TERM1 ) { die "Failed to open UART RX terminal 1." if system1("xterm -T 'TB UART Input' -hold -e 'bash $ZAP_HOME/src/scripts/uart_input.bash $UART1_PATH_RX' &"); } |
|
############################################################################################################################################# |
# Compile using VVP |
############################################################################################################################################# |
|
die "*E: Verilog Compilation Failed!\n" if system1("iverilog $IVL_OPTIONS"); |
die "*E: Failed to read out Log FIFO!\n" if system1("rm -f $LOG_FILE_PATH ; mkfifo $LOG_FILE_PATH ; cat $LOG_FILE_PATH | gzip > $COMPRESSED_LOG_FILE_PATH &"); |
|
if ( $WAVES ) { |
die "*E: Failed to read out VCD FIFO!\n" if system1("rm -f $VCD_PATH ; mkfifo $VCD_PATH ; cat $VCD_PATH | gzip > $COMPRESSED_VCD_PATH &"); |
} |
|
die "*E: Verilog Compilation Failed!\n" if system("iverilog $IVL_OPTIONS"); |
die "*E: VVP execution error!\n" if system("vvp $VVP_PATH | tee $LOG_FILE_PATH"); |
die "*E: VVP execution error!\n" if system1("vvp $VVP_PATH | tee $LOG_FILE_PATH"); |
|
die "*E: Errors occurred! Please grep for Errors in $LOG_FILE_PATH\n" unless system("grep Error $LOG_FILE_PATH"); |
die "*E: There were Warnings! Please grep for Warnings in $LOG_FILE_PATH\n" unless system("grep Warning $LOG_FILE_PATH"); |
############################################################################################################################################### |
# Scan for errors and warnings. |
############################################################################################################################################### |
|
die "*E: Errors occurred! Please grep for Errors in $COMPRESSED_LOG_FILE_PATH\n" unless system("zcat $COMPRESSED_LOG_FILE_PATH | grep Error"); |
die "*E: There were Warnings! Please grep for Warnings in $COMPRESSED_LOG_FILE_PATH\n" unless system("zcat $COMPRESSED_LOG_FILE_PATH | grep Warning"); |
|
############################################################################################################################################### |
# Functions |
############################################################################################################################################### |
|
sub system1 { |
my $x = $_[0]; |
print "#SystemCommand: $x\n"; |
system("$x"); |
} |
|
exit 0; |
|
|
/zap/trunk/src/scripts/uart_input.bash
0,0 → 1,18
#!/bin/bash |
|
############################################## |
# This file reads characters into a file. The |
# Verilog testbench then opens this file and |
# writes it to the UART RX character wise. |
# |
# Call this like: |
# bash uart_input.bash <filename> |
############################################## |
|
IFS="" |
|
while true |
do |
read -n1 -r -d "" char |
echo -n "$char" >> "$1" |
done |
/zap/trunk/src/testbench/cpu/uart16550/doc/src/UART_spec.doc
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
zap/trunk/src/testbench/cpu/uart16550/doc/src/UART_spec.doc
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: zap/trunk/src/testbench/cpu/uart16550/doc/UART_spec.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: zap/trunk/src/testbench/cpu/uart16550/doc/UART_spec.pdf
===================================================================
--- zap/trunk/src/testbench/cpu/uart16550/doc/UART_spec.pdf (revision 42)
+++ zap/trunk/src/testbench/cpu/uart16550/doc/UART_spec.pdf (nonexistent)
zap/trunk/src/testbench/cpu/uart16550/doc/UART_spec.pdf
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: zap/trunk/src/testbench/cpu/uart16550/rtl/uart_tfifo.v
===================================================================
--- zap/trunk/src/testbench/cpu/uart16550/rtl/uart_tfifo.v (revision 42)
+++ zap/trunk/src/testbench/cpu/uart16550/rtl/uart_tfifo.v (nonexistent)
@@ -1,241 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_tfifo.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core transmitter FIFO ////
-//// ////
-//// To Do: ////
-//// Nothing. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: 2002/07/22 ////
-//// (See log for the revision history) ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source is distributed in the hope that it will be ////
-//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
-//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
-//// PURPOSE. See the GNU Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.1 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.16 2001/12/20 13:25:46 mohor
-// rx push changed to be only one cycle wide.
-//
-// Revision 1.15 2001/12/18 09:01:07 mohor
-// Bug that was entered in the last update fixed (rx state machine).
-//
-// Revision 1.14 2001/12/17 14:46:48 mohor
-// overrun signal was moved to separate block because many sequential lsr
-// reads were preventing data from being written to rx fifo.
-// underrun signal was not used and was removed from the project.
-//
-// Revision 1.13 2001/11/26 21:38:54 gorban
-// Lots of fixes:
-// Break condition wasn't handled correctly at all.
-// LSR bits could lose their values.
-// LSR value after reset was wrong.
-// Timing of THRE interrupt signal corrected.
-// LSR bit 0 timing corrected.
-//
-// Revision 1.12 2001/11/08 14:54:23 mohor
-// Comments in Slovene language deleted, few small fixes for better work of
-// old tools. IRQs need to be fix.
-//
-// Revision 1.11 2001/11/07 17:51:52 gorban
-// Heavily rewritten interrupt and LSR subsystems.
-// Many bugs hopefully squashed.
-//
-// Revision 1.10 2001/10/20 09:58:40 gorban
-// Small synopsis fixes
-//
-// Revision 1.9 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.8 2001/08/24 08:48:10 mohor
-// FIFO was not cleared after the data was read bug fixed.
-//
-// Revision 1.7 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.3 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.3 2001/05/27 17:37:48 gorban
-// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
-//
-// Revision 1.2 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:12+02 jacob
-// Initial revision
-//
-//
-
-
-`include "uart_defines.v"
-
-module uart_tfifo (clk,
- wb_rst_i, data_in, data_out,
-// Control signals
- push, // push strobe, active high
- pop, // pop strobe, active high
-// status signals
- overrun,
- count,
- fifo_reset,
- reset_status
- );
-
-
-// FIFO parameters
-parameter fifo_width = `UART_FIFO_WIDTH;
-parameter fifo_depth = `UART_FIFO_DEPTH;
-parameter fifo_pointer_w = `UART_FIFO_POINTER_W;
-parameter fifo_counter_w = `UART_FIFO_COUNTER_W;
-
-input clk;
-input wb_rst_i;
-input push;
-input pop;
-input [fifo_width-1:0] data_in;
-input fifo_reset;
-input reset_status;
-
-output [fifo_width-1:0] data_out;
-output overrun;
-output [fifo_counter_w-1:0] count;
-
-wire [fifo_width-1:0] data_out;
-
-// FIFO pointers
-reg [fifo_pointer_w-1:0] top;
-reg [fifo_pointer_w-1:0] bottom;
-
-reg [fifo_counter_w-1:0] count;
-reg overrun;
-wire [fifo_pointer_w-1:0] top_plus_1 = top + 1'b1;
-
-raminfr #(fifo_pointer_w,fifo_width,fifo_depth) tfifo
- (.clk(clk),
- .we(push),
- .a(top),
- .dpra(bottom),
- .di(data_in),
- .dpo(data_out)
- );
-
-
-always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
-begin
- if (wb_rst_i)
- begin
- top <= 0;
- bottom <= 1'b0;
- count <= 0;
- end
- else
- if (fifo_reset) begin
- top <= 0;
- bottom <= 1'b0;
- count <= 0;
- end
- else
- begin
- case ({push, pop})
- 2'b10 : if (count0)
- begin
- bottom <= bottom + 1'b1;
- count <= count - 1'b1;
- end
- 2'b11 : begin
- bottom <= bottom + 1'b1;
- top <= top_plus_1;
- end
- default: ;
- endcase
- end
-end // always
-
-always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
-begin
- if (wb_rst_i)
- overrun <= 1'b0;
- else
- if(fifo_reset | reset_status)
- overrun <= 1'b0;
- else
- if(push & (count==fifo_depth))
- overrun <= 1'b1;
-end // always
-
-endmodule
Index: zap/trunk/src/testbench/cpu/uart16550/rtl/uart_wb.v
===================================================================
--- zap/trunk/src/testbench/cpu/uart16550/rtl/uart_wb.v (revision 42)
+++ zap/trunk/src/testbench/cpu/uart16550/rtl/uart_wb.v (nonexistent)
@@ -1,314 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_wb.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core WISHBONE interface. ////
-//// ////
-//// Known problems (limits): ////
-//// Inserts one wait state on all transfers. ////
-//// Note affected signals and the way they are affected. ////
-//// ////
-//// To Do: ////
-//// Nothing. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: 2001/05/17 ////
-//// (See log for the revision history) ////
-//// ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source is distributed in the hope that it will be ////
-//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
-//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
-//// PURPOSE. See the GNU Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.16 2002/07/29 21:16:18 gorban
-// The uart_defines.v file is included again in sources.
-//
-// Revision 1.15 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.12 2001/12/19 08:03:34 mohor
-// Warnings cleared.
-//
-// Revision 1.11 2001/12/06 14:51:04 gorban
-// Bug in LSR[0] is fixed.
-// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
-//
-// Revision 1.10 2001/12/03 21:44:29 gorban
-// Updated specification documentation.
-// Added full 32-bit data bus interface, now as default.
-// Address is 5-bit wide in 32-bit data bus mode.
-// Added wb_sel_i input to the core. It's used in the 32-bit mode.
-// Added debug interface with two 32-bit read-only registers in 32-bit mode.
-// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
-// My small test bench is modified to work with 32-bit mode.
-//
-// Revision 1.9 2001/10/20 09:58:40 gorban
-// Small synopsis fixes
-//
-// Revision 1.8 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.7 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.4 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.3 2001/05/21 19:12:01 gorban
-// Corrected some Linter messages.
-//
-// Revision 1.2 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:13+02 jacob
-// Initial revision
-//
-//
-
-// UART core WISHBONE interface
-//
-// Author: Jacob Gorban (jacob.gorban@flextronicssemi.com)
-// Company: Flextronics Semiconductor
-//
-
-`include "uart_defines.v"
-
-module uart_wb (clk, wb_rst_i,
- wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_adr_i,
- wb_adr_int, wb_dat_i, wb_dat_o, wb_dat8_i, wb_dat8_o, wb_dat32_o, wb_sel_i,
- we_o, re_o // Write and read enable output for the core
-);
-
-input clk;
-
-// WISHBONE interface
-input wb_rst_i;
-input wb_we_i;
-input wb_stb_i;
-input wb_cyc_i;
-input [3:0] wb_sel_i;
-input [`UART_ADDR_WIDTH-1:0] wb_adr_i; //WISHBONE address line
-
-`ifdef DATA_BUS_WIDTH_8
-input [7:0] wb_dat_i; //input WISHBONE bus
-output [7:0] wb_dat_o;
-reg [7:0] wb_dat_o;
-wire [7:0] wb_dat_i;
-reg [7:0] wb_dat_is;
-`else // for 32 data bus mode
-input [31:0] wb_dat_i; //input WISHBONE bus
-output [31:0] wb_dat_o;
-reg [31:0] wb_dat_o;
-wire [31:0] wb_dat_i;
-reg [31:0] wb_dat_is;
-`endif // !`ifdef DATA_BUS_WIDTH_8
-
-output [`UART_ADDR_WIDTH-1:0] wb_adr_int; // internal signal for address bus
-input [7:0] wb_dat8_o; // internal 8 bit output to be put into wb_dat_o
-output [7:0] wb_dat8_i;
-input [31:0] wb_dat32_o; // 32 bit data output (for debug interface)
-output wb_ack_o;
-output we_o;
-output re_o;
-
-wire we_o;
-reg wb_ack_o;
-reg [7:0] wb_dat8_i;
-wire [7:0] wb_dat8_o;
-wire [`UART_ADDR_WIDTH-1:0] wb_adr_int; // internal signal for address bus
-reg [`UART_ADDR_WIDTH-1:0] wb_adr_is;
-reg wb_we_is;
-reg wb_cyc_is;
-reg wb_stb_is;
-reg [3:0] wb_sel_is;
-wire [3:0] wb_sel_i;
-reg wre ;// timing control signal for write or read enable
-
-// wb_ack_o FSM
-reg [1:0] wbstate;
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) begin
- wb_ack_o <= 1'b0;
- wbstate <= 0;
- wre <= 1'b1;
- end else
- case (wbstate)
- 0: begin
- if (wb_stb_is & wb_cyc_is) begin
- wre <= 0;
- wbstate <= 1;
- wb_ack_o <= 1;
- end else begin
- wre <= 1;
- wb_ack_o <= 0;
- end
- end
- 1: begin
- wb_ack_o <= 0;
- wbstate <= 2;
- wre <= 0;
- end
- 2,3: begin
- wb_ack_o <= 0;
- wbstate <= 0;
- wre <= 0;
- end
- endcase
-
-assign we_o = wb_we_is & wb_stb_is & wb_cyc_is & wre ; //WE for registers
-assign re_o = ~wb_we_is & wb_stb_is & wb_cyc_is & wre ; //RE for registers
-
-// Sample input signals
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) begin
- wb_adr_is <= 0;
- wb_we_is <= 0;
- wb_cyc_is <= 0;
- wb_stb_is <= 0;
- wb_dat_is <= 0;
- wb_sel_is <= 0;
- end else begin
- wb_adr_is <= wb_adr_i;
- wb_we_is <= wb_we_i;
- wb_cyc_is <= wb_cyc_i;
- wb_stb_is <= wb_stb_i;
- wb_dat_is <= wb_dat_i;
- wb_sel_is <= wb_sel_i;
- end
-
-`ifdef DATA_BUS_WIDTH_8 // 8-bit data bus
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i)
- wb_dat_o <= 0;
- else
- wb_dat_o <= wb_dat8_o;
-
-always @(wb_dat_is)
- wb_dat8_i = wb_dat_is;
-
-assign wb_adr_int = wb_adr_is;
-
-`else // 32-bit bus
-// put output to the correct byte in 32 bits using select line
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i)
- wb_dat_o <= 0;
- else if (re_o)
- case (wb_sel_is)
- 4'b0001: wb_dat_o <= {24'b0, wb_dat8_o};
- 4'b0010: wb_dat_o <= {16'b0, wb_dat8_o, 8'b0};
- 4'b0100: wb_dat_o <= {8'b0, wb_dat8_o, 16'b0};
- 4'b1000: wb_dat_o <= {wb_dat8_o, 24'b0};
- 4'b1111: wb_dat_o <= wb_dat32_o; // debug interface output
- default: wb_dat_o <= 0;
- endcase // case(wb_sel_i)
-
-reg [1:0] wb_adr_int_lsb;
-
-always @(wb_sel_is or wb_dat_is)
-begin
- case (wb_sel_is)
- 4'b0001 : wb_dat8_i = wb_dat_is[7:0];
- 4'b0010 : wb_dat8_i = wb_dat_is[15:8];
- 4'b0100 : wb_dat8_i = wb_dat_is[23:16];
- 4'b1000 : wb_dat8_i = wb_dat_is[31:24];
- default : wb_dat8_i = wb_dat_is[7:0];
- endcase // case(wb_sel_i)
-
- `ifdef LITLE_ENDIAN
- case (wb_sel_is)
- 4'b0001 : wb_adr_int_lsb = 2'h0;
- 4'b0010 : wb_adr_int_lsb = 2'h1;
- 4'b0100 : wb_adr_int_lsb = 2'h2;
- 4'b1000 : wb_adr_int_lsb = 2'h3;
- default : wb_adr_int_lsb = 2'h0;
- endcase // case(wb_sel_i)
- `else
- case (wb_sel_is)
- 4'b0001 : wb_adr_int_lsb = 2'h3;
- 4'b0010 : wb_adr_int_lsb = 2'h2;
- 4'b0100 : wb_adr_int_lsb = 2'h1;
- 4'b1000 : wb_adr_int_lsb = 2'h0;
- default : wb_adr_int_lsb = 2'h0;
- endcase // case(wb_sel_i)
- `endif
-end
-
-assign wb_adr_int = {wb_adr_is[`UART_ADDR_WIDTH-1:2], wb_adr_int_lsb};
-
-`endif // !`ifdef DATA_BUS_WIDTH_8
-
-endmodule
-
-
-
-
-
-
-
-
-
-
Index: zap/trunk/src/testbench/cpu/uart16550/rtl/uart_transmitter.v
===================================================================
--- zap/trunk/src/testbench/cpu/uart16550/rtl/uart_transmitter.v (revision 42)
+++ zap/trunk/src/testbench/cpu/uart16550/rtl/uart_transmitter.v (nonexistent)
@@ -1,349 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_transmitter.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core transmitter logic ////
-//// ////
-//// Known problems (limits): ////
-//// None known ////
-//// ////
-//// To Do: ////
-//// Thourough testing. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: 2001/05/17 ////
-//// (See log for the revision history) ////
-//// ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source is distributed in the hope that it will be ////
-//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
-//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
-//// PURPOSE. See the GNU Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.18 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.16 2002/01/08 11:29:40 mohor
-// tf_pop was too wide. Now it is only 1 clk cycle width.
-//
-// Revision 1.15 2001/12/17 14:46:48 mohor
-// overrun signal was moved to separate block because many sequential lsr
-// reads were preventing data from being written to rx fifo.
-// underrun signal was not used and was removed from the project.
-//
-// Revision 1.14 2001/12/03 21:44:29 gorban
-// Updated specification documentation.
-// Added full 32-bit data bus interface, now as default.
-// Address is 5-bit wide in 32-bit data bus mode.
-// Added wb_sel_i input to the core. It's used in the 32-bit mode.
-// Added debug interface with two 32-bit read-only registers in 32-bit mode.
-// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
-// My small test bench is modified to work with 32-bit mode.
-//
-// Revision 1.13 2001/11/08 14:54:23 mohor
-// Comments in Slovene language deleted, few small fixes for better work of
-// old tools. IRQs need to be fix.
-//
-// Revision 1.12 2001/11/07 17:51:52 gorban
-// Heavily rewritten interrupt and LSR subsystems.
-// Many bugs hopefully squashed.
-//
-// Revision 1.11 2001/10/29 17:00:46 gorban
-// fixed parity sending and tx_fifo resets over- and underrun
-//
-// Revision 1.10 2001/10/20 09:58:40 gorban
-// Small synopsis fixes
-//
-// Revision 1.9 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.8 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.6 2001/06/23 11:21:48 gorban
-// DL made 16-bit long. Fixed transmission/reception bugs.
-//
-// Revision 1.5 2001/06/02 14:28:14 gorban
-// Fixed receiver and transmitter. Major bug fixed.
-//
-// Revision 1.4 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.3 2001/05/27 17:37:49 gorban
-// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
-//
-// Revision 1.2 2001/05/21 19:12:02 gorban
-// Corrected some Linter messages.
-//
-// Revision 1.1 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:12+02 jacob
-// Initial revision
-//
-//
-
-
-`include "uart_defines.v"
-
-module uart_transmitter (clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, stx_pad_o, tstate, tf_count, tx_reset, lsr_mask);
-
-input clk;
-input wb_rst_i;
-input [7:0] lcr;
-input tf_push;
-input [7:0] wb_dat_i;
-input enable;
-input tx_reset;
-input lsr_mask; //reset of fifo
-output stx_pad_o;
-output [2:0] tstate;
-output [`UART_FIFO_COUNTER_W-1:0] tf_count;
-
-reg [2:0] tstate;
-reg [4:0] counter;
-reg [2:0] bit_counter; // counts the bits to be sent
-reg [6:0] shift_out; // output shift register
-reg stx_o_tmp;
-reg parity_xor; // parity of the word
-reg tf_pop;
-reg bit_out;
-
-// TX FIFO instance
-//
-// Transmitter FIFO signals
-wire [`UART_FIFO_WIDTH-1:0] tf_data_in;
-wire [`UART_FIFO_WIDTH-1:0] tf_data_out;
-wire tf_push;
-wire tf_overrun;
-wire [`UART_FIFO_COUNTER_W-1:0] tf_count;
-
-assign tf_data_in = wb_dat_i;
-
-uart_tfifo fifo_tx( // error bit signal is not used in transmitter FIFO
- .clk( clk ),
- .wb_rst_i( wb_rst_i ),
- .data_in( tf_data_in ),
- .data_out( tf_data_out ),
- .push( tf_push ),
- .pop( tf_pop ),
- .overrun( tf_overrun ),
- .count( tf_count ),
- .fifo_reset( tx_reset ),
- .reset_status(lsr_mask)
-);
-
-// TRANSMITTER FINAL STATE MACHINE
-
-parameter s_idle = 3'd0;
-parameter s_send_start = 3'd1;
-parameter s_send_byte = 3'd2;
-parameter s_send_parity = 3'd3;
-parameter s_send_stop = 3'd4;
-parameter s_pop_byte = 3'd5;
-
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- begin
- tstate <= s_idle;
- stx_o_tmp <= 1'b1;
- counter <= 5'b0;
- shift_out <= 7'b0;
- bit_out <= 1'b0;
- parity_xor <= 1'b0;
- tf_pop <= 1'b0;
- bit_counter <= 3'b0;
- end
- else
- if (enable)
- begin
- case (tstate)
- s_idle : if (~|tf_count) // if tf_count==0
- begin
- tstate <= s_idle;
- stx_o_tmp <= 1'b1;
- end
- else
- begin
- tf_pop <= 1'b0;
- stx_o_tmp <= 1'b1;
- tstate <= s_pop_byte;
- end
- s_pop_byte : begin
- tf_pop <= 1'b1;
- case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word
- 2'b00 : begin
- bit_counter <= 3'b100;
- parity_xor <= ^tf_data_out[4:0];
- end
- 2'b01 : begin
- bit_counter <= 3'b101;
- parity_xor <= ^tf_data_out[5:0];
- end
- 2'b10 : begin
- bit_counter <= 3'b110;
- parity_xor <= ^tf_data_out[6:0];
- end
- 2'b11 : begin
- bit_counter <= 3'b111;
- parity_xor <= ^tf_data_out[7:0];
- end
- endcase
- {shift_out[6:0], bit_out} <= tf_data_out;
- tstate <= s_send_start;
- end
- s_send_start : begin
- tf_pop <= 1'b0;
- if (~|counter)
- counter <= 5'b01111;
- else
- if (counter == 5'b00001)
- begin
- counter <= 0;
- tstate <= s_send_byte;
- end
- else
- counter <= counter - 1'b1;
- stx_o_tmp <= 1'b0;
- end
- s_send_byte : begin
- if (~|counter)
- counter <= 5'b01111;
- else
- if (counter == 5'b00001)
- begin
- if (bit_counter > 3'b0)
- begin
- bit_counter <= bit_counter - 1'b1;
- {shift_out[5:0],bit_out } <= {shift_out[6:1], shift_out[0]};
- tstate <= s_send_byte;
- end
- else // end of byte
- if (~lcr[`UART_LC_PE])
- begin
- tstate <= s_send_stop;
- end
- else
- begin
- case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]})
- 2'b00: bit_out <= ~parity_xor;
- 2'b01: bit_out <= 1'b1;
- 2'b10: bit_out <= parity_xor;
- 2'b11: bit_out <= 1'b0;
- endcase
- tstate <= s_send_parity;
- end
- counter <= 0;
- end
- else
- counter <= counter - 1'b1;
- stx_o_tmp <= bit_out; // set output pin
- end
- s_send_parity : begin
- if (~|counter)
- counter <= 5'b01111;
- else
- if (counter == 5'b00001)
- begin
- counter <= 4'b0;
- tstate <= s_send_stop;
- end
- else
- counter <= counter - 1'b1;
- stx_o_tmp <= bit_out;
- end
- s_send_stop : begin
- if (~|counter)
- begin
- casex ({lcr[`UART_LC_SB],lcr[`UART_LC_BITS]})
- 3'b0xx: counter <= 5'b01101; // 1 stop bit ok igor
- 3'b100: counter <= 5'b10101; // 1.5 stop bit
- default: counter <= 5'b11101; // 2 stop bits
- endcase
- end
- else
- if (counter == 5'b00001)
- begin
- counter <= 0;
- tstate <= s_idle;
- end
- else
- counter <= counter - 1'b1;
- stx_o_tmp <= 1'b1;
- end
-
- default : // should never get here
- tstate <= s_idle;
- endcase
- end // end if enable
- else
- tf_pop <= 1'b0; // tf_pop must be 1 cycle width
-end // transmitter logic
-
-assign stx_pad_o = lcr[`UART_LC_BC] ? 1'b0 : stx_o_tmp; // Break condition
-
-endmodule
Index: zap/trunk/src/testbench/cpu/uart16550/rtl/uart_defines.v
===================================================================
--- zap/trunk/src/testbench/cpu/uart16550/rtl/uart_defines.v (revision 42)
+++ zap/trunk/src/testbench/cpu/uart16550/rtl/uart_defines.v (nonexistent)
@@ -1,249 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_defines.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// Defines of the Core ////
-//// ////
-//// Known problems (limits): ////
-//// None ////
-//// ////
-//// To Do: ////
-//// Nothing. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: 2001/05/17 ////
-//// (See log for the revision history) ////
-///// Modified for use in the ZAP project by Revanth Kamaraj ////
-/// ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source is distributed in the hope that it will be ////
-//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
-//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
-//// PURPOSE. See the GNU Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.13 2003/06/11 16:37:47 gorban
-// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
-//
-// Revision 1.12 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.10 2001/12/11 08:55:40 mohor
-// Scratch register define added.
-//
-// Revision 1.9 2001/12/03 21:44:29 gorban
-// Updated specification documentation.
-// Added full 32-bit data bus interface, now as default.
-// Address is 5-bit wide in 32-bit data bus mode.
-// Added wb_sel_i input to the core. It's used in the 32-bit mode.
-// Added debug interface with two 32-bit read-only registers in 32-bit mode.
-// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
-// My small test bench is modified to work with 32-bit mode.
-//
-// Revision 1.8 2001/11/26 21:38:54 gorban
-// Lots of fixes:
-// Break condition wasn't handled correctly at all.
-// LSR bits could lose their values.
-// LSR value after reset was wrong.
-// Timing of THRE interrupt signal corrected.
-// LSR bit 0 timing corrected.
-//
-// Revision 1.7 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.6 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.5 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.4 2001/05/21 19:12:02 gorban
-// Corrected some Linter messages.
-//
-// Revision 1.3 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:11+02 jacob
-// Initial revision
-//
-//
-
-// remove comments to restore to use the new version with 8 data bit interface
-// in 32bit-bus mode, the wb_sel_i signal is used to put data in correct place
-// also, in 8-bit version there'll be no debugging features included
-// CAUTION: doesn't work with current version of OR1200
-//`define DATA_BUS_WIDTH_8
-
-`ifdef DATA_BUS_WIDTH_8
- `define UART_ADDR_WIDTH 3
- `define UART_DATA_WIDTH 8
-`else
- `define UART_ADDR_WIDTH 5
- `define UART_DATA_WIDTH 32
-`endif
-
-// Uncomment this if you want your UART to have
-// 16xBaudrate output port.
-// If defined, the enable signal will be used to drive baudrate_o signal
-// It's frequency is 16xbaudrate
-
-// `define UART_HAS_BAUDRATE_OUTPUT
-
-// Register addresses
-`define UART_REG_RB `UART_ADDR_WIDTH'd0 // receiver buffer
-`define UART_REG_TR `UART_ADDR_WIDTH'd0 // transmitter
-`define UART_REG_IE `UART_ADDR_WIDTH'd1 // Interrupt enable
-`define UART_REG_II `UART_ADDR_WIDTH'd2 // Interrupt identification
-`define UART_REG_FC `UART_ADDR_WIDTH'd2 // FIFO control
-`define UART_REG_LC `UART_ADDR_WIDTH'd3 // Line Control
-`define UART_REG_MC `UART_ADDR_WIDTH'd4 // Modem control
-`define UART_REG_LS `UART_ADDR_WIDTH'd5 // Line status
-`define UART_REG_MS `UART_ADDR_WIDTH'd6 // Modem status
-`define UART_REG_SR `UART_ADDR_WIDTH'd7 // Scratch register
-`define UART_REG_DL1 `UART_ADDR_WIDTH'd0 // Divisor latch bytes (1-2)
-`define UART_REG_DL2 `UART_ADDR_WIDTH'd1
-
-// Interrupt Enable register bits
-`define UART_IE_RDA 0 // Received Data available interrupt
-`define UART_IE_THRE 1 // Transmitter Holding Register empty interrupt
-`define UART_IE_RLS 2 // Receiver Line Status Interrupt
-`define UART_IE_MS 3 // Modem Status Interrupt
-
-// Interrupt Identification register bits
-`define UART_II_IP 0 // Interrupt pending when 0
-`define UART_II_II 3:1 // Interrupt identification
-
-// Interrupt identification values for bits 3:1
-`define UART_II_RLS 3'b011 // Receiver Line Status
-`define UART_II_RDA 3'b010 // Receiver Data available
-`define UART_II_TI 3'b110 // Timeout Indication
-`define UART_II_THRE 3'b001 // Transmitter Holding Register empty
-`define UART_II_MS 3'b000 // Modem Status
-
-// FIFO Control Register bits
-`define UART_FC_TL 1:0 // Trigger level
-
-// FIFO trigger level values
-`define UART_FC_1 2'b00
-`define UART_FC_4 2'b01
-`define UART_FC_8 2'b10
-`define UART_FC_14 2'b11
-
-// Line Control register bits
-`define UART_LC_BITS 1:0 // bits in character
-`define UART_LC_SB 2 // stop bits
-`define UART_LC_PE 3 // parity enable
-`define UART_LC_EP 4 // even parity
-`define UART_LC_SP 5 // stick parity
-`define UART_LC_BC 6 // Break control
-`define UART_LC_DL 7 // Divisor Latch access bit
-
-// Modem Control register bits
-`define UART_MC_DTR 0
-`define UART_MC_RTS 1
-`define UART_MC_OUT1 2
-`define UART_MC_OUT2 3
-`define UART_MC_LB 4 // Loopback mode
-
-// Line Status Register bits
-`define UART_LS_DR 0 // Data ready
-`define UART_LS_OE 1 // Overrun Error
-`define UART_LS_PE 2 // Parity Error
-`define UART_LS_FE 3 // Framing Error
-`define UART_LS_BI 4 // Break interrupt
-`define UART_LS_TFE 5 // Transmit FIFO is empty
-`define UART_LS_TE 6 // Transmitter Empty indicator
-`define UART_LS_EI 7 // Error indicator
-
-// Modem Status Register bits
-`define UART_MS_DCTS 0 // Delta signals
-`define UART_MS_DDSR 1
-`define UART_MS_TERI 2
-`define UART_MS_DDCD 3
-`define UART_MS_CCTS 4 // Complement signals
-`define UART_MS_CDSR 5
-`define UART_MS_CRI 6
-`define UART_MS_CDCD 7
-
-// FIFO parameter defines
-
-`define UART_FIFO_WIDTH 8
-`define UART_FIFO_DEPTH 16
-`define UART_FIFO_POINTER_W 4
-`define UART_FIFO_COUNTER_W 5
-// receiver fifo has width 11 because it has break, parity and framing error bits
-`define UART_FIFO_REC_WIDTH 11
-
-
-`define VERBOSE_WB 0 // All activity on the WISHBONE is recorded
-`define VERBOSE_LINE_STATUS 0 // Details about the lsr (line status register)
-`define FAST_TEST 1 // 64/1024 packets are sent
-
-// Added by Revanth to support LITTLE_ENDIAN mode of operation.
-`define LITLE_ENDIAN
-
-
-
-
-
Index: zap/trunk/src/testbench/cpu/uart16550/rtl/uart_sync_flops.v
===================================================================
--- zap/trunk/src/testbench/cpu/uart16550/rtl/uart_sync_flops.v (revision 42)
+++ zap/trunk/src/testbench/cpu/uart16550/rtl/uart_sync_flops.v (nonexistent)
@@ -1,122 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_sync_flops.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core receiver logic ////
-//// ////
-//// Known problems (limits): ////
-//// None known ////
-//// ////
-//// To Do: ////
-//// Thourough testing. ////
-//// ////
-//// Author(s): ////
-//// - Andrej Erzen (andreje@flextronics.si) ////
-//// - Tadej Markovic (tadejm@flextronics.si) ////
-//// ////
-//// Created: 2004/05/20 ////
-//// Last Updated: 2004/05/20 ////
-//// (See log for the revision history) ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source is distributed in the hope that it will be ////
-//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
-//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
-//// PURPOSE. See the GNU Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-//
-
-
-
-
-module uart_sync_flops
-(
- // internal signals
- rst_i,
- clk_i,
- stage1_rst_i,
- stage1_clk_en_i,
- async_dat_i,
- sync_dat_o
-);
-
-parameter Tp = 1;
-parameter width = 1;
-parameter init_value = 1'b0;
-
-input rst_i; // reset input
-input clk_i; // clock input
-input stage1_rst_i; // synchronous reset for stage 1 FF
-input stage1_clk_en_i; // synchronous clock enable for stage 1 FF
-input [width-1:0] async_dat_i; // asynchronous data input
-output [width-1:0] sync_dat_o; // synchronous data output
-
-
-//
-// Interal signal declarations
-//
-
-reg [width-1:0] sync_dat_o;
-reg [width-1:0] flop_0;
-
-
-// first stage
-always @ (posedge clk_i or posedge rst_i)
-begin
- if (rst_i)
- flop_0 <= #Tp {width{init_value}};
- else
- flop_0 <= #Tp async_dat_i;
-end
-
-// second stage
-always @ (posedge clk_i or posedge rst_i)
-begin
- if (rst_i)
- sync_dat_o <= #Tp {width{init_value}};
- else if (stage1_rst_i)
- sync_dat_o <= #Tp {width{init_value}};
- else if (stage1_clk_en_i)
- sync_dat_o <= #Tp flop_0;
-end
-
-endmodule
Index: zap/trunk/src/testbench/cpu/uart16550/rtl/uart_regs.v
===================================================================
--- zap/trunk/src/testbench/cpu/uart16550/rtl/uart_regs.v (revision 42)
+++ zap/trunk/src/testbench/cpu/uart16550/rtl/uart_regs.v (nonexistent)
@@ -1,892 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_regs.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// Registers of the uart 16550 core ////
-//// ////
-//// Known problems (limits): ////
-//// Inserts 1 wait state in all WISHBONE transfers ////
-//// ////
-//// To Do: ////
-//// Nothing or verification. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: (See log for the revision history ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source is distributed in the hope that it will be ////
-//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
-//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
-//// PURPOSE. See the GNU Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.41 2004/05/21 11:44:41 tadejm
-// Added synchronizer flops for RX input.
-//
-// Revision 1.40 2003/06/11 16:37:47 gorban
-// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
-//
-// Revision 1.39 2002/07/29 21:16:18 gorban
-// The uart_defines.v file is included again in sources.
-//
-// Revision 1.38 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.37 2001/12/27 13:24:09 mohor
-// lsr[7] was not showing overrun errors.
-//
-// Revision 1.36 2001/12/20 13:25:46 mohor
-// rx push changed to be only one cycle wide.
-//
-// Revision 1.35 2001/12/19 08:03:34 mohor
-// Warnings cleared.
-//
-// Revision 1.34 2001/12/19 07:33:54 mohor
-// Synplicity was having troubles with the comment.
-//
-// Revision 1.33 2001/12/17 10:14:43 mohor
-// Things related to msr register changed. After THRE IRQ occurs, and one
-// character is written to the transmit fifo, the detection of the THRE bit in the
-// LSR is delayed for one character time.
-//
-// Revision 1.32 2001/12/14 13:19:24 mohor
-// MSR register fixed.
-//
-// Revision 1.31 2001/12/14 10:06:58 mohor
-// After reset modem status register MSR should be reset.
-//
-// Revision 1.30 2001/12/13 10:09:13 mohor
-// thre irq should be cleared only when being source of interrupt.
-//
-// Revision 1.29 2001/12/12 09:05:46 mohor
-// LSR status bit 0 was not cleared correctly in case of reseting the FCR (rx fifo).
-//
-// Revision 1.28 2001/12/10 19:52:41 gorban
-// Scratch register added
-//
-// Revision 1.27 2001/12/06 14:51:04 gorban
-// Bug in LSR[0] is fixed.
-// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
-//
-// Revision 1.26 2001/12/03 21:44:29 gorban
-// Updated specification documentation.
-// Added full 32-bit data bus interface, now as default.
-// Address is 5-bit wide in 32-bit data bus mode.
-// Added wb_sel_i input to the core. It's used in the 32-bit mode.
-// Added debug interface with two 32-bit read-only registers in 32-bit mode.
-// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
-// My small test bench is modified to work with 32-bit mode.
-//
-// Revision 1.25 2001/11/28 19:36:39 gorban
-// Fixed: timeout and break didn't pay attention to current data format when counting time
-//
-// Revision 1.24 2001/11/26 21:38:54 gorban
-// Lots of fixes:
-// Break condition wasn't handled correctly at all.
-// LSR bits could lose their values.
-// LSR value after reset was wrong.
-// Timing of THRE interrupt signal corrected.
-// LSR bit 0 timing corrected.
-//
-// Revision 1.23 2001/11/12 21:57:29 gorban
-// fixed more typo bugs
-//
-// Revision 1.22 2001/11/12 15:02:28 mohor
-// lsr1r error fixed.
-//
-// Revision 1.21 2001/11/12 14:57:27 mohor
-// ti_int_pnd error fixed.
-//
-// Revision 1.20 2001/11/12 14:50:27 mohor
-// ti_int_d error fixed.
-//
-// Revision 1.19 2001/11/10 12:43:21 gorban
-// Logic Synthesis bugs fixed. Some other minor changes
-//
-// Revision 1.18 2001/11/08 14:54:23 mohor
-// Comments in Slovene language deleted, few small fixes for better work of
-// old tools. IRQs need to be fix.
-//
-// Revision 1.17 2001/11/07 17:51:52 gorban
-// Heavily rewritten interrupt and LSR subsystems.
-// Many bugs hopefully squashed.
-//
-// Revision 1.16 2001/11/02 09:55:16 mohor
-// no message
-//
-// Revision 1.15 2001/10/31 15:19:22 gorban
-// Fixes to break and timeout conditions
-//
-// Revision 1.14 2001/10/29 17:00:46 gorban
-// fixed parity sending and tx_fifo resets over- and underrun
-//
-// Revision 1.13 2001/10/20 09:58:40 gorban
-// Small synopsis fixes
-//
-// Revision 1.12 2001/10/19 16:21:40 gorban
-// Changes data_out to be synchronous again as it should have been.
-//
-// Revision 1.11 2001/10/18 20:35:45 gorban
-// small fix
-//
-// Revision 1.10 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.9 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.10 2001/06/23 11:21:48 gorban
-// DL made 16-bit long. Fixed transmission/reception bugs.
-//
-// Revision 1.9 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.8 2001/05/29 20:05:04 gorban
-// Fixed some bugs and synthesis problems.
-//
-// Revision 1.7 2001/05/27 17:37:49 gorban
-// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
-//
-// Revision 1.6 2001/05/21 19:12:02 gorban
-// Corrected some Linter messages.
-//
-// Revision 1.5 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:11+02 jacob
-// Initial revision
-//
-//
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-
-
-`include "uart_defines.v"
-
-`define UART_DL1 7:0
-`define UART_DL2 15:8
-
-module uart_regs (clk,
- wb_rst_i, wb_addr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_re_i,
-
-// additional signals
- modem_inputs,
- stx_pad_o, srx_pad_i,
-
-`ifdef DATA_BUS_WIDTH_8
-`else
-// debug interface signals enabled
-ier, iir, fcr, mcr, lcr, msr, lsr, rf_count, tf_count, tstate, rstate,
-`endif
- rts_pad_o, dtr_pad_o, int_o
-`ifdef UART_HAS_BAUDRATE_OUTPUT
- , baud_o
-`endif
-
- );
-
-input clk;
-input wb_rst_i;
-input [`UART_ADDR_WIDTH-1:0] wb_addr_i;
-input [7:0] wb_dat_i;
-output [7:0] wb_dat_o;
-input wb_we_i;
-input wb_re_i;
-
-output stx_pad_o;
-input srx_pad_i;
-
-input [3:0] modem_inputs;
-output rts_pad_o;
-output dtr_pad_o;
-output int_o;
-`ifdef UART_HAS_BAUDRATE_OUTPUT
-output baud_o;
-`endif
-
-`ifdef DATA_BUS_WIDTH_8
-`else
-// if 32-bit databus and debug interface are enabled
-output [3:0] ier;
-output [3:0] iir;
-output [1:0] fcr; /// bits 7 and 6 of fcr. Other bits are ignored
-output [4:0] mcr;
-output [7:0] lcr;
-output [7:0] msr;
-output [7:0] lsr;
-output [`UART_FIFO_COUNTER_W-1:0] rf_count;
-output [`UART_FIFO_COUNTER_W-1:0] tf_count;
-output [2:0] tstate;
-output [3:0] rstate;
-
-`endif
-
-wire [3:0] modem_inputs;
-reg enable;
-`ifdef UART_HAS_BAUDRATE_OUTPUT
-assign baud_o = enable; // baud_o is actually the enable signal
-`endif
-
-
-wire stx_pad_o; // received from transmitter module
-wire srx_pad_i;
-wire srx_pad;
-
-reg [7:0] wb_dat_o;
-
-wire [`UART_ADDR_WIDTH-1:0] wb_addr_i;
-wire [7:0] wb_dat_i;
-
-
-reg [3:0] ier;
-reg [3:0] iir;
-reg [1:0] fcr; /// bits 7 and 6 of fcr. Other bits are ignored
-reg [4:0] mcr;
-reg [7:0] lcr;
-reg [7:0] msr;
-reg [15:0] dl; // 32-bit divisor latch
-reg [7:0] scratch; // UART scratch register
-reg start_dlc; // activate dlc on writing to UART_DL1
-reg lsr_mask_d; // delay for lsr_mask condition
-reg msi_reset; // reset MSR 4 lower bits indicator
-//reg threi_clear; // THRE interrupt clear flag
-reg [15:0] dlc; // 32-bit divisor latch counter
-reg int_o;
-
-reg [3:0] trigger_level; // trigger level of the receiver FIFO
-reg rx_reset;
-reg tx_reset;
-
-wire dlab; // divisor latch access bit
-wire cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i; // modem status bits
-wire loopback; // loopback bit (MCR bit 4)
-wire cts, dsr, ri, dcd; // effective signals
-wire cts_c, dsr_c, ri_c, dcd_c; // Complement effective signals (considering loopback)
-wire rts_pad_o, dtr_pad_o; // modem control outputs
-
-// LSR bits wires and regs
-wire [7:0] lsr;
-wire lsr0, lsr1, lsr2, lsr3, lsr4, lsr5, lsr6, lsr7;
-reg lsr0r, lsr1r, lsr2r, lsr3r, lsr4r, lsr5r, lsr6r, lsr7r;
-wire lsr_mask; // lsr_mask
-
-//
-// ASSINGS
-//
-
-assign lsr[7:0] = { lsr7r, lsr6r, lsr5r, lsr4r, lsr3r, lsr2r, lsr1r, lsr0r };
-
-assign {cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i} = modem_inputs;
-assign {cts, dsr, ri, dcd} = ~{cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
-
-assign {cts_c, dsr_c, ri_c, dcd_c} = loopback ? {mcr[`UART_MC_RTS],mcr[`UART_MC_DTR],mcr[`UART_MC_OUT1],mcr[`UART_MC_OUT2]}
- : {cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
-
-assign dlab = lcr[`UART_LC_DL];
-assign loopback = mcr[4];
-
-// assign modem outputs
-assign rts_pad_o = mcr[`UART_MC_RTS];
-assign dtr_pad_o = mcr[`UART_MC_DTR];
-
-// Interrupt signals
-wire rls_int; // receiver line status interrupt
-wire rda_int; // receiver data available interrupt
-wire ti_int; // timeout indicator interrupt
-wire thre_int; // transmitter holding register empty interrupt
-wire ms_int; // modem status interrupt
-
-// FIFO signals
-reg tf_push;
-reg rf_pop;
-wire [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
-wire rf_error_bit; // an error (parity or framing) is inside the fifo
-wire [`UART_FIFO_COUNTER_W-1:0] rf_count;
-wire [`UART_FIFO_COUNTER_W-1:0] tf_count;
-wire [2:0] tstate;
-wire [3:0] rstate;
-wire [9:0] counter_t;
-
-wire thre_set_en; // THRE status is delayed one character time when a character is written to fifo.
-reg [7:0] block_cnt; // While counter counts, THRE status is blocked (delayed one character cycle)
-reg [7:0] block_value; // One character length minus stop bit
-
-// Transmitter Instance
-wire serial_out;
-
-uart_transmitter transmitter(clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, serial_out, tstate, tf_count, tx_reset, lsr_mask);
-
- // Synchronizing and sampling serial RX input
- uart_sync_flops i_uart_sync_flops
- (
- .rst_i (wb_rst_i),
- .clk_i (clk),
- .stage1_rst_i (1'b0),
- .stage1_clk_en_i (1'b1),
- .async_dat_i (srx_pad_i),
- .sync_dat_o (srx_pad)
- );
- defparam i_uart_sync_flops.width = 1;
- defparam i_uart_sync_flops.init_value = 1'b1;
-
-// handle loopback
-wire serial_in = loopback ? serial_out : srx_pad;
-assign stx_pad_o = loopback ? 1'b1 : serial_out;
-
-// Receiver Instance
-uart_receiver receiver(clk, wb_rst_i, lcr, rf_pop, serial_in, enable,
- counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask, rstate, rf_push_pulse);
-
-
-// Asynchronous reading here because the outputs are sampled in uart_wb.v file
-always @(dl or dlab or ier or iir or scratch
- or lcr or lsr or msr or rf_data_out or wb_addr_i or wb_re_i) // asynchrounous reading
-begin
- case (wb_addr_i)
- `UART_REG_RB : wb_dat_o = dlab ? dl[`UART_DL1] : rf_data_out[10:3];
- `UART_REG_IE : wb_dat_o = dlab ? dl[`UART_DL2] : ier;
- `UART_REG_II : wb_dat_o = {4'b1100,iir};
- `UART_REG_LC : wb_dat_o = lcr;
- `UART_REG_LS : wb_dat_o = lsr;
- `UART_REG_MS : wb_dat_o = msr;
- `UART_REG_SR : wb_dat_o = scratch;
- default: wb_dat_o = 8'b0; // ??
- endcase // case(wb_addr_i)
-end // always @ (dl or dlab or ier or iir or scratch...
-
-
-// rf_pop signal handling
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- rf_pop <= 0;
- else
- if (rf_pop) // restore the signal to 0 after one clock cycle
- rf_pop <= 0;
- else
- if (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab)
- rf_pop <= 1; // advance read pointer
-end
-
-wire lsr_mask_condition;
-wire iir_read;
-wire msr_read;
-wire fifo_read;
-wire fifo_write;
-
-assign lsr_mask_condition = (wb_re_i && wb_addr_i == `UART_REG_LS && !dlab);
-assign iir_read = (wb_re_i && wb_addr_i == `UART_REG_II && !dlab);
-assign msr_read = (wb_re_i && wb_addr_i == `UART_REG_MS && !dlab);
-assign fifo_read = (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab);
-assign fifo_write = (wb_we_i && wb_addr_i == `UART_REG_TR && !dlab);
-
-// lsr_mask_d delayed signal handling
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- lsr_mask_d <= 0;
- else // reset bits in the Line Status Register
- lsr_mask_d <= lsr_mask_condition;
-end
-
-// lsr_mask is rise detected
-assign lsr_mask = lsr_mask_condition && ~lsr_mask_d;
-
-// msi_reset signal handling
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- msi_reset <= 1;
- else
- if (msi_reset)
- msi_reset <= 0;
- else
- if (msr_read)
- msi_reset <= 1; // reset bits in Modem Status Register
-end
-
-
-//
-// WRITES AND RESETS //
-//
-// Line Control Register
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i)
- lcr <= 8'b00000011; // 8n1 setting
- else
- if (wb_we_i && wb_addr_i==`UART_REG_LC)
- lcr <= wb_dat_i;
-
-// Interrupt Enable Register or UART_DL2
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i)
- begin
- ier <= 4'b0000; // no interrupts after reset
- dl[`UART_DL2] <= 8'b0;
- end
- else
- if (wb_we_i && wb_addr_i==`UART_REG_IE)
- if (dlab)
- begin
- dl[`UART_DL2] <= wb_dat_i;
- end
- else
- ier <= wb_dat_i[3:0]; // ier uses only 4 lsb
-
-
-// FIFO Control Register and rx_reset, tx_reset signals
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) begin
- fcr <= 2'b11;
- rx_reset <= 0;
- tx_reset <= 0;
- end else
- if (wb_we_i && wb_addr_i==`UART_REG_FC) begin
- fcr <= wb_dat_i[7:6];
- rx_reset <= wb_dat_i[1];
- tx_reset <= wb_dat_i[2];
- end else begin
- rx_reset <= 0;
- tx_reset <= 0;
- end
-
-// Modem Control Register
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i)
- mcr <= 5'b0;
- else
- if (wb_we_i && wb_addr_i==`UART_REG_MC)
- mcr <= wb_dat_i[4:0];
-
-// Scratch register
-// Line Control Register
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i)
- scratch <= 0; // 8n1 setting
- else
- if (wb_we_i && wb_addr_i==`UART_REG_SR)
- scratch <= wb_dat_i;
-
-// TX_FIFO or UART_DL1
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i)
- begin
- dl[`UART_DL1] <= 8'b0;
- tf_push <= 1'b0;
- start_dlc <= 1'b0;
- end
- else
- if (wb_we_i && wb_addr_i==`UART_REG_TR)
- if (dlab)
- begin
- dl[`UART_DL1] <= wb_dat_i;
- start_dlc <= 1'b1; // enable DL counter
- tf_push <= 1'b0;
- end
- else
- begin
- tf_push <= 1'b1;
- start_dlc <= 1'b0;
- end // else: !if(dlab)
- else
- begin
- start_dlc <= 1'b0;
- tf_push <= 1'b0;
- end // else: !if(dlab)
-
-// Receiver FIFO trigger level selection logic (asynchronous mux)
-always @(fcr)
- case (fcr[`UART_FC_TL])
- 2'b00 : trigger_level = 1;
- 2'b01 : trigger_level = 4;
- 2'b10 : trigger_level = 8;
- 2'b11 : trigger_level = 14;
- endcase // case(fcr[`UART_FC_TL])
-
-//
-// STATUS REGISTERS //
-//
-
-// Modem Status Register
-reg [3:0] delayed_modem_signals;
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- begin
- msr <= 0;
- delayed_modem_signals[3:0] <= 0;
- end
- else begin
- msr[`UART_MS_DDCD:`UART_MS_DCTS] <= msi_reset ? 4'b0 :
- msr[`UART_MS_DDCD:`UART_MS_DCTS] | ({dcd, ri, dsr, cts} ^ delayed_modem_signals[3:0]);
- msr[`UART_MS_CDCD:`UART_MS_CCTS] <= {dcd_c, ri_c, dsr_c, cts_c};
- delayed_modem_signals[3:0] <= {dcd, ri, dsr, cts};
- end
-end
-
-
-// Line Status Register
-
-// activation conditions
-assign lsr0 = (rf_count==0 && rf_push_pulse); // data in receiver fifo available set condition
-assign lsr1 = rf_overrun; // Receiver overrun error
-assign lsr2 = rf_data_out[1]; // parity error bit
-assign lsr3 = rf_data_out[0]; // framing error bit
-assign lsr4 = rf_data_out[2]; // break error in the character
-assign lsr5 = (tf_count==5'b0 && thre_set_en); // transmitter fifo is empty
-assign lsr6 = (tf_count==5'b0 && thre_set_en && (tstate == /*`S_IDLE */ 0)); // transmitter empty
-assign lsr7 = rf_error_bit | rf_overrun;
-
-// lsr bit0 (receiver data available)
-reg lsr0_d;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr0_d <= 0;
- else lsr0_d <= lsr0;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr0r <= 0;
- else lsr0r <= (rf_count==1 && rf_pop && !rf_push_pulse || rx_reset) ? 0 : // deassert condition
- lsr0r || (lsr0 && ~lsr0_d); // set on rise of lsr0 and keep asserted until deasserted
-
-// lsr bit 1 (receiver overrun)
-reg lsr1_d; // delayed
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr1_d <= 0;
- else lsr1_d <= lsr1;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr1r <= 0;
- else lsr1r <= lsr_mask ? 0 : lsr1r || (lsr1 && ~lsr1_d); // set on rise
-
-// lsr bit 2 (parity error)
-reg lsr2_d; // delayed
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr2_d <= 0;
- else lsr2_d <= lsr2;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr2r <= 0;
- else lsr2r <= lsr_mask ? 0 : lsr2r || (lsr2 && ~lsr2_d); // set on rise
-
-// lsr bit 3 (framing error)
-reg lsr3_d; // delayed
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr3_d <= 0;
- else lsr3_d <= lsr3;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr3r <= 0;
- else lsr3r <= lsr_mask ? 0 : lsr3r || (lsr3 && ~lsr3_d); // set on rise
-
-// lsr bit 4 (break indicator)
-reg lsr4_d; // delayed
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr4_d <= 0;
- else lsr4_d <= lsr4;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr4r <= 0;
- else lsr4r <= lsr_mask ? 0 : lsr4r || (lsr4 && ~lsr4_d);
-
-// lsr bit 5 (transmitter fifo is empty)
-reg lsr5_d;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr5_d <= 1;
- else lsr5_d <= lsr5;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr5r <= 1;
- else lsr5r <= (fifo_write) ? 0 : lsr5r || (lsr5 && ~lsr5_d);
-
-// lsr bit 6 (transmitter empty indicator)
-reg lsr6_d;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr6_d <= 1;
- else lsr6_d <= lsr6;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr6r <= 1;
- else lsr6r <= (fifo_write) ? 0 : lsr6r || (lsr6 && ~lsr6_d);
-
-// lsr bit 7 (error in fifo)
-reg lsr7_d;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr7_d <= 0;
- else lsr7_d <= lsr7;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr7r <= 0;
- else lsr7r <= lsr_mask ? 0 : lsr7r || (lsr7 && ~lsr7_d);
-
-// Frequency divider
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- dlc <= 0;
- else
- if (start_dlc | ~ (|dlc))
- dlc <= dl - 1; // preset counter
- else
- dlc <= dlc - 1; // decrement counter
-end
-
-// Enable signal generation logic
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- enable <= 1'b0;
- else
- if (|dl & ~(|dlc)) // dl>0 & dlc==0
- enable <= 1'b1;
- else
- enable <= 1'b0;
-end
-
-// Delaying THRE status for one character cycle after a character is written to an empty fifo.
-always @(lcr)
- case (lcr[3:0])
- 4'b0000 : block_value = 95; // 6 bits
- 4'b0100 : block_value = 103; // 6.5 bits
- 4'b0001, 4'b1000 : block_value = 111; // 7 bits
- 4'b1100 : block_value = 119; // 7.5 bits
- 4'b0010, 4'b0101, 4'b1001 : block_value = 127; // 8 bits
- 4'b0011, 4'b0110, 4'b1010, 4'b1101 : block_value = 143; // 9 bits
- 4'b0111, 4'b1011, 4'b1110 : block_value = 159; // 10 bits
- 4'b1111 : block_value = 175; // 11 bits
- endcase // case(lcr[3:0])
-
-// Counting time of one character minus stop bit
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- block_cnt <= 8'd0;
- else
- if(lsr5r & fifo_write) // THRE bit set & write to fifo occured
- block_cnt <= block_value;
- else
- if (enable & block_cnt != 8'b0) // only work on enable times
- block_cnt <= block_cnt - 1; // decrement break counter
-end // always of break condition detection
-
-// Generating THRE status enable signal
-assign thre_set_en = ~(|block_cnt);
-
-
-//
-// INTERRUPT LOGIC
-//
-
-assign rls_int = ier[`UART_IE_RLS] && (lsr[`UART_LS_OE] || lsr[`UART_LS_PE] || lsr[`UART_LS_FE] || lsr[`UART_LS_BI]);
-assign rda_int = ier[`UART_IE_RDA] && (rf_count >= {1'b0,trigger_level});
-assign thre_int = ier[`UART_IE_THRE] && lsr[`UART_LS_TFE];
-assign ms_int = ier[`UART_IE_MS] && (| msr[3:0]);
-assign ti_int = ier[`UART_IE_RDA] && (counter_t == 10'b0) && (|rf_count);
-
-reg rls_int_d;
-reg thre_int_d;
-reg ms_int_d;
-reg ti_int_d;
-reg rda_int_d;
-
-// delay lines
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) rls_int_d <= 0;
- else rls_int_d <= rls_int;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) rda_int_d <= 0;
- else rda_int_d <= rda_int;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) thre_int_d <= 0;
- else thre_int_d <= thre_int;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) ms_int_d <= 0;
- else ms_int_d <= ms_int;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) ti_int_d <= 0;
- else ti_int_d <= ti_int;
-
-// rise detection signals
-
-wire rls_int_rise;
-wire thre_int_rise;
-wire ms_int_rise;
-wire ti_int_rise;
-wire rda_int_rise;
-
-assign rda_int_rise = rda_int & ~rda_int_d;
-assign rls_int_rise = rls_int & ~rls_int_d;
-assign thre_int_rise = thre_int & ~thre_int_d;
-assign ms_int_rise = ms_int & ~ms_int_d;
-assign ti_int_rise = ti_int & ~ti_int_d;
-
-// interrupt pending flags
-reg rls_int_pnd;
-reg rda_int_pnd;
-reg thre_int_pnd;
-reg ms_int_pnd;
-reg ti_int_pnd;
-
-// interrupt pending flags assignments
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) rls_int_pnd <= 0;
- else
- rls_int_pnd <= lsr_mask ? 0 : // reset condition
- rls_int_rise ? 1 : // latch condition
- rls_int_pnd && ier[`UART_IE_RLS]; // default operation: remove if masked
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) rda_int_pnd <= 0;
- else
- rda_int_pnd <= ((rf_count == {1'b0,trigger_level}) && fifo_read) ? 0 : // reset condition
- rda_int_rise ? 1 : // latch condition
- rda_int_pnd && ier[`UART_IE_RDA]; // default operation: remove if masked
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) thre_int_pnd <= 0;
- else
- thre_int_pnd <= fifo_write || (iir_read & ~iir[`UART_II_IP] & iir[`UART_II_II] == `UART_II_THRE)? 0 :
- thre_int_rise ? 1 :
- thre_int_pnd && ier[`UART_IE_THRE];
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) ms_int_pnd <= 0;
- else
- ms_int_pnd <= msr_read ? 0 :
- ms_int_rise ? 1 :
- ms_int_pnd && ier[`UART_IE_MS];
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) ti_int_pnd <= 0;
- else
- ti_int_pnd <= fifo_read ? 0 :
- ti_int_rise ? 1 :
- ti_int_pnd && ier[`UART_IE_RDA];
-// end of pending flags
-
-// INT_O logic
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- int_o <= 1'b0;
- else
- int_o <=
- rls_int_pnd ? ~lsr_mask :
- rda_int_pnd ? 1 :
- ti_int_pnd ? ~fifo_read :
- thre_int_pnd ? !(fifo_write & iir_read) :
- ms_int_pnd ? ~msr_read :
- 0; // if no interrupt are pending
-end
-
-
-// Interrupt Identification register
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- iir <= 1;
- else
- if (rls_int_pnd) // interrupt is pending
- begin
- iir[`UART_II_II] <= `UART_II_RLS; // set identification register to correct value
- iir[`UART_II_IP] <= 1'b0; // and clear the IIR bit 0 (interrupt pending)
- end else // the sequence of conditions determines priority of interrupt identification
- if (rda_int)
- begin
- iir[`UART_II_II] <= `UART_II_RDA;
- iir[`UART_II_IP] <= 1'b0;
- end
- else if (ti_int_pnd)
- begin
- iir[`UART_II_II] <= `UART_II_TI;
- iir[`UART_II_IP] <= 1'b0;
- end
- else if (thre_int_pnd)
- begin
- iir[`UART_II_II] <= `UART_II_THRE;
- iir[`UART_II_IP] <= 1'b0;
- end
- else if (ms_int_pnd)
- begin
- iir[`UART_II_II] <= `UART_II_MS;
- iir[`UART_II_IP] <= 1'b0;
- end else // no interrupt is pending
- begin
- iir[`UART_II_II] <= 0;
- iir[`UART_II_IP] <= 1'b1;
- end
-end
-
-endmodule
Index: zap/trunk/src/testbench/cpu/uart16550/rtl/uart_top.v
===================================================================
--- zap/trunk/src/testbench/cpu/uart16550/rtl/uart_top.v (revision 42)
+++ zap/trunk/src/testbench/cpu/uart16550/rtl/uart_top.v (nonexistent)
@@ -1,338 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_top.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core top level. ////
-//// ////
-//// Known problems (limits): ////
-//// Note that transmitter and receiver instances are inside ////
-//// the uart_regs.v file. ////
-//// ////
-//// To Do: ////
-//// Nothing so far. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: 2001/05/17 ////
-//// (See log for the revision history) ////
-//// ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source is distributed in the hope that it will be ////
-//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
-//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
-//// PURPOSE. See the GNU Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.18 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.17 2001/12/19 08:40:03 mohor
-// Warnings fixed (unused signals removed).
-//
-// Revision 1.16 2001/12/06 14:51:04 gorban
-// Bug in LSR[0] is fixed.
-// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
-//
-// Revision 1.15 2001/12/03 21:44:29 gorban
-// Updated specification documentation.
-// Added full 32-bit data bus interface, now as default.
-// Address is 5-bit wide in 32-bit data bus mode.
-// Added wb_sel_i input to the core. It's used in the 32-bit mode.
-// Added debug interface with two 32-bit read-only registers in 32-bit mode.
-// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
-// My small test bench is modified to work with 32-bit mode.
-//
-// Revision 1.14 2001/11/07 17:51:52 gorban
-// Heavily rewritten interrupt and LSR subsystems.
-// Many bugs hopefully squashed.
-//
-// Revision 1.13 2001/10/20 09:58:40 gorban
-// Small synopsis fixes
-//
-// Revision 1.12 2001/08/25 15:46:19 gorban
-// Modified port names again
-//
-// Revision 1.11 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.10 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.4 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.3 2001/05/21 19:12:02 gorban
-// Corrected some Linter messages.
-//
-// Revision 1.2 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:12+02 jacob
-// Initial revision
-//
-//
-
-`include "uart_defines.v"
-
-module uart_top (
- wb_clk_i,
-
- // Wishbone signals
- wb_rst_i, wb_adr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_sel_i,
- int_o, // interrupt request
-
- // UART signals
- // serial input/output
- stx_pad_o, srx_pad_i,
-
- // modem signals
- rts_pad_o, cts_pad_i, dtr_pad_o, dsr_pad_i, ri_pad_i, dcd_pad_i
-`ifdef UART_HAS_BAUDRATE_OUTPUT
- , baud_o
-`endif
- );
-
-parameter uart_data_width = `UART_DATA_WIDTH;
-parameter uart_addr_width = `UART_ADDR_WIDTH;
-
-input wb_clk_i;
-
-// WISHBONE interface
-input wb_rst_i;
-input [uart_addr_width-1:0] wb_adr_i;
-input [uart_data_width-1:0] wb_dat_i;
-output [uart_data_width-1:0] wb_dat_o;
-input wb_we_i;
-input wb_stb_i;
-input wb_cyc_i;
-input [3:0] wb_sel_i;
-output wb_ack_o;
-output int_o;
-
-// UART signals
-input srx_pad_i;
-output stx_pad_o;
-output rts_pad_o;
-input cts_pad_i;
-output dtr_pad_o;
-input dsr_pad_i;
-input ri_pad_i;
-input dcd_pad_i;
-
-// optional baudrate output
-`ifdef UART_HAS_BAUDRATE_OUTPUT
-output baud_o;
-`endif
-
-
-wire stx_pad_o;
-wire rts_pad_o;
-wire dtr_pad_o;
-
-wire [uart_addr_width-1:0] wb_adr_i;
-wire [uart_data_width-1:0] wb_dat_i;
-wire [uart_data_width-1:0] wb_dat_o;
-
-wire [7:0] wb_dat8_i; // 8-bit internal data input
-wire [7:0] wb_dat8_o; // 8-bit internal data output
-wire [31:0] wb_dat32_o; // debug interface 32-bit output
-wire [3:0] wb_sel_i; // WISHBONE select signal
-wire [uart_addr_width-1:0] wb_adr_int;
-wire we_o; // Write enable for registers
-wire re_o; // Read enable for registers
-//
-// MODULE INSTANCES
-//
-
-`ifdef DATA_BUS_WIDTH_8
-`else
-// debug interface wires
-wire [3:0] ier;
-wire [3:0] iir;
-wire [1:0] fcr;
-wire [4:0] mcr;
-wire [7:0] lcr;
-wire [7:0] msr;
-wire [7:0] lsr;
-wire [`UART_FIFO_COUNTER_W-1:0] rf_count;
-wire [`UART_FIFO_COUNTER_W-1:0] tf_count;
-wire [2:0] tstate;
-wire [3:0] rstate;
-`endif
-
-`ifdef DATA_BUS_WIDTH_8
-//// WISHBONE interface module
-uart_wb wb_interface(
- .clk( wb_clk_i ),
- .wb_rst_i( wb_rst_i ),
- .wb_dat_i(wb_dat_i),
- .wb_dat_o(wb_dat_o),
- .wb_dat8_i(wb_dat8_i),
- .wb_dat8_o(wb_dat8_o),
- .wb_dat32_o(32'b0),
- .wb_sel_i(4'b0),
- .wb_we_i( wb_we_i ),
- .wb_stb_i( wb_stb_i ),
- .wb_cyc_i( wb_cyc_i ),
- .wb_ack_o( wb_ack_o ),
- .wb_adr_i(wb_adr_i),
- .wb_adr_int(wb_adr_int),
- .we_o( we_o ),
- .re_o(re_o)
- );
-`else
-uart_wb wb_interface(
- .clk( wb_clk_i ),
- .wb_rst_i( wb_rst_i ),
- .wb_dat_i(wb_dat_i),
- .wb_dat_o(wb_dat_o),
- .wb_dat8_i(wb_dat8_i),
- .wb_dat8_o(wb_dat8_o),
- .wb_sel_i(wb_sel_i),
- .wb_dat32_o(wb_dat32_o),
- .wb_we_i( wb_we_i ),
- .wb_stb_i( wb_stb_i ),
- .wb_cyc_i( wb_cyc_i ),
- .wb_ack_o( wb_ack_o ),
- .wb_adr_i(wb_adr_i),
- .wb_adr_int(wb_adr_int),
- .we_o( we_o ),
- .re_o(re_o)
- );
-`endif
-
-// Registers
-uart_regs regs(
- .clk( wb_clk_i ),
- .wb_rst_i( wb_rst_i ),
- .wb_addr_i( wb_adr_int ),
- .wb_dat_i( wb_dat8_i ),
- .wb_dat_o( wb_dat8_o ),
- .wb_we_i( we_o ),
- .wb_re_i(re_o),
- .modem_inputs( {cts_pad_i, dsr_pad_i,
- ri_pad_i, dcd_pad_i} ),
- .stx_pad_o( stx_pad_o ),
- .srx_pad_i( srx_pad_i ),
-`ifdef DATA_BUS_WIDTH_8
-`else
-// debug interface signals enabled
-.ier(ier),
-.iir(iir),
-.fcr(fcr),
-.mcr(mcr),
-.lcr(lcr),
-.msr(msr),
-.lsr(lsr),
-.rf_count(rf_count),
-.tf_count(tf_count),
-.tstate(tstate),
-.rstate(rstate),
-`endif
- .rts_pad_o( rts_pad_o ),
- .dtr_pad_o( dtr_pad_o ),
- .int_o( int_o )
-`ifdef UART_HAS_BAUDRATE_OUTPUT
- , .baud_o(baud_o)
-`endif
-
-);
-
-`ifdef DATA_BUS_WIDTH_8
-`else
-uart_debug_if dbg(/*AUTOINST*/
- // Outputs
- .wb_dat32_o (wb_dat32_o[31:0]),
- // Inputs
- .wb_adr_i (wb_adr_int[`UART_ADDR_WIDTH-1:0]),
- .ier (ier[3:0]),
- .iir (iir[3:0]),
- .fcr (fcr[1:0]),
- .mcr (mcr[4:0]),
- .lcr (lcr[7:0]),
- .msr (msr[7:0]),
- .lsr (lsr[7:0]),
- .rf_count (rf_count[`UART_FIFO_COUNTER_W-1:0]),
- .tf_count (tf_count[`UART_FIFO_COUNTER_W-1:0]),
- .tstate (tstate[2:0]),
- .rstate (rstate[3:0]));
-`endif
-
-initial
-begin
- `ifdef DATA_BUS_WIDTH_8
- $display("(%m) UART INFO: Data bus width is 8. No Debug interface.\n");
- `else
- $display("(%m) UART INFO: Data bus width is 32. Debug Interface present.\n");
- `endif
- `ifdef UART_HAS_BAUDRATE_OUTPUT
- $display("(%m) UART INFO: Has baudrate output\n");
- `else
- $display("(%m) UART INFO: Doesn't have baudrate output\n");
- `endif
-end
-
-endmodule
-
-
Index: zap/trunk/src/testbench/cpu/uart16550/rtl/raminfr.v
===================================================================
--- zap/trunk/src/testbench/cpu/uart16550/rtl/raminfr.v (revision 42)
+++ zap/trunk/src/testbench/cpu/uart16550/rtl/raminfr.v (nonexistent)
@@ -1,112 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// raminfr.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// Inferrable Distributed RAM for FIFOs ////
-//// ////
-//// Known problems (limits): ////
-//// None . ////
-//// ////
-//// To Do: ////
-//// Nothing so far. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// ////
-//// Created: 2002/07/22 ////
-//// Last Updated: 2002/07/22 ////
-//// (See log for the revision history) ////
-//// ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source is distributed in the hope that it will be ////
-//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
-//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
-//// PURPOSE. See the GNU Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.1 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-
-//Following is the Verilog code for a dual-port RAM with asynchronous read.
-module raminfr
- (clk, we, a, dpra, di, dpo);
-
-parameter addr_width = 4;
-parameter data_width = 8;
-parameter depth = 16;
-
-input clk;
-input we;
-input [addr_width-1:0] a;
-input [addr_width-1:0] dpra;
-input [data_width-1:0] di;
-//output [data_width-1:0] spo;
-output [data_width-1:0] dpo;
-reg [data_width-1:0] ram [depth-1:0];
-
-wire [data_width-1:0] dpo;
-wire [data_width-1:0] di;
-wire [addr_width-1:0] a;
-wire [addr_width-1:0] dpra;
-
- always @(posedge clk) begin
- if (we)
- ram[a] <= di;
- end
-// assign spo = ram[a];
- assign dpo = ram[dpra];
-endmodule
-
Index: zap/trunk/src/testbench/cpu/uart16550/rtl/uart_receiver.v
===================================================================
--- zap/trunk/src/testbench/cpu/uart16550/rtl/uart_receiver.v (revision 42)
+++ zap/trunk/src/testbench/cpu/uart16550/rtl/uart_receiver.v (nonexistent)
@@ -1,481 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_receiver.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core receiver logic ////
-//// ////
-//// Known problems (limits): ////
-//// None known ////
-//// ////
-//// To Do: ////
-//// Thourough testing. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: 2001/05/17 ////
-//// (See log for the revision history) ////
-//// ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source is distributed in the hope that it will be ////
-//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
-//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
-//// PURPOSE. See the GNU Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.29 2002/07/29 21:16:18 gorban
-// The uart_defines.v file is included again in sources.
-//
-// Revision 1.28 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.27 2001/12/30 20:39:13 mohor
-// More than one character was stored in case of break. End of the break
-// was not detected correctly.
-//
-// Revision 1.26 2001/12/20 13:28:27 mohor
-// Missing declaration of rf_push_q fixed.
-//
-// Revision 1.25 2001/12/20 13:25:46 mohor
-// rx push changed to be only one cycle wide.
-//
-// Revision 1.24 2001/12/19 08:03:34 mohor
-// Warnings cleared.
-//
-// Revision 1.23 2001/12/19 07:33:54 mohor
-// Synplicity was having troubles with the comment.
-//
-// Revision 1.22 2001/12/17 14:46:48 mohor
-// overrun signal was moved to separate block because many sequential lsr
-// reads were preventing data from being written to rx fifo.
-// underrun signal was not used and was removed from the project.
-//
-// Revision 1.21 2001/12/13 10:31:16 mohor
-// timeout irq must be set regardless of the rda irq (rda irq does not reset the
-// timeout counter).
-//
-// Revision 1.20 2001/12/10 19:52:05 gorban
-// Igor fixed break condition bugs
-//
-// Revision 1.19 2001/12/06 14:51:04 gorban
-// Bug in LSR[0] is fixed.
-// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
-//
-// Revision 1.18 2001/12/03 21:44:29 gorban
-// Updated specification documentation.
-// Added full 32-bit data bus interface, now as default.
-// Address is 5-bit wide in 32-bit data bus mode.
-// Added wb_sel_i input to the core. It's used in the 32-bit mode.
-// Added debug interface with two 32-bit read-only registers in 32-bit mode.
-// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
-// My small test bench is modified to work with 32-bit mode.
-//
-// Revision 1.17 2001/11/28 19:36:39 gorban
-// Fixed: timeout and break didn't pay attention to current data format when counting time
-//
-// Revision 1.16 2001/11/27 22:17:09 gorban
-// Fixed bug that prevented synthesis in uart_receiver.v
-//
-// Revision 1.15 2001/11/26 21:38:54 gorban
-// Lots of fixes:
-// Break condition wasn't handled correctly at all.
-// LSR bits could lose their values.
-// LSR value after reset was wrong.
-// Timing of THRE interrupt signal corrected.
-// LSR bit 0 timing corrected.
-//
-// Revision 1.14 2001/11/10 12:43:21 gorban
-// Logic Synthesis bugs fixed. Some other minor changes
-//
-// Revision 1.13 2001/11/08 14:54:23 mohor
-// Comments in Slovene language deleted, few small fixes for better work of
-// old tools. IRQs need to be fix.
-//
-// Revision 1.12 2001/11/07 17:51:52 gorban
-// Heavily rewritten interrupt and LSR subsystems.
-// Many bugs hopefully squashed.
-//
-// Revision 1.11 2001/10/31 15:19:22 gorban
-// Fixes to break and timeout conditions
-//
-// Revision 1.10 2001/10/20 09:58:40 gorban
-// Small synopsis fixes
-//
-// Revision 1.9 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.8 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.6 2001/06/23 11:21:48 gorban
-// DL made 16-bit long. Fixed transmission/reception bugs.
-//
-// Revision 1.5 2001/06/02 14:28:14 gorban
-// Fixed receiver and transmitter. Major bug fixed.
-//
-// Revision 1.4 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.3 2001/05/27 17:37:49 gorban
-// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
-//
-// Revision 1.2 2001/05/21 19:12:02 gorban
-// Corrected some Linter messages.
-//
-// Revision 1.1 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:11+02 jacob
-// Initial revision
-//
-//
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-
-
-`include "uart_defines.v"
-
-module uart_receiver (clk, wb_rst_i, lcr, rf_pop, srx_pad_i, enable,
- counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask, rstate, rf_push_pulse);
-
-input clk;
-input wb_rst_i;
-input [7:0] lcr;
-input rf_pop;
-input srx_pad_i;
-input enable;
-input rx_reset;
-input lsr_mask;
-
-output [9:0] counter_t;
-output [`UART_FIFO_COUNTER_W-1:0] rf_count;
-output [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
-output rf_overrun;
-output rf_error_bit;
-output [3:0] rstate;
-output rf_push_pulse;
-
-reg [3:0] rstate;
-reg [3:0] rcounter16;
-reg [2:0] rbit_counter;
-reg [7:0] rshift; // receiver shift register
-reg rparity; // received parity
-reg rparity_error;
-reg rframing_error; // framing error flag
-reg rbit_in;
-reg rparity_xor;
-reg [7:0] counter_b; // counts the 0 (low) signals
-reg rf_push_q;
-
-// RX FIFO signals
-reg [`UART_FIFO_REC_WIDTH-1:0] rf_data_in;
-wire [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
-wire rf_push_pulse;
-reg rf_push;
-wire rf_pop;
-wire rf_overrun;
-wire [`UART_FIFO_COUNTER_W-1:0] rf_count;
-wire rf_error_bit; // an error (parity or framing) is inside the fifo
-wire break_error = (counter_b == 0);
-
-// RX FIFO instance
-uart_rfifo #(`UART_FIFO_REC_WIDTH) fifo_rx(
- .clk( clk ),
- .wb_rst_i( wb_rst_i ),
- .data_in( rf_data_in ),
- .data_out( rf_data_out ),
- .push( rf_push_pulse ),
- .pop( rf_pop ),
- .overrun( rf_overrun ),
- .count( rf_count ),
- .error_bit( rf_error_bit ),
- .fifo_reset( rx_reset ),
- .reset_status(lsr_mask)
-);
-
-wire rcounter16_eq_7 = (rcounter16 == 4'd7);
-wire rcounter16_eq_0 = (rcounter16 == 4'd0);
-wire rcounter16_eq_1 = (rcounter16 == 4'd1);
-
-wire [3:0] rcounter16_minus_1 = rcounter16 - 1'b1;
-
-parameter sr_idle = 4'd0;
-parameter sr_rec_start = 4'd1;
-parameter sr_rec_bit = 4'd2;
-parameter sr_rec_parity = 4'd3;
-parameter sr_rec_stop = 4'd4;
-parameter sr_check_parity = 4'd5;
-parameter sr_rec_prepare = 4'd6;
-parameter sr_end_bit = 4'd7;
-parameter sr_ca_lc_parity = 4'd8;
-parameter sr_wait1 = 4'd9;
-parameter sr_push = 4'd10;
-
-
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- begin
- rstate <= sr_idle;
- rbit_in <= 1'b0;
- rcounter16 <= 0;
- rbit_counter <= 0;
- rparity_xor <= 1'b0;
- rframing_error <= 1'b0;
- rparity_error <= 1'b0;
- rparity <= 1'b0;
- rshift <= 0;
- rf_push <= 1'b0;
- rf_data_in <= 0;
- end
- else
- if (enable)
- begin
- case (rstate)
- sr_idle : begin
- rf_push <= 1'b0;
- rf_data_in <= 0;
- rcounter16 <= 4'b1110;
- if (srx_pad_i==1'b0 & ~break_error) // detected a pulse (start bit?)
- begin
- rstate <= sr_rec_start;
- end
- end
- sr_rec_start : begin
- rf_push <= 1'b0;
- if (rcounter16_eq_7) // check the pulse
- if (srx_pad_i==1'b1) // no start bit
- rstate <= sr_idle;
- else // start bit detected
- rstate <= sr_rec_prepare;
- rcounter16 <= rcounter16_minus_1;
- end
- sr_rec_prepare:begin
- case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word
- 2'b00 : rbit_counter <= 3'b100;
- 2'b01 : rbit_counter <= 3'b101;
- 2'b10 : rbit_counter <= 3'b110;
- 2'b11 : rbit_counter <= 3'b111;
- endcase
- if (rcounter16_eq_0)
- begin
- rstate <= sr_rec_bit;
- rcounter16 <= 4'b1110;
- rshift <= 0;
- end
- else
- rstate <= sr_rec_prepare;
- rcounter16 <= rcounter16_minus_1;
- end
- sr_rec_bit : begin
- if (rcounter16_eq_0)
- rstate <= sr_end_bit;
- if (rcounter16_eq_7) // read the bit
- case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word
- 2'b00 : rshift[4:0] <= {srx_pad_i, rshift[4:1]};
- 2'b01 : rshift[5:0] <= {srx_pad_i, rshift[5:1]};
- 2'b10 : rshift[6:0] <= {srx_pad_i, rshift[6:1]};
- 2'b11 : rshift[7:0] <= {srx_pad_i, rshift[7:1]};
- endcase
- rcounter16 <= rcounter16_minus_1;
- end
- sr_end_bit : begin
- if (rbit_counter==3'b0) // no more bits in word
- if (lcr[`UART_LC_PE]) // choose state based on parity
- rstate <= sr_rec_parity;
- else
- begin
- rstate <= sr_rec_stop;
- rparity_error <= 1'b0; // no parity - no error :)
- end
- else // else we have more bits to read
- begin
- rstate <= sr_rec_bit;
- rbit_counter <= rbit_counter - 1'b1;
- end
- rcounter16 <= 4'b1110;
- end
- sr_rec_parity: begin
- if (rcounter16_eq_7) // read the parity
- begin
- rparity <= srx_pad_i;
- rstate <= sr_ca_lc_parity;
- end
- rcounter16 <= rcounter16_minus_1;
- end
- sr_ca_lc_parity : begin // rcounter equals 6
- rcounter16 <= rcounter16_minus_1;
- rparity_xor <= ^{rshift,rparity}; // calculate parity on all incoming data
- rstate <= sr_check_parity;
- end
- sr_check_parity: begin // rcounter equals 5
- case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]})
- 2'b00: rparity_error <= rparity_xor == 0; // no error if parity 1
- 2'b01: rparity_error <= ~rparity; // parity should sticked to 1
- 2'b10: rparity_error <= rparity_xor == 1; // error if parity is odd
- 2'b11: rparity_error <= rparity; // parity should be sticked to 0
- endcase
- rcounter16 <= rcounter16_minus_1;
- rstate <= sr_wait1;
- end
- sr_wait1 : if (rcounter16_eq_0)
- begin
- rstate <= sr_rec_stop;
- rcounter16 <= 4'b1110;
- end
- else
- rcounter16 <= rcounter16_minus_1;
- sr_rec_stop : begin
- if (rcounter16_eq_7) // read the parity
- begin
- rframing_error <= !srx_pad_i; // no framing error if input is 1 (stop bit)
- rstate <= sr_push;
- end
- rcounter16 <= rcounter16_minus_1;
- end
- sr_push : begin
-///////////////////////////////////////
-// $display($time, ": received: %b", rf_data_in);
- if(srx_pad_i | break_error)
- begin
- if(break_error)
- rf_data_in <= {8'b0, 3'b100}; // break input (empty character) to receiver FIFO
- else
- rf_data_in <= {rshift, 1'b0, rparity_error, rframing_error};
- rf_push <= 1'b1;
- rstate <= sr_idle;
- end
- else if(~rframing_error) // There's always a framing before break_error -> wait for break or srx_pad_i
- begin
- rf_data_in <= {rshift, 1'b0, rparity_error, rframing_error};
- rf_push <= 1'b1;
- rcounter16 <= 4'b1110;
- rstate <= sr_rec_start;
- end
-
- end
- default : rstate <= sr_idle;
- endcase
- end // if (enable)
-end // always of receiver
-
-always @ (posedge clk or posedge wb_rst_i)
-begin
- if(wb_rst_i)
- rf_push_q <= 0;
- else
- rf_push_q <= rf_push;
-end
-
-assign rf_push_pulse = rf_push & ~rf_push_q;
-
-
-//
-// Break condition detection.
-// Works in conjuction with the receiver state machine
-
-reg [9:0] toc_value; // value to be set to timeout counter
-
-always @(lcr)
- case (lcr[3:0])
- 4'b0000 : toc_value = 447; // 7 bits
- 4'b0100 : toc_value = 479; // 7.5 bits
- 4'b0001, 4'b1000 : toc_value = 511; // 8 bits
- 4'b1100 : toc_value = 543; // 8.5 bits
- 4'b0010, 4'b0101, 4'b1001 : toc_value = 575; // 9 bits
- 4'b0011, 4'b0110, 4'b1010, 4'b1101 : toc_value = 639; // 10 bits
- 4'b0111, 4'b1011, 4'b1110 : toc_value = 703; // 11 bits
- 4'b1111 : toc_value = 767; // 12 bits
- endcase // case(lcr[3:0])
-
-wire [7:0] brc_value; // value to be set to break counter
-assign brc_value = toc_value[9:2]; // the same as timeout but 1 insead of 4 character times
-
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- counter_b <= 8'd159;
- else
- if (srx_pad_i)
- counter_b <= brc_value; // character time length - 1
- else
- if(enable & counter_b != 8'b0) // only work on enable times break not reached.
- counter_b <= counter_b - 1; // decrement break counter
-end // always of break condition detection
-
-///
-/// Timeout condition detection
-reg [9:0] counter_t; // counts the timeout condition clocks
-
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- counter_t <= 10'd639; // 10 bits for the default 8N1
- else
- if(rf_push_pulse || rf_pop || rf_count == 0) // counter is reset when RX FIFO is empty, accessed or above trigger level
- counter_t <= toc_value;
- else
- if (enable && counter_t != 10'b0) // we don't want to underflow
- counter_t <= counter_t - 1;
-end
-
-endmodule
Index: zap/trunk/src/testbench/cpu/uart16550/rtl/uart_debug_if.v
===================================================================
--- zap/trunk/src/testbench/cpu/uart16550/rtl/uart_debug_if.v (revision 42)
+++ zap/trunk/src/testbench/cpu/uart16550/rtl/uart_debug_if.v (nonexistent)
@@ -1,124 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_debug_if.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core debug interface. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// ////
-//// Created: 2001/12/02 ////
-//// (See log for the revision history) ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source is distributed in the hope that it will be ////
-//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
-//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
-//// PURPOSE. See the GNU Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.4 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.3 2001/12/19 08:40:03 mohor
-// Warnings fixed (unused signals removed).
-//
-// Revision 1.2 2001/12/12 22:17:30 gorban
-// some synthesis bugs fixed
-//
-// Revision 1.1 2001/12/04 21:14:16 gorban
-// committed the debug interface file
-//
-
-
-`include "uart_defines.v"
-
-module uart_debug_if (/*AUTOARG*/
-// Outputs
-wb_dat32_o,
-// Inputs
-wb_adr_i, ier, iir, fcr, mcr, lcr, msr,
-lsr, rf_count, tf_count, tstate, rstate
-) ;
-
-input [`UART_ADDR_WIDTH-1:0] wb_adr_i;
-output [31:0] wb_dat32_o;
-input [3:0] ier;
-input [3:0] iir;
-input [1:0] fcr; /// bits 7 and 6 of fcr. Other bits are ignored
-input [4:0] mcr;
-input [7:0] lcr;
-input [7:0] msr;
-input [7:0] lsr;
-input [`UART_FIFO_COUNTER_W-1:0] rf_count;
-input [`UART_FIFO_COUNTER_W-1:0] tf_count;
-input [2:0] tstate;
-input [3:0] rstate;
-
-
-wire [`UART_ADDR_WIDTH-1:0] wb_adr_i;
-reg [31:0] wb_dat32_o;
-
-always @(/*AUTOSENSE*/fcr or ier or iir or lcr or lsr or mcr or msr
- or rf_count or rstate or tf_count or tstate or wb_adr_i)
- case (wb_adr_i)
- // 8 + 8 + 4 + 4 + 8
- 5'b01000: wb_dat32_o = {msr,lcr,iir,ier,lsr};
- // 5 + 2 + 5 + 4 + 5 + 3
- 5'b01100: wb_dat32_o = {8'b0, fcr,mcr, rf_count, rstate, tf_count, tstate};
- default: wb_dat32_o = 0;
- endcase // case(wb_adr_i)
-
-endmodule // uart_debug_if
-
Index: zap/trunk/src/testbench/cpu/uart16550/rtl/uart_rfifo.v
===================================================================
--- zap/trunk/src/testbench/cpu/uart16550/rtl/uart_rfifo.v (revision 42)
+++ zap/trunk/src/testbench/cpu/uart16550/rtl/uart_rfifo.v (nonexistent)
@@ -1,318 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_rfifo.v (Modified from uart_fifo.v) ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core receiver FIFO ////
-//// ////
-//// To Do: ////
-//// Nothing. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: 2002/07/22 ////
-//// (See log for the revision history) ////
-//// ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source is distributed in the hope that it will be ////
-//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
-//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
-//// PURPOSE. See the GNU Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.3 2003/06/11 16:37:47 gorban
-// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
-//
-// Revision 1.2 2002/07/29 21:16:18 gorban
-// The uart_defines.v file is included again in sources.
-//
-// Revision 1.1 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.16 2001/12/20 13:25:46 mohor
-// rx push changed to be only one cycle wide.
-//
-// Revision 1.15 2001/12/18 09:01:07 mohor
-// Bug that was entered in the last update fixed (rx state machine).
-//
-// Revision 1.14 2001/12/17 14:46:48 mohor
-// overrun signal was moved to separate block because many sequential lsr
-// reads were preventing data from being written to rx fifo.
-// underrun signal was not used and was removed from the project.
-//
-// Revision 1.13 2001/11/26 21:38:54 gorban
-// Lots of fixes:
-// Break condition wasn't handled correctly at all.
-// LSR bits could lose their values.
-// LSR value after reset was wrong.
-// Timing of THRE interrupt signal corrected.
-// LSR bit 0 timing corrected.
-//
-// Revision 1.12 2001/11/08 14:54:23 mohor
-// Comments in Slovene language deleted, few small fixes for better work of
-// old tools. IRQs need to be fix.
-//
-// Revision 1.11 2001/11/07 17:51:52 gorban
-// Heavily rewritten interrupt and LSR subsystems.
-// Many bugs hopefully squashed.
-//
-// Revision 1.10 2001/10/20 09:58:40 gorban
-// Small synopsis fixes
-//
-// Revision 1.9 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.8 2001/08/24 08:48:10 mohor
-// FIFO was not cleared after the data was read bug fixed.
-//
-// Revision 1.7 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.3 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.3 2001/05/27 17:37:48 gorban
-// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
-//
-// Revision 1.2 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:12+02 jacob
-// Initial revision
-//
-//
-
-
-`include "uart_defines.v"
-
-module uart_rfifo (clk,
- wb_rst_i, data_in, data_out,
-// Control signals
- push, // push strobe, active high
- pop, // pop strobe, active high
-// status signals
- overrun,
- count,
- error_bit,
- fifo_reset,
- reset_status
- );
-
-
-// FIFO parameters
-parameter fifo_width = `UART_FIFO_WIDTH;
-parameter fifo_depth = `UART_FIFO_DEPTH;
-parameter fifo_pointer_w = `UART_FIFO_POINTER_W;
-parameter fifo_counter_w = `UART_FIFO_COUNTER_W;
-
-input clk;
-input wb_rst_i;
-input push;
-input pop;
-input [fifo_width-1:0] data_in;
-input fifo_reset;
-input reset_status;
-
-output [fifo_width-1:0] data_out;
-output overrun;
-output [fifo_counter_w-1:0] count;
-output error_bit;
-
-wire [fifo_width-1:0] data_out;
-wire [7:0] data8_out;
-// flags FIFO
-reg [2:0] fifo[fifo_depth-1:0];
-
-// FIFO pointers
-reg [fifo_pointer_w-1:0] top;
-reg [fifo_pointer_w-1:0] bottom;
-
-reg [fifo_counter_w-1:0] count;
-reg overrun;
-
-wire [fifo_pointer_w-1:0] top_plus_1 = top + 1'b1;
-
-raminfr #(fifo_pointer_w,8,fifo_depth) rfifo
- (.clk(clk),
- .we(push),
- .a(top),
- .dpra(bottom),
- .di(data_in[fifo_width-1:fifo_width-8]),
- .dpo(data8_out)
- );
-
-always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
-begin
- if (wb_rst_i)
- begin
- top <= 0;
- bottom <= 1'b0;
- count <= 0;
- fifo[0] <= 0;
- fifo[1] <= 0;
- fifo[2] <= 0;
- fifo[3] <= 0;
- fifo[4] <= 0;
- fifo[5] <= 0;
- fifo[6] <= 0;
- fifo[7] <= 0;
- fifo[8] <= 0;
- fifo[9] <= 0;
- fifo[10] <= 0;
- fifo[11] <= 0;
- fifo[12] <= 0;
- fifo[13] <= 0;
- fifo[14] <= 0;
- fifo[15] <= 0;
- end
- else
- if (fifo_reset) begin
- top <= 0;
- bottom <= 1'b0;
- count <= 0;
- fifo[0] <= 0;
- fifo[1] <= 0;
- fifo[2] <= 0;
- fifo[3] <= 0;
- fifo[4] <= 0;
- fifo[5] <= 0;
- fifo[6] <= 0;
- fifo[7] <= 0;
- fifo[8] <= 0;
- fifo[9] <= 0;
- fifo[10] <= 0;
- fifo[11] <= 0;
- fifo[12] <= 0;
- fifo[13] <= 0;
- fifo[14] <= 0;
- fifo[15] <= 0;
- end
- else
- begin
- case ({push, pop})
- 2'b10 : if (count0)
- begin
- fifo[bottom] <= 0;
- bottom <= bottom + 1'b1;
- count <= count - 1'b1;
- end
- 2'b11 : begin
- bottom <= bottom + 1'b1;
- top <= top_plus_1;
- fifo[top] <= data_in[2:0];
- end
- default: ;
- endcase
- end
-end // always
-
-always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
-begin
- if (wb_rst_i)
- overrun <= 1'b0;
- else
- if(fifo_reset | reset_status)
- overrun <= 1'b0;
- else
- if(push & ~pop & (count==fifo_depth))
- overrun <= 1'b1;
-end // always
-
-
-// please note though that data_out is only valid one clock after pop signal
-assign data_out = {data8_out,fifo[bottom]};
-
-// Additional logic for detection of error conditions (parity and framing) inside the FIFO
-// for the Line Status Register bit 7
-
-wire [2:0] word0 = fifo[0];
-wire [2:0] word1 = fifo[1];
-wire [2:0] word2 = fifo[2];
-wire [2:0] word3 = fifo[3];
-wire [2:0] word4 = fifo[4];
-wire [2:0] word5 = fifo[5];
-wire [2:0] word6 = fifo[6];
-wire [2:0] word7 = fifo[7];
-
-wire [2:0] word8 = fifo[8];
-wire [2:0] word9 = fifo[9];
-wire [2:0] word10 = fifo[10];
-wire [2:0] word11 = fifo[11];
-wire [2:0] word12 = fifo[12];
-wire [2:0] word13 = fifo[13];
-wire [2:0] word14 = fifo[14];
-wire [2:0] word15 = fifo[15];
-
-// a 1 is returned if any of the error bits in the fifo is 1
-assign error_bit = |(word0[2:0] | word1[2:0] | word2[2:0] | word3[2:0] |
- word4[2:0] | word5[2:0] | word6[2:0] | word7[2:0] |
- word8[2:0] | word9[2:0] | word10[2:0] | word11[2:0] |
- word12[2:0] | word13[2:0] | word14[2:0] | word15[2:0] );
-
-endmodule
Index: zap/trunk/src/testbench/cpu/timer/timer.v
===================================================================
--- zap/trunk/src/testbench/cpu/timer/timer.v (revision 42)
+++ zap/trunk/src/testbench/cpu/timer/timer.v (nonexistent)
@@ -1,255 +0,0 @@
-`default_nettype none
-
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program is distributed in the hope that it will be useful, --
-// -- but WITHOUT ANY WARRANTY; without even the implied warranty of --
-// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
-// -- GNU General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-
-
-//
-// A testbench model of a wishbone timer peripheral.
-//
-// Local addresses:
-// 0x0 (DEVEN) - 0x1 to enable the timer unit. 0x0 to disable the unit.
-// 0x4 (DEVPR) - Timer length in number of Wishbone clocks.
-// 0x8 (DEVAK) - Write: 0x1 to acknowledge interrupt. Read: 0x1 reveals timer interrupt occured.
-// 0xC (DEVST) - 0x1 to start the timer. Write only. Always reads 0x0.
-//
-
-module timer (
-
-// Clock and reset.
-input wire i_clk,
-input wire i_rst,
-
-// Wishbone interface.
-input wire [31:0] i_wb_dat,
-input wire [3:0] i_wb_adr,
-input wire i_wb_stb,
-input wire i_wb_cyc,
-input wire i_wb_wen,
-input wire [3:0] i_wb_sel,
-output reg [31:0] o_wb_dat,
-output reg o_wb_ack,
-
-
-// Interrupt output. Level interrupt.
-output reg o_irq
-
-);
-
-// Timer registers.
-reg [31:0] DEVEN; // 0x0
-reg [31:0] DEVPR; // 0x4
-reg [31:0] DEVAK; // 0x8
-reg [31:0] DEVST; // 0xC
-
-`ifndef TB_TIMER
-`define TB_TIMER
- `define DEVEN 32'h0
- `define DEVPR 32'h4
- `define DEVAK 32'h8
- `define DEVST 32'hC
-`endif
-
-// Timer core.
-reg [31:0] ctr; // Core counter.
-reg start; // Pulse to start the timer. Done signal is cleared.
-reg done; // Asserted when timer is done.
-reg clr; // Clears the done signal.
-reg [31:0] state; // State
-reg enable; // 1 to enable the timer.
-reg [31:0] finalval; // Final value to count.
-reg [31:0] wbstate;
-
-localparam IDLE = 0;
-localparam COUNTING = 1;
-localparam DONE = 2;
-
-localparam WBIDLE = 0;
-localparam WBREAD = 1;
-localparam WBWRITE = 2;
-localparam WBACK = 3;
-
-always @*
- o_irq = done;
-
-always @*
-begin
- start = DEVST[0];
- enable = DEVEN[0];
- finalval = DEVPR;
- clr = DEVAK[0];
-end
-
-always @ (posedge i_clk)
-begin
- DEVST <= 0;
-
- if ( i_rst )
- begin
- DEVEN <= 0;
- DEVPR <= 0;
- DEVAK <= 0;
- DEVST <= 0;
- wbstate <= WBIDLE;
- o_wb_dat <= 0;
- o_wb_ack <= 0;
- end
- else
- begin
- case(wbstate)
- WBIDLE:
- begin
- o_wb_ack <= 1'd0;
-
- if ( i_wb_stb && i_wb_cyc )
- begin
- if ( i_wb_wen )
- wbstate <= WBWRITE;
- else
- wbstate <= WBREAD;
- end
- end
-
- WBWRITE:
- begin
- case(i_wb_adr)
- `DEVEN: // DEVEN
- begin
- $display($time, " - %m --> Writing register DEVEN...");
- if ( i_wb_sel[0] ) DEVEN[7:0] <= i_wb_dat >> 0;
- if ( i_wb_sel[1] ) DEVEN[15:8] <= i_wb_dat >> 8;
- if ( i_wb_sel[2] ) DEVEN[23:16] <= i_wb_dat >> 16;
- if ( i_wb_sel[3] ) DEVEN[31:24] <= i_wb_dat >> 24;
- end
-
- `DEVPR: // DEVPR
- begin
- $display($time, " - %m --> Writing register DEVPR...");
- if ( i_wb_sel[0] ) DEVPR[7:0] <= i_wb_dat >> 0;
- if ( i_wb_sel[1] ) DEVPR[15:8] <= i_wb_dat >> 8;
- if ( i_wb_sel[2] ) DEVPR[23:16] <= i_wb_dat >> 16;
- if ( i_wb_sel[3] ) DEVPR[31:24] <= i_wb_dat >> 24;
-
- end
-
- `DEVAK: // DEVAK
- begin
- $display($time, " - %m --> Writing register DEVAK...");
- if ( i_wb_sel[0] ) DEVPR[7:0] <= i_wb_dat >> 0;
- if ( i_wb_sel[1] ) DEVPR[15:8] <= i_wb_dat >> 8;
- if ( i_wb_sel[2] ) DEVPR[23:16] <= i_wb_dat >> 16;
- if ( i_wb_sel[3] ) DEVPR[31:24] <= i_wb_dat >> 24;
- end
-
- `DEVST: // DEVST
- begin
- $display($time, " - %m --> Writing register DEVST...");
- if ( i_wb_sel[0] ) DEVST[7:0] <= i_wb_dat >> 0;
- if ( i_wb_sel[1] ) DEVST[15:8] <= i_wb_dat >> 8;
- if ( i_wb_sel[2] ) DEVST[23:16] <= i_wb_dat >> 16;
- if ( i_wb_sel[3] ) DEVST[31:24] <= i_wb_dat >> 24;
- end
-
- endcase
-
- wbstate <= WBACK;
- end
-
- WBREAD:
- begin
- case(i_wb_adr)
- `DEVEN: o_wb_dat <= DEVEN;
- `DEVPR: o_wb_dat <= DEVPR;
- `DEVAK: o_wb_dat <= done;
- `DEVST: o_wb_dat <= 32'd0;
- endcase
-
- wbstate <= WBACK;
- end
-
- WBACK:
- begin
- o_wb_ack <= 1'd1;
- wbstate <= WBIDLE;
- end
- endcase
- end
-end
-
-always @ (posedge i_clk)
-begin
- if ( i_rst || !enable )
- begin
- ctr <= 0;
- done <= 0;
- state <= IDLE;
- end
- else // if enabled
- begin
- case(state)
- IDLE:
- begin
- if ( start )
- begin
- $display($time,": Timer started counting...");
- state <= COUNTING;
- end
- end
-
- COUNTING:
- begin
- ctr <= ctr + 1;
-
- if ( ctr == finalval )
- begin
- $display($time, ": Timer done counting...");
- state <= DONE;
- end
- end
-
- DONE:
- begin
- done <= 1;
-
- if ( start )
- begin
- $display($time, ": Timer got START from DONE state...");
- done <= 0;
- state <= COUNTING;
- ctr <= 0;
- end
- else if ( clr ) // Acknowledge.
- begin
- $display($time, ": Timer got done in ACK state...");
- done <= 0;
- state <= IDLE;
- ctr <= 0;
- end
- end
- endcase
- end
-end
-
-endmodule
-
-`default_nettype wire
Index: zap/trunk/src/testbench/cpu/vic/vic.v
===================================================================
--- zap/trunk/src/testbench/cpu/vic/vic.v (revision 42)
+++ zap/trunk/src/testbench/cpu/vic/vic.v (nonexistent)
@@ -1,171 +0,0 @@
-`default_nettype none
-
-
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program is distributed in the hope that it will be useful, --
-// -- but WITHOUT ANY WARRANTY; without even the implied warranty of --
-// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
-// -- GNU General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-
-//
-// Testbench VIC model.
-//
-// 0x0 - INT_STATUS
-// 0x4 - INT_MASK
-// 0x8 - INT_CLEAR
-//
-
-module vic #(parameter SOURCES = 2) (
-
-// Clock and reset.
-input wire i_clk,
-input wire i_rst,
-
-// Wishbone interface.
-input wire [31:0] i_wb_dat,
-input wire [3:0] i_wb_adr,
-input wire i_wb_stb,
-input wire i_wb_cyc,
-input wire i_wb_wen,
-input wire [3:0] i_wb_sel,
-output reg [31:0] o_wb_dat,
-output reg o_wb_ack,
-
-// Interrupt sources in
-input [SOURCES-1:0] i_irq,
-
-// Interrupt output. Level interrupt.
-output reg o_irq
-
-
-);
-
-`define INT_STATUS 0
-`define INT_MASK 4
-`define INT_CLEAR 8
-
-reg [31:0] INT_STATUS;
-reg [31:0] INT_MASK;
-reg [31:0] wbstate;
-
-// Wishbone states.
-localparam WBIDLE = 0;
-localparam WBREAD = 1;
-localparam WBWRITE = 2;
-localparam WBACK = 3;
-
-always @ (posedge i_clk)
-begin
- o_irq <= | ( INT_STATUS & ~INT_MASK );
-end
-
-always @ (posedge i_clk)
-begin
- if ( i_rst )
- begin
- wbstate <= WBIDLE;
- o_wb_dat <= 0;
- o_wb_ack <= 0;
-
- INT_MASK <= 32'hffffffff;
- INT_STATUS <= 32'h0;
- end
- else
- begin:blk1
- integer i;
-
- // Normally record interrupts.
- for(i=0;i> 0;
- if ( i_wb_sel[1] ) INT_MASK[15:8] <= i_wb_dat >> 8;
- if ( i_wb_sel[2] ) INT_MASK[23:16] <= i_wb_dat >> 16;
- if ( i_wb_sel[3] ) INT_MASK[31:24] <= i_wb_dat >> 24;
-
- end
-
- `INT_CLEAR: // INT_CLEAR
- begin: blk22
- integer i;
-
- $display($time, "Writing to INT_CLEAR register...");
- if ( i_wb_sel[0] ) for(i=0; i <=7;i++) if ( i_wb_dat[i] ) INT_STATUS[i] <= 1'd0;
- if ( i_wb_sel[1] ) for(i=8; i<=15;i++) if ( i_wb_dat[i] ) INT_STATUS[i] <= 1'd0;
- if ( i_wb_sel[2] ) for(i=16;i<=23;i++) if ( i_wb_dat[i] ) INT_STATUS[i] <= 1'd0;
- if ( i_wb_sel[3] ) for(i=24;i<=31;i++) if ( i_wb_dat[i] ) INT_STATUS[i] <= 1'd0;
- end
-
- default: $display($time, "%m --> Warning: Attemting to write to illgal register...");
-
- endcase
-
- wbstate <= WBACK;
- end
-
- WBREAD:
- begin
- case(i_wb_adr)
- `INT_STATUS: o_wb_dat <= `INT_STATUS;
- `INT_MASK: o_wb_dat <= `INT_MASK;
-
- default:
- begin
- $display($time, " %m --> Warning: Attempting to read from illegal register. Will return 0...");
- o_wb_dat <= 0;
- end
- endcase
-
- wbstate <= WBACK;
- end
-
- WBACK:
- begin
- o_wb_ack <= 1'd1;
- wbstate <= WBIDLE;
- end
- endcase
- end
-end
-
-endmodule
-
-`default_nettype wire
Index: zap/trunk/src/testbench/cpu/zap_ram_tb.v
===================================================================
--- zap/trunk/src/testbench/cpu/zap_ram_tb.v (revision 42)
+++ zap/trunk/src/testbench/cpu/zap_ram_tb.v (nonexistent)
@@ -1,145 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program is distributed in the hope that it will be useful, --
-// -- but WITHOUT ANY WARRANTY; without even the implied warranty of --
-// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
-// -- GNU General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`include "zap_defines.vh"
-
-//
-// This is a testbench model of a wishbone RAM. Note that port 2 is
-// unused.
-//
-
-module model_ram_dual #(parameter SIZE_IN_BYTES = 4096) (
-
-input i_clk,
-
-input i_wb_cyc,
-input i_wb_stb,
-input [31:0] i_wb_adr,
-input [31:0] i_wb_dat,
-input [3:0] i_wb_sel,
-input i_wb_we,
-
-// unused.
-input i_wb_cyc2,
-input i_wb_stb2,
-input [31:0] i_wb_adr2,
-input [31:0] i_wb_dat2,
-input [3:0] i_wb_sel2,
-input i_wb_we2,
-
-output reg [31:0] o_wb_dat,
-output reg [31:0] o_wb_dat2, // unused.
-
-output reg o_wb_ack,
-output reg o_wb_ack2 // unused.
-
-);
-
-integer seed = `SEED;
-reg [31:0] ram [SIZE_IN_BYTES/4 -1:0];
-
-initial
-begin:blk1
- integer i;
- integer j;
- reg [7:0] mem [SIZE_IN_BYTES-1:0];
-
- j = 0;
-
- for ( i=0;i> 2 ];
- end
- else if ( i_wb_we && i_wb_cyc && i_wb_stb && !stall )
- begin
- o_wb_ack <= 1'd1;
- o_wb_dat <= 'dx;
-
- if ( i_wb_sel[0] ) ram [ i_wb_adr >> 2 ][7:0] <= i_wb_dat[7:0];
- if ( i_wb_sel[1] ) ram [ i_wb_adr >> 2 ][15:8] <= i_wb_dat[15:8];
- if ( i_wb_sel[2] ) ram [ i_wb_adr >> 2 ][23:16] <= i_wb_dat[23:16];
- if ( i_wb_sel[3] ) ram [ i_wb_adr >> 2 ][31:24] <= i_wb_dat[31:24];
- end
- else
- begin
- o_wb_ack <= 1'd0;
- o_wb_dat <= 'dx;
- end
-end
-
-// Wishbone RAM model.
-always @ (negedge i_clk)
-begin:blk2
- reg stall2;
-
- stall2 = $random(seed);
-
- if ( !i_wb_we2 && i_wb_cyc2 && i_wb_stb2 && !stall2 )
- begin
- o_wb_ack2 <= 1'd1;
- o_wb_dat2 <= ram [ i_wb_adr2 >> 2 ];
- end
- else if ( i_wb_we2 && i_wb_cyc2 && i_wb_stb2 && !stall2 )
- begin
- o_wb_ack2 <= 1'd1;
- o_wb_dat2 <= 'dx;
-
- if ( i_wb_sel2[0] ) ram [ i_wb_adr2 >> 2 ][7:0] <= i_wb_dat2[7:0];
- if ( i_wb_sel2[1] ) ram [ i_wb_adr2 >> 2 ][15:8] <= i_wb_dat2[15:8];
- if ( i_wb_sel2[2] ) ram [ i_wb_adr2 >> 2 ][23:16] <= i_wb_dat2[23:16];
- if ( i_wb_sel2[3] ) ram [ i_wb_adr2 >> 2 ][31:24] <= i_wb_dat2[31:24];
- end
- else
- begin
- o_wb_ack2 <= 1'd0;
- o_wb_dat2 <= 'dx;
- end
-end
-
-endmodule
-
-///////////////////////////////////////////////////////////////////////////////
-
Index: zap/trunk/src/testbench/cpu/zap_tb.v
===================================================================
--- zap/trunk/src/testbench/cpu/zap_tb.v (revision 42)
+++ zap/trunk/src/testbench/cpu/zap_tb.v (nonexistent)
@@ -1,475 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program is distributed in the hope that it will be useful, --
-// -- but WITHOUT ANY WARRANTY; without even the implied warranty of --
-// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
-// -- GNU General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-
-
-`default_nettype none
-`include "zap_defines.vh"
-
-//
-// Top level testbench. Ties the CPU together with RAM, UART, VIC and a timer.
-//
-// UART address space starts from FFFFFFE0 to FFFFFFFF
-// Timer address space starts from FFFFFFC0 to FFFFFFDF
-// VIC address space starts from FFFFFFA0 to FFFFFFBF
-//
-
-module zap_test; // +nctop+zap_test
-
-localparam UART_LO = 32'hFFFFFFE0;
-localparam UART_HI = 32'hFFFFFFFF;
-localparam TIMER_LO = 32'hFFFFFFC0;
-localparam TIMER_HI = 32'hFFFFFFDF;
-localparam VIC_LO = 32'hFFFFFFA0;
-localparam VIC_HI = 32'hFFFFFFBF;
-
-// CPU config.
-parameter RAM_SIZE = 32768;
-parameter START = 1992;
-parameter COUNT = 120;
-parameter DATA_SECTION_TLB_ENTRIES = 4;
-parameter DATA_LPAGE_TLB_ENTRIES = 8;
-parameter DATA_SPAGE_TLB_ENTRIES = 16;
-parameter DATA_CACHE_SIZE = 1024;
-parameter CODE_SECTION_TLB_ENTRIES = 4;
-parameter CODE_LPAGE_TLB_ENTRIES = 8;
-parameter CODE_SPAGE_TLB_ENTRIES = 16;
-parameter CODE_CACHE_SIZE = 1024;
-parameter FIFO_DEPTH = 4;
-parameter BP_ENTRIES = 1024;
-parameter STORE_BUFFER_DEPTH = 32;
-
-///////////////////////////////////////////////////////////////////////////////
-
-reg i_clk;
-reg i_reset;
-
-
-wire data_wb_cyc; reg data_wb_cyc_ram, data_wb_cyc_uart, data_wb_cyc_timer, data_wb_cyc_vic;
-wire data_wb_stb; reg data_wb_stb_ram, data_wb_stb_uart, data_wb_stb_timer, data_wb_stb_vic;
-reg [31:0] data_wb_din; wire [31:0] data_wb_din_ram, data_wb_din_uart, data_wb_din_timer, data_wb_din_vic;
-reg data_wb_ack; wire data_wb_ack_ram, data_wb_ack_uart, data_wb_ack_timer, data_wb_ack_vic;
-
-wire [3:0] data_wb_sel;
-wire data_wb_we;
-wire [31:0] data_wb_dout;
-wire [31:0] data_wb_adr;
-wire [2:0] data_wb_cti; // Cycle Type Indicator.
-
-wire global_irq;
-
-// Wishbone selector.
-always @*
-begin
- data_wb_cyc_uart = 0;
- data_wb_stb_uart = 0;
- data_wb_cyc_ram = 0;
- data_wb_stb_ram = 0;
- data_wb_cyc_timer = 0;
- data_wb_stb_timer = 0;
- data_wb_cyc_vic = 0;
- data_wb_stb_vic = 0;
-
- if ( data_wb_adr >= UART_LO && data_wb_adr <= UART_HI ) // UART access
- begin
- data_wb_cyc_uart = data_wb_cyc;
- data_wb_stb_uart = data_wb_stb;
- data_wb_ack = data_wb_ack_uart;
- data_wb_din = data_wb_din_uart;
- end
- else if ( data_wb_adr >= TIMER_LO && data_wb_adr <= TIMER_HI ) // Timer access
- begin
- data_wb_cyc_timer = data_wb_cyc;
- data_wb_stb_timer = data_wb_stb;
- data_wb_ack = data_wb_ack_timer;
- data_wb_din = data_wb_din_timer;
- end
- else if ( data_wb_adr >= VIC_LO && data_wb_adr <= VIC_HI ) // VIC access.
- begin
- data_wb_cyc_vic = data_wb_cyc;
- data_wb_stb_vic = data_wb_stb;
- data_wb_ack = data_wb_ack_vic;
- data_wb_din = data_wb_din_vic;
- end
- else // RAM access
- begin
- data_wb_cyc_ram = data_wb_cyc;
- data_wb_stb_ram = data_wb_stb;
- data_wb_ack = data_wb_ack_ram;
- data_wb_din = data_wb_din_ram;
- end
-end
-
-initial
-begin
- $display("################################################################################");
- $display("SEED in decimal = %d", `SEED);
- $display("parameter RAM_SIZE %d", RAM_SIZE );
- $display("parameter START %d", START );
- $display("parameter COUNT %d", COUNT );
- $display("parameter FIFO_DEPTH %d", u_zap_top.FIFO_DEPTH);
-
- `ifdef STALL
- $display("STALL defined!");
- `endif
-
- `ifdef TLB_DEBUG
- $display("TLB_DEBUG defined!");
- `endif
-
- $display("parameter DATA_SECTION_TLB_ENTRIES = %d", DATA_SECTION_TLB_ENTRIES ) ;
- $display("parameter DATA_LPAGE_TLB_ENTRIES = %d", DATA_LPAGE_TLB_ENTRIES ) ;
- $display("parameter DATA_SPAGE_TLB_ENTRIES = %d", DATA_SPAGE_TLB_ENTRIES ) ;
- $display("parameter DATA_CACHE_SIZE = %d", DATA_CACHE_SIZE ) ;
- $display("parameter CODE_SECTION_TLB_ENTRIES = %d", CODE_SECTION_TLB_ENTRIES ) ;
- $display("parameter CODE_LPAGE_TLB_ENTRIES = %d", CODE_LPAGE_TLB_ENTRIES ) ;
- $display("parameter CODE_SPAGE_TLB_ENTRIES = %d", CODE_SPAGE_TLB_ENTRIES ) ;
- $display("parameter CODE_CACHE_SIZE = %d", CODE_CACHE_SIZE ) ;
- $display("parameter STORE_BUFFER_DEPTH = %d", STORE_BUFFER_DEPTH ) ;
- $display("################################################################################");
-
-end
-
-//////////////////////////////////////////////////////////////////////////////////
-
-// =========================
-// Processor core.
-// =========================
-zap_top #(
- // Configure FIFO depth and BP entries.
- .FIFO_DEPTH(FIFO_DEPTH),
- .BP_ENTRIES(BP_ENTRIES),
- .STORE_BUFFER_DEPTH(STORE_BUFFER_DEPTH),
-
- // data config.
- .DATA_SECTION_TLB_ENTRIES(DATA_SECTION_TLB_ENTRIES),
- .DATA_LPAGE_TLB_ENTRIES(DATA_LPAGE_TLB_ENTRIES),
- .DATA_SPAGE_TLB_ENTRIES(DATA_SPAGE_TLB_ENTRIES),
- .DATA_CACHE_SIZE(DATA_CACHE_SIZE),
-
- // code config.
- .CODE_SECTION_TLB_ENTRIES(CODE_SECTION_TLB_ENTRIES),
- .CODE_LPAGE_TLB_ENTRIES(CODE_LPAGE_TLB_ENTRIES),
- .CODE_SPAGE_TLB_ENTRIES(CODE_SPAGE_TLB_ENTRIES),
- .CODE_CACHE_SIZE(CODE_CACHE_SIZE)
-)
-u_zap_top
-(
- .i_clk(i_clk),
- .i_reset(i_reset),
-
- `ifdef IRQ_EN
- .i_irq(global_irq),
- `else
- .i_irq(1'd0),
- `endif
-
- .i_fiq(1'd0),
- .o_wb_cyc(data_wb_cyc),
- .o_wb_stb(data_wb_stb),
- .o_wb_adr(data_wb_adr),
- .o_wb_we (data_wb_we),
- .o_wb_cti(data_wb_cti),
- .i_wb_dat(data_wb_din),
- .o_wb_dat(data_wb_dout),
- .i_wb_ack(data_wb_ack),
- .o_wb_sel(data_wb_sel),
- .o_wb_bte() // Always zero.
-
-);
-
-// ===============================
-// UART
-// ===============================
-
-wire uart_in = 1'd0;
-wire uart_out;
-wire uart_irq;
-
-uart_top u_uart_top (
-
- // WISHBONE interface
- .wb_clk_i(i_clk),
- .wb_rst_i(i_reset),
- .wb_adr_i(data_wb_adr),
- .wb_dat_i(data_wb_dout),
- .wb_dat_o(data_wb_din_uart),
- .wb_we_i (data_wb_we),
- .wb_stb_i(data_wb_stb_uart),
- .wb_cyc_i(data_wb_cyc_uart),
- .wb_sel_i(data_wb_sel),
- .wb_ack_o(data_wb_ack_uart),
- .int_o (uart_irq), // Interrupt.
-
- // UART signals.
- .srx_pad_i(uart_in),
- .stx_pad_o(uart_out),
- .rts_pad_o(),
- .cts_pad_i(1'd0),
- .dtr_pad_o(),
- .dsr_pad_i(1'd0),
- .ri_pad_i (1'd0),
- .dcd_pad_i(1'd0)
-);
-
-// ===============================
-// Timer
-// ===============================
-
-wire timer_irq;
-
-timer u_timer (
- .i_clk(i_clk),
- .i_rst(i_reset),
- .i_wb_adr(data_wb_adr),
- .i_wb_dat(data_wb_dout),
- .i_wb_stb(data_wb_stb_timer),
- .i_wb_cyc(data_wb_cyc_timer), // From core
- .i_wb_wen(data_wb_we),
- .i_wb_sel(data_wb_sel),
- .o_wb_dat(data_wb_din_timer), // To core.
- .o_wb_ack(data_wb_ack_timer),
- .o_irq(timer_irq) // Interrupt
-);
-
-// ===============================
-// VIC
-// ===============================
-
-vic #(.SOURCES(2)) u_vic (
- .i_clk(i_clk),
- .i_rst(i_reset),
- .i_wb_adr(data_wb_adr),
- .i_wb_dat(data_wb_dout),
- .i_wb_stb(data_wb_stb_vic),
- .i_wb_cyc(data_wb_cyc_vic), // From core
- .i_wb_wen(data_wb_we),
- .i_wb_sel(data_wb_sel),
- .o_wb_dat(data_wb_din_vic), // To core.
- .o_wb_ack(data_wb_ack_vic),
-
- .i_irq({timer_irq, uart_irq}), // Concatenate interrupt sources.
- .o_irq(global_irq) // Interrupt out
-);
-
-///////////////////////////////////////////////////////////////////////////////
-
-reg [3:0] clk_ctr = 4'd0;
-
-// Logic to read from UART - Assumes no parity, 8 bits per character and
-// 1 stop bit. TB logic.
-
-localparam UART_WAIT_FOR_START = 0;
-localparam UART_RX = 1;
-localparam UART_STOP_BIT = 2;
-
-integer uart_state = UART_WAIT_FOR_START;
-reg uart_sof = 1'd0;
-reg uart_eof = 1'd0;
-integer uart_ctr = 0;
-integer uart_bit_ctr = 1'dx;
-reg [7:0] uart_sr = 0;
-reg [7:0] UART_SR;
-reg UART_SR_DAV;
-
-always @ (posedge i_clk)
-begin
- UART_SR_DAV = 1'd0;
- uart_sof = 1'd0;
- uart_eof = 1'd0;
-
- case ( uart_state )
- UART_WAIT_FOR_START:
- begin
- if ( !uart_out )
- begin
- uart_ctr = uart_ctr + 1;
- uart_sof = 1'd1;
- end
-
- if ( !uart_out && uart_ctr == 16 )
- begin
- uart_sof = 1'd0;
- uart_state = UART_RX;
- uart_ctr = 0;
- uart_bit_ctr = 0;
- end
- end
-
- UART_RX:
- begin
- uart_ctr++;
-
- if ( uart_ctr == 2 )
- uart_sr = uart_sr >> 1 | uart_out << 7;
-
- if ( uart_ctr == 16 )
- begin
- uart_bit_ctr++;
- uart_ctr = 0;
-
- if ( uart_bit_ctr == 8 )
- begin
- uart_state = UART_STOP_BIT;
- UART_SR = uart_sr;
- UART_SR_DAV = 1'd1;
- uart_ctr = 0;
- uart_bit_ctr = 0;
- end
- end
- end
-
- UART_STOP_BIT:
- begin
- uart_ctr++;
-
- if ( uart_out && uart_ctr == 16 ) // Stop bit.
- begin
- uart_state = UART_WAIT_FOR_START;
- uart_bit_ctr = 0;
- uart_ctr = 0;
- end
- end
- endcase
-end
-
-// Write ASCII characters on UART TX to a file.
-
-integer signed fh;
-
-initial
-begin
- fh = $fopen(`UART_FILE_PATH, "w");
-
- if ( fh == -1 )
- begin
- $display($time, " - Error: Failed to open UART output log.");
- $finish;
- end
- else
- begin
- $display($time, " - File opened %s!", `UART_FILE_PATH);
- end
-end
-
-always @ (negedge i_clk)
-begin
- if ( UART_SR_DAV )
- begin
- $display("UART Wrote %c", UART_SR);
- $fwrite(fh, "%c", UART_SR);
- $fflush(fh);
- end
-end
-
-// ===============================
-// RAM
-// ===============================
-model_ram_dual
-#(
- .SIZE_IN_BYTES (RAM_SIZE)
-)
-U_MODEL_RAM_DATA
-(
- .i_clk(i_clk),
-
- .i_wb_cyc(data_wb_cyc_ram),
- .i_wb_stb(data_wb_stb_ram),
- .i_wb_adr(data_wb_adr),
- .i_wb_we(data_wb_we),
- .o_wb_dat(data_wb_din_ram),
- .i_wb_dat(data_wb_dout),
- .o_wb_ack(data_wb_ack_ram),
- .i_wb_sel(data_wb_sel),
-
- // Port 2 is unused.
- .i_wb_cyc2(0),
- .i_wb_stb2(0),
- .i_wb_adr2(0),
- .i_wb_we2 (0),
- .o_wb_dat2(),
- .o_wb_ack2(),
- .i_wb_sel2(0),
- .i_wb_dat2(0)
-);
-
-// ===========================
-// Variables.
-// ===========================
-integer i;
-
-// ===========================
-// Clocks.
-// ===========================
-initial i_clk = 0;
-always #10 i_clk = !i_clk;
-
-integer seed = `SEED;
-integer seed_new = `SEED + 1;
-
-// ===========================
-// Interrupts
-// ===========================
-
-initial i_reset = 1'd0;
-
-initial
-begin
- for(i=START;i>>>>>>>>>>>>>>>>>>>>>> MEMORY DUMP START <<<<<<<<<<<<<<<<<<<<<<<");
-
- for(i=START;i>>>>>>>>>>>>>>>>>>>>>>>>>");
-
- $fclose(fh);
-
- `include "zap_check.vh"
-end
-
-endmodule
-
-`default_nettype wire
Index: zap/trunk/src/testbench/External_IP/uart16550/doc/src/UART_spec.doc
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: zap/trunk/src/testbench/External_IP/uart16550/doc/src/UART_spec.doc
===================================================================
--- zap/trunk/src/testbench/External_IP/uart16550/doc/src/UART_spec.doc (nonexistent)
+++ zap/trunk/src/testbench/External_IP/uart16550/doc/src/UART_spec.doc (revision 43)
zap/trunk/src/testbench/External_IP/uart16550/doc/src/UART_spec.doc
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: zap/trunk/src/testbench/External_IP/uart16550/doc/CHANGES.txt
===================================================================
--- zap/trunk/src/testbench/External_IP/uart16550/doc/CHANGES.txt (nonexistent)
+++ zap/trunk/src/testbench/External_IP/uart16550/doc/CHANGES.txt (revision 43)
@@ -0,0 +1,111 @@
+Note: This Changes file is being maintained since 25.5.2001.
+
+29.07.2002
+~~~~~~~~~~
+Reverted to have uart_defines.v file to be included in the verilog
+files. It seems that it's been a bad idea in the first place.
+
+22.07.2002
+~~~~~~~~~~
+Notice that this file hasn't been updated for a while so not all changed are present.
+
+Bug Fixes:
+ * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
+ Problem reported by Kenny.Tung.
+ * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
+
+Improvements:
+ * Made FIFO's as general inferrable memory where possible.
+ So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
+ This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
+
+ * Added optional baudrate output (baud_o).
+ This is identical to BAUDOUT* signal on 16550 chip.
+ It outputs 16xbit_clock_rate - the divided clock.
+ It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
+
+Note:
+ The uart_defines.v file is no longer included in the source files.
+ So keep this in mind when doing simulation. Add it manually.
+ I've done this, so that you could you your own define files for
+ different configurations. I need this for the IrDA core I develop.
+ You can just uncomment the `includes if you want the old behaviour.
+ The uart_fifo.v file is no longer used. Intead uart_rfifo.v and uart_tfifo.v
+ file are now present. Also raminfr.v in the new inferred ram module.
+
+ Check the new core and I hope you'll like it.
+
+10.08.2001
+~~~~~~~~~~
+* Modified naming of top signals and defines to be unique and easy to integrate
+* Changed the directory structure of the core to new structure as described in OpenCores
+ coding guidelines. !!!
+* Fixed (I hope) the detection of break condition
+* Added top level parameters for data width and address line width
+
+23.06.2001
+~~~~~~~~~~
+
+* With the help of Bob Kirstein another two bugs were fixed:
+ 1. Trasmitter was sending stop bit two 16xclock cycle slonger than needed.
+ 2. Receiver was losing 1 16xclock cycle on each character and went out of sync.
+
+* Major change:
+ I have modified the divisor latch register to be 16-bit long instead of 32 as I thought was
+ necessary for higher speed systems. Thanks to Rick Wright for pointing this out.
+ So now, DL3 and DL4 register bytes are not used.
+ Documentation is updated to follow this change.
+
+* Note that more than 1 stop bit in a byte i snot implemented.
+
+2.05.2001
+~~~~~~~~~
+
+* Fixed transmitter and receiver - the start and the stop bits were sent and received complemented.
+ Big thanks go to Bob Kirstein for pointing this out to me.
+
+
+31.05.2001
+~~~~~~~~~~
+
+* Minor changes in register reading code
+* Changed FCR to be 2 bits wide (reset bits are not needed) and instead enabled the rx_reset and tx_reset
+ signals which I forgot to implement.
+* Changed defines for FCR.
+* Cleaned ports that were not connected in top-level.
+* Changed the code to have only one FIFO module instead of two to overcome versioning problem on the cost of
+ some additional gate count. UART_RX_FIFO was modified a little and renamed to UART_FIFO.
+* UART_RX_FIFO.v and UART_TX_FIFO.v files removed from the project.
+* Changes to receiver and transmitter modules concerning FIFO handling.
+* Commented out `include "UART_defines" in all files but UART_top.v and test bench.
+* Modified test bench a little for a little better check.
+
+
+29.05.2001
+~~~~~~~~~~
+
+* Fixed: Line Control Register block didn't have wb_rst_i in its sensitivity list
+* Fixed: Modem Status Register block didn't have wb_rst_i in its sensitivity list and didn't set reset value
+* Fixed rf_pop, lsr_mask, msi_reset and threi_clear not being synthesizable in release 1.7. (Thanks
+ to Pavel Korenski for pointing this to me)
+
+
+27.05.2001
+~~~~~~~~~~
+
+Thanks to Rick Wright for pointing me many of my bugs.
+
+* Fixed the rf_pop and lsr_mask flags not being deasserted.
+* Fixed Time-Out interrupt not being masked by bit 0 in IER
+* Fixed interrupt logic not being masked by IER
+* Fixed bit 0 (interrupt pending) of IIR being set incorrectly
+* Fixed Modem Status Register bits 3:0 handling (didn't work as should have)
+* Fixed modem status interrupt to be related to bits [3:0] (deltas) instead of the bits 7:4 of MSR.
+ This way the interrupt is cleared upon reading from the MSR.
+* Fixed THRE interrupt not being reset by reading IIR
+* Changed Receiver and Transmitter FIFO, so that they do not use the FIFO_inc.v file because of problems
+ with #include command.
+* Removed FIFO_inc.v from CVS tree.
+
+* Updated specifications .pdf file
+
Index: zap/trunk/src/testbench/External_IP/uart16550/doc/UART_spec.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: zap/trunk/src/testbench/External_IP/uart16550/doc/UART_spec.pdf
===================================================================
--- zap/trunk/src/testbench/External_IP/uart16550/doc/UART_spec.pdf (nonexistent)
+++ zap/trunk/src/testbench/External_IP/uart16550/doc/UART_spec.pdf (revision 43)
zap/trunk/src/testbench/External_IP/uart16550/doc/UART_spec.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: zap/trunk/src/testbench/External_IP/uart16550/rtl/raminfr.v
===================================================================
--- zap/trunk/src/testbench/External_IP/uart16550/rtl/raminfr.v (nonexistent)
+++ zap/trunk/src/testbench/External_IP/uart16550/rtl/raminfr.v (revision 43)
@@ -0,0 +1,112 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// raminfr.v ////
+//// ////
+//// ////
+//// This file is part of the "UART 16550 compatible" project ////
+//// http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Documentation related to this project: ////
+//// - http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Projects compatibility: ////
+//// - WISHBONE ////
+//// RS232 Protocol ////
+//// 16550D uart (mostly supported) ////
+//// ////
+//// Overview (main Features): ////
+//// Inferrable Distributed RAM for FIFOs ////
+//// ////
+//// Known problems (limits): ////
+//// None . ////
+//// ////
+//// To Do: ////
+//// Nothing so far. ////
+//// ////
+//// Author(s): ////
+//// - gorban@opencores.org ////
+//// - Jacob Gorban ////
+//// ////
+//// Created: 2002/07/22 ////
+//// Last Updated: 2002/07/22 ////
+//// (See log for the revision history) ////
+//// ////
+//// Modified for use in the ZAP project by Revanth Kamaraj ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000, 2001 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.1 2002/07/22 23:02:23 gorban
+// Bug Fixes:
+// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
+// Problem reported by Kenny.Tung.
+// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
+//
+// Improvements:
+// * Made FIFO's as general inferrable memory where possible.
+// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
+// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
+//
+// * Added optional baudrate output (baud_o).
+// This is identical to BAUDOUT* signal on 16550 chip.
+// It outputs 16xbit_clock_rate - the divided clock.
+// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
+//
+
+//Following is the Verilog code for a dual-port RAM with asynchronous read.
+module raminfr
+ (clk, we, a, dpra, di, dpo);
+
+parameter addr_width = 4;
+parameter data_width = 8;
+parameter depth = 16;
+
+input clk;
+input we;
+input [addr_width-1:0] a;
+input [addr_width-1:0] dpra;
+input [data_width-1:0] di;
+//output [data_width-1:0] spo;
+output [data_width-1:0] dpo;
+reg [data_width-1:0] ram [depth-1:0];
+
+wire [data_width-1:0] dpo;
+wire [data_width-1:0] di;
+wire [addr_width-1:0] a;
+wire [addr_width-1:0] dpra;
+
+ always @(posedge clk) begin
+ if (we)
+ ram[a] <= di;
+ end
+// assign spo = ram[a];
+ assign dpo = ram[dpra];
+endmodule
+
Index: zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_debug_if.v
===================================================================
--- zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_debug_if.v (nonexistent)
+++ zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_debug_if.v (revision 43)
@@ -0,0 +1,124 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// uart_debug_if.v ////
+//// ////
+//// ////
+//// This file is part of the "UART 16550 compatible" project ////
+//// http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Documentation related to this project: ////
+//// - http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Projects compatibility: ////
+//// - WISHBONE ////
+//// RS232 Protocol ////
+//// 16550D uart (mostly supported) ////
+//// ////
+//// Overview (main Features): ////
+//// UART core debug interface. ////
+//// ////
+//// Author(s): ////
+//// - gorban@opencores.org ////
+//// - Jacob Gorban ////
+//// ////
+//// Created: 2001/12/02 ////
+//// (See log for the revision history) ////
+//// Modified for use in the ZAP project by Revanth Kamaraj ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000, 2001 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.4 2002/07/22 23:02:23 gorban
+// Bug Fixes:
+// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
+// Problem reported by Kenny.Tung.
+// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
+//
+// Improvements:
+// * Made FIFO's as general inferrable memory where possible.
+// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
+// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
+//
+// * Added optional baudrate output (baud_o).
+// This is identical to BAUDOUT* signal on 16550 chip.
+// It outputs 16xbit_clock_rate - the divided clock.
+// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
+//
+// Revision 1.3 2001/12/19 08:40:03 mohor
+// Warnings fixed (unused signals removed).
+//
+// Revision 1.2 2001/12/12 22:17:30 gorban
+// some synthesis bugs fixed
+//
+// Revision 1.1 2001/12/04 21:14:16 gorban
+// committed the debug interface file
+//
+
+
+`include "uart_defines.v"
+
+module uart_debug_if (/*AUTOARG*/
+// Outputs
+wb_dat32_o,
+// Inputs
+wb_adr_i, ier, iir, fcr, mcr, lcr, msr,
+lsr, rf_count, tf_count, tstate, rstate
+) ;
+
+input [`UART_ADDR_WIDTH-1:0] wb_adr_i;
+output [31:0] wb_dat32_o;
+input [3:0] ier;
+input [3:0] iir;
+input [1:0] fcr; /// bits 7 and 6 of fcr. Other bits are ignored
+input [4:0] mcr;
+input [7:0] lcr;
+input [7:0] msr;
+input [7:0] lsr;
+input [`UART_FIFO_COUNTER_W-1:0] rf_count;
+input [`UART_FIFO_COUNTER_W-1:0] tf_count;
+input [2:0] tstate;
+input [3:0] rstate;
+
+
+wire [`UART_ADDR_WIDTH-1:0] wb_adr_i;
+reg [31:0] wb_dat32_o;
+
+always @(/*AUTOSENSE*/fcr or ier or iir or lcr or lsr or mcr or msr
+ or rf_count or rstate or tf_count or tstate or wb_adr_i)
+ case (wb_adr_i)
+ // 8 + 8 + 4 + 4 + 8
+ 5'b01000: wb_dat32_o = {msr,lcr,iir,ier,lsr};
+ // 5 + 2 + 5 + 4 + 5 + 3
+ 5'b01100: wb_dat32_o = {8'b0, fcr,mcr, rf_count, rstate, tf_count, tstate};
+ default: wb_dat32_o = 0;
+ endcase // case(wb_adr_i)
+
+endmodule // uart_debug_if
+
Index: zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_defines.v
===================================================================
--- zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_defines.v (nonexistent)
+++ zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_defines.v (revision 43)
@@ -0,0 +1,249 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// uart_defines.v ////
+//// ////
+//// ////
+//// This file is part of the "UART 16550 compatible" project ////
+//// http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Documentation related to this project: ////
+//// - http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Projects compatibility: ////
+//// - WISHBONE ////
+//// RS232 Protocol ////
+//// 16550D uart (mostly supported) ////
+//// ////
+//// Overview (main Features): ////
+//// Defines of the Core ////
+//// ////
+//// Known problems (limits): ////
+//// None ////
+//// ////
+//// To Do: ////
+//// Nothing. ////
+//// ////
+//// Author(s): ////
+//// - gorban@opencores.org ////
+//// - Jacob Gorban ////
+//// - Igor Mohor (igorm@opencores.org) ////
+//// ////
+//// Created: 2001/05/12 ////
+//// Last Updated: 2001/05/17 ////
+//// (See log for the revision history) ////
+///// Modified for use in the ZAP project by Revanth Kamaraj ////
+/// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000, 2001 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.13 2003/06/11 16:37:47 gorban
+// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
+//
+// Revision 1.12 2002/07/22 23:02:23 gorban
+// Bug Fixes:
+// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
+// Problem reported by Kenny.Tung.
+// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
+//
+// Improvements:
+// * Made FIFO's as general inferrable memory where possible.
+// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
+// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
+//
+// * Added optional baudrate output (baud_o).
+// This is identical to BAUDOUT* signal on 16550 chip.
+// It outputs 16xbit_clock_rate - the divided clock.
+// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
+//
+// Revision 1.10 2001/12/11 08:55:40 mohor
+// Scratch register define added.
+//
+// Revision 1.9 2001/12/03 21:44:29 gorban
+// Updated specification documentation.
+// Added full 32-bit data bus interface, now as default.
+// Address is 5-bit wide in 32-bit data bus mode.
+// Added wb_sel_i input to the core. It's used in the 32-bit mode.
+// Added debug interface with two 32-bit read-only registers in 32-bit mode.
+// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
+// My small test bench is modified to work with 32-bit mode.
+//
+// Revision 1.8 2001/11/26 21:38:54 gorban
+// Lots of fixes:
+// Break condition wasn't handled correctly at all.
+// LSR bits could lose their values.
+// LSR value after reset was wrong.
+// Timing of THRE interrupt signal corrected.
+// LSR bit 0 timing corrected.
+//
+// Revision 1.7 2001/08/24 21:01:12 mohor
+// Things connected to parity changed.
+// Clock devider changed.
+//
+// Revision 1.6 2001/08/23 16:05:05 mohor
+// Stop bit bug fixed.
+// Parity bug fixed.
+// WISHBONE read cycle bug fixed,
+// OE indicator (Overrun Error) bug fixed.
+// PE indicator (Parity Error) bug fixed.
+// Register read bug fixed.
+//
+// Revision 1.5 2001/05/31 20:08:01 gorban
+// FIFO changes and other corrections.
+//
+// Revision 1.4 2001/05/21 19:12:02 gorban
+// Corrected some Linter messages.
+//
+// Revision 1.3 2001/05/17 18:34:18 gorban
+// First 'stable' release. Should be sythesizable now. Also added new header.
+//
+// Revision 1.0 2001-05-17 21:27:11+02 jacob
+// Initial revision
+//
+//
+
+// remove comments to restore to use the new version with 8 data bit interface
+// in 32bit-bus mode, the wb_sel_i signal is used to put data in correct place
+// also, in 8-bit version there'll be no debugging features included
+// CAUTION: doesn't work with current version of OR1200
+//`define DATA_BUS_WIDTH_8
+
+`ifdef DATA_BUS_WIDTH_8
+ `define UART_ADDR_WIDTH 3
+ `define UART_DATA_WIDTH 8
+`else
+ `define UART_ADDR_WIDTH 5
+ `define UART_DATA_WIDTH 32
+`endif
+
+// Uncomment this if you want your UART to have
+// 16xBaudrate output port.
+// If defined, the enable signal will be used to drive baudrate_o signal
+// It's frequency is 16xbaudrate
+
+// `define UART_HAS_BAUDRATE_OUTPUT
+
+// Register addresses
+`define UART_REG_RB `UART_ADDR_WIDTH'd0 // receiver buffer
+`define UART_REG_TR `UART_ADDR_WIDTH'd0 // transmitter
+`define UART_REG_IE `UART_ADDR_WIDTH'd1 // Interrupt enable
+`define UART_REG_II `UART_ADDR_WIDTH'd2 // Interrupt identification
+`define UART_REG_FC `UART_ADDR_WIDTH'd2 // FIFO control
+`define UART_REG_LC `UART_ADDR_WIDTH'd3 // Line Control
+`define UART_REG_MC `UART_ADDR_WIDTH'd4 // Modem control
+`define UART_REG_LS `UART_ADDR_WIDTH'd5 // Line status
+`define UART_REG_MS `UART_ADDR_WIDTH'd6 // Modem status
+`define UART_REG_SR `UART_ADDR_WIDTH'd7 // Scratch register
+`define UART_REG_DL1 `UART_ADDR_WIDTH'd0 // Divisor latch bytes (1-2)
+`define UART_REG_DL2 `UART_ADDR_WIDTH'd1
+
+// Interrupt Enable register bits
+`define UART_IE_RDA 0 // Received Data available interrupt
+`define UART_IE_THRE 1 // Transmitter Holding Register empty interrupt
+`define UART_IE_RLS 2 // Receiver Line Status Interrupt
+`define UART_IE_MS 3 // Modem Status Interrupt
+
+// Interrupt Identification register bits
+`define UART_II_IP 0 // Interrupt pending when 0
+`define UART_II_II 3:1 // Interrupt identification
+
+// Interrupt identification values for bits 3:1
+`define UART_II_RLS 3'b011 // Receiver Line Status
+`define UART_II_RDA 3'b010 // Receiver Data available
+`define UART_II_TI 3'b110 // Timeout Indication
+`define UART_II_THRE 3'b001 // Transmitter Holding Register empty
+`define UART_II_MS 3'b000 // Modem Status
+
+// FIFO Control Register bits
+`define UART_FC_TL 1:0 // Trigger level
+
+// FIFO trigger level values
+`define UART_FC_1 2'b00
+`define UART_FC_4 2'b01
+`define UART_FC_8 2'b10
+`define UART_FC_14 2'b11
+
+// Line Control register bits
+`define UART_LC_BITS 1:0 // bits in character
+`define UART_LC_SB 2 // stop bits
+`define UART_LC_PE 3 // parity enable
+`define UART_LC_EP 4 // even parity
+`define UART_LC_SP 5 // stick parity
+`define UART_LC_BC 6 // Break control
+`define UART_LC_DL 7 // Divisor Latch access bit
+
+// Modem Control register bits
+`define UART_MC_DTR 0
+`define UART_MC_RTS 1
+`define UART_MC_OUT1 2
+`define UART_MC_OUT2 3
+`define UART_MC_LB 4 // Loopback mode
+
+// Line Status Register bits
+`define UART_LS_DR 0 // Data ready
+`define UART_LS_OE 1 // Overrun Error
+`define UART_LS_PE 2 // Parity Error
+`define UART_LS_FE 3 // Framing Error
+`define UART_LS_BI 4 // Break interrupt
+`define UART_LS_TFE 5 // Transmit FIFO is empty
+`define UART_LS_TE 6 // Transmitter Empty indicator
+`define UART_LS_EI 7 // Error indicator
+
+// Modem Status Register bits
+`define UART_MS_DCTS 0 // Delta signals
+`define UART_MS_DDSR 1
+`define UART_MS_TERI 2
+`define UART_MS_DDCD 3
+`define UART_MS_CCTS 4 // Complement signals
+`define UART_MS_CDSR 5
+`define UART_MS_CRI 6
+`define UART_MS_CDCD 7
+
+// FIFO parameter defines
+
+`define UART_FIFO_WIDTH 8
+`define UART_FIFO_DEPTH 16
+`define UART_FIFO_POINTER_W 4
+`define UART_FIFO_COUNTER_W 5
+// receiver fifo has width 11 because it has break, parity and framing error bits
+`define UART_FIFO_REC_WIDTH 11
+
+
+`define VERBOSE_WB 0 // All activity on the WISHBONE is recorded
+`define VERBOSE_LINE_STATUS 0 // Details about the lsr (line status register)
+`define FAST_TEST 1 // 64/1024 packets are sent
+
+// Added by Revanth to support LITTLE_ENDIAN mode of operation.
+`define LITLE_ENDIAN
+
+
+
+
+
Index: zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_receiver.v
===================================================================
--- zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_receiver.v (nonexistent)
+++ zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_receiver.v (revision 43)
@@ -0,0 +1,481 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// uart_receiver.v ////
+//// ////
+//// ////
+//// This file is part of the "UART 16550 compatible" project ////
+//// http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Documentation related to this project: ////
+//// - http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Projects compatibility: ////
+//// - WISHBONE ////
+//// RS232 Protocol ////
+//// 16550D uart (mostly supported) ////
+//// ////
+//// Overview (main Features): ////
+//// UART core receiver logic ////
+//// ////
+//// Known problems (limits): ////
+//// None known ////
+//// ////
+//// To Do: ////
+//// Thourough testing. ////
+//// ////
+//// Author(s): ////
+//// - gorban@opencores.org ////
+//// - Jacob Gorban ////
+//// - Igor Mohor (igorm@opencores.org) ////
+//// ////
+//// Created: 2001/05/12 ////
+//// Last Updated: 2001/05/17 ////
+//// (See log for the revision history) ////
+//// ////
+//// Modified for use in the ZAP project by Revanth Kamaraj ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000, 2001 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.29 2002/07/29 21:16:18 gorban
+// The uart_defines.v file is included again in sources.
+//
+// Revision 1.28 2002/07/22 23:02:23 gorban
+// Bug Fixes:
+// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
+// Problem reported by Kenny.Tung.
+// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
+//
+// Improvements:
+// * Made FIFO's as general inferrable memory where possible.
+// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
+// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
+//
+// * Added optional baudrate output (baud_o).
+// This is identical to BAUDOUT* signal on 16550 chip.
+// It outputs 16xbit_clock_rate - the divided clock.
+// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
+//
+// Revision 1.27 2001/12/30 20:39:13 mohor
+// More than one character was stored in case of break. End of the break
+// was not detected correctly.
+//
+// Revision 1.26 2001/12/20 13:28:27 mohor
+// Missing declaration of rf_push_q fixed.
+//
+// Revision 1.25 2001/12/20 13:25:46 mohor
+// rx push changed to be only one cycle wide.
+//
+// Revision 1.24 2001/12/19 08:03:34 mohor
+// Warnings cleared.
+//
+// Revision 1.23 2001/12/19 07:33:54 mohor
+// Synplicity was having troubles with the comment.
+//
+// Revision 1.22 2001/12/17 14:46:48 mohor
+// overrun signal was moved to separate block because many sequential lsr
+// reads were preventing data from being written to rx fifo.
+// underrun signal was not used and was removed from the project.
+//
+// Revision 1.21 2001/12/13 10:31:16 mohor
+// timeout irq must be set regardless of the rda irq (rda irq does not reset the
+// timeout counter).
+//
+// Revision 1.20 2001/12/10 19:52:05 gorban
+// Igor fixed break condition bugs
+//
+// Revision 1.19 2001/12/06 14:51:04 gorban
+// Bug in LSR[0] is fixed.
+// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
+//
+// Revision 1.18 2001/12/03 21:44:29 gorban
+// Updated specification documentation.
+// Added full 32-bit data bus interface, now as default.
+// Address is 5-bit wide in 32-bit data bus mode.
+// Added wb_sel_i input to the core. It's used in the 32-bit mode.
+// Added debug interface with two 32-bit read-only registers in 32-bit mode.
+// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
+// My small test bench is modified to work with 32-bit mode.
+//
+// Revision 1.17 2001/11/28 19:36:39 gorban
+// Fixed: timeout and break didn't pay attention to current data format when counting time
+//
+// Revision 1.16 2001/11/27 22:17:09 gorban
+// Fixed bug that prevented synthesis in uart_receiver.v
+//
+// Revision 1.15 2001/11/26 21:38:54 gorban
+// Lots of fixes:
+// Break condition wasn't handled correctly at all.
+// LSR bits could lose their values.
+// LSR value after reset was wrong.
+// Timing of THRE interrupt signal corrected.
+// LSR bit 0 timing corrected.
+//
+// Revision 1.14 2001/11/10 12:43:21 gorban
+// Logic Synthesis bugs fixed. Some other minor changes
+//
+// Revision 1.13 2001/11/08 14:54:23 mohor
+// Comments in Slovene language deleted, few small fixes for better work of
+// old tools. IRQs need to be fix.
+//
+// Revision 1.12 2001/11/07 17:51:52 gorban
+// Heavily rewritten interrupt and LSR subsystems.
+// Many bugs hopefully squashed.
+//
+// Revision 1.11 2001/10/31 15:19:22 gorban
+// Fixes to break and timeout conditions
+//
+// Revision 1.10 2001/10/20 09:58:40 gorban
+// Small synopsis fixes
+//
+// Revision 1.9 2001/08/24 21:01:12 mohor
+// Things connected to parity changed.
+// Clock devider changed.
+//
+// Revision 1.8 2001/08/23 16:05:05 mohor
+// Stop bit bug fixed.
+// Parity bug fixed.
+// WISHBONE read cycle bug fixed,
+// OE indicator (Overrun Error) bug fixed.
+// PE indicator (Parity Error) bug fixed.
+// Register read bug fixed.
+//
+// Revision 1.6 2001/06/23 11:21:48 gorban
+// DL made 16-bit long. Fixed transmission/reception bugs.
+//
+// Revision 1.5 2001/06/02 14:28:14 gorban
+// Fixed receiver and transmitter. Major bug fixed.
+//
+// Revision 1.4 2001/05/31 20:08:01 gorban
+// FIFO changes and other corrections.
+//
+// Revision 1.3 2001/05/27 17:37:49 gorban
+// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
+//
+// Revision 1.2 2001/05/21 19:12:02 gorban
+// Corrected some Linter messages.
+//
+// Revision 1.1 2001/05/17 18:34:18 gorban
+// First 'stable' release. Should be sythesizable now. Also added new header.
+//
+// Revision 1.0 2001-05-17 21:27:11+02 jacob
+// Initial revision
+//
+//
+//// Modified for use in the ZAP project by Revanth Kamaraj ////
+
+
+`include "uart_defines.v"
+
+module uart_receiver (clk, wb_rst_i, lcr, rf_pop, srx_pad_i, enable,
+ counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask, rstate, rf_push_pulse);
+
+input clk;
+input wb_rst_i;
+input [7:0] lcr;
+input rf_pop;
+input srx_pad_i;
+input enable;
+input rx_reset;
+input lsr_mask;
+
+output [9:0] counter_t;
+output [`UART_FIFO_COUNTER_W-1:0] rf_count;
+output [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
+output rf_overrun;
+output rf_error_bit;
+output [3:0] rstate;
+output rf_push_pulse;
+
+reg [3:0] rstate;
+reg [3:0] rcounter16;
+reg [2:0] rbit_counter;
+reg [7:0] rshift; // receiver shift register
+reg rparity; // received parity
+reg rparity_error;
+reg rframing_error; // framing error flag
+reg rbit_in;
+reg rparity_xor;
+reg [7:0] counter_b; // counts the 0 (low) signals
+reg rf_push_q;
+
+// RX FIFO signals
+reg [`UART_FIFO_REC_WIDTH-1:0] rf_data_in;
+wire [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
+wire rf_push_pulse;
+reg rf_push;
+wire rf_pop;
+wire rf_overrun;
+wire [`UART_FIFO_COUNTER_W-1:0] rf_count;
+wire rf_error_bit; // an error (parity or framing) is inside the fifo
+wire break_error = (counter_b == 0);
+
+// RX FIFO instance
+uart_rfifo #(`UART_FIFO_REC_WIDTH) fifo_rx(
+ .clk( clk ),
+ .wb_rst_i( wb_rst_i ),
+ .data_in( rf_data_in ),
+ .data_out( rf_data_out ),
+ .push( rf_push_pulse ),
+ .pop( rf_pop ),
+ .overrun( rf_overrun ),
+ .count( rf_count ),
+ .error_bit( rf_error_bit ),
+ .fifo_reset( rx_reset ),
+ .reset_status(lsr_mask)
+);
+
+wire rcounter16_eq_7 = (rcounter16 == 4'd7);
+wire rcounter16_eq_0 = (rcounter16 == 4'd0);
+wire rcounter16_eq_1 = (rcounter16 == 4'd1);
+
+wire [3:0] rcounter16_minus_1 = rcounter16 - 1'b1;
+
+parameter sr_idle = 4'd0;
+parameter sr_rec_start = 4'd1;
+parameter sr_rec_bit = 4'd2;
+parameter sr_rec_parity = 4'd3;
+parameter sr_rec_stop = 4'd4;
+parameter sr_check_parity = 4'd5;
+parameter sr_rec_prepare = 4'd6;
+parameter sr_end_bit = 4'd7;
+parameter sr_ca_lc_parity = 4'd8;
+parameter sr_wait1 = 4'd9;
+parameter sr_push = 4'd10;
+
+
+always @(posedge clk or posedge wb_rst_i)
+begin
+ if (wb_rst_i)
+ begin
+ rstate <= sr_idle;
+ rbit_in <= 1'b0;
+ rcounter16 <= 0;
+ rbit_counter <= 0;
+ rparity_xor <= 1'b0;
+ rframing_error <= 1'b0;
+ rparity_error <= 1'b0;
+ rparity <= 1'b0;
+ rshift <= 0;
+ rf_push <= 1'b0;
+ rf_data_in <= 0;
+ end
+ else
+ if (enable)
+ begin
+ case (rstate)
+ sr_idle : begin
+ rf_push <= 1'b0;
+ rf_data_in <= 0;
+ rcounter16 <= 4'b1110;
+ if (srx_pad_i==1'b0 & ~break_error) // detected a pulse (start bit?)
+ begin
+ rstate <= sr_rec_start;
+ end
+ end
+ sr_rec_start : begin
+ rf_push <= 1'b0;
+ if (rcounter16_eq_7) // check the pulse
+ if (srx_pad_i==1'b1) // no start bit
+ rstate <= sr_idle;
+ else // start bit detected
+ rstate <= sr_rec_prepare;
+ rcounter16 <= rcounter16_minus_1;
+ end
+ sr_rec_prepare:begin
+ case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word
+ 2'b00 : rbit_counter <= 3'b100;
+ 2'b01 : rbit_counter <= 3'b101;
+ 2'b10 : rbit_counter <= 3'b110;
+ 2'b11 : rbit_counter <= 3'b111;
+ endcase
+ if (rcounter16_eq_0)
+ begin
+ rstate <= sr_rec_bit;
+ rcounter16 <= 4'b1110;
+ rshift <= 0;
+ end
+ else
+ rstate <= sr_rec_prepare;
+ rcounter16 <= rcounter16_minus_1;
+ end
+ sr_rec_bit : begin
+ if (rcounter16_eq_0)
+ rstate <= sr_end_bit;
+ if (rcounter16_eq_7) // read the bit
+ case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word
+ 2'b00 : rshift[4:0] <= {srx_pad_i, rshift[4:1]};
+ 2'b01 : rshift[5:0] <= {srx_pad_i, rshift[5:1]};
+ 2'b10 : rshift[6:0] <= {srx_pad_i, rshift[6:1]};
+ 2'b11 : rshift[7:0] <= {srx_pad_i, rshift[7:1]};
+ endcase
+ rcounter16 <= rcounter16_minus_1;
+ end
+ sr_end_bit : begin
+ if (rbit_counter==3'b0) // no more bits in word
+ if (lcr[`UART_LC_PE]) // choose state based on parity
+ rstate <= sr_rec_parity;
+ else
+ begin
+ rstate <= sr_rec_stop;
+ rparity_error <= 1'b0; // no parity - no error :)
+ end
+ else // else we have more bits to read
+ begin
+ rstate <= sr_rec_bit;
+ rbit_counter <= rbit_counter - 1'b1;
+ end
+ rcounter16 <= 4'b1110;
+ end
+ sr_rec_parity: begin
+ if (rcounter16_eq_7) // read the parity
+ begin
+ rparity <= srx_pad_i;
+ rstate <= sr_ca_lc_parity;
+ end
+ rcounter16 <= rcounter16_minus_1;
+ end
+ sr_ca_lc_parity : begin // rcounter equals 6
+ rcounter16 <= rcounter16_minus_1;
+ rparity_xor <= ^{rshift,rparity}; // calculate parity on all incoming data
+ rstate <= sr_check_parity;
+ end
+ sr_check_parity: begin // rcounter equals 5
+ case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]})
+ 2'b00: rparity_error <= rparity_xor == 0; // no error if parity 1
+ 2'b01: rparity_error <= ~rparity; // parity should sticked to 1
+ 2'b10: rparity_error <= rparity_xor == 1; // error if parity is odd
+ 2'b11: rparity_error <= rparity; // parity should be sticked to 0
+ endcase
+ rcounter16 <= rcounter16_minus_1;
+ rstate <= sr_wait1;
+ end
+ sr_wait1 : if (rcounter16_eq_0)
+ begin
+ rstate <= sr_rec_stop;
+ rcounter16 <= 4'b1110;
+ end
+ else
+ rcounter16 <= rcounter16_minus_1;
+ sr_rec_stop : begin
+ if (rcounter16_eq_7) // read the parity
+ begin
+ rframing_error <= !srx_pad_i; // no framing error if input is 1 (stop bit)
+ rstate <= sr_push;
+ end
+ rcounter16 <= rcounter16_minus_1;
+ end
+ sr_push : begin
+///////////////////////////////////////
+// $display($time, ": received: %b", rf_data_in);
+ if(srx_pad_i | break_error)
+ begin
+ if(break_error)
+ rf_data_in <= {8'b0, 3'b100}; // break input (empty character) to receiver FIFO
+ else
+ rf_data_in <= {rshift, 1'b0, rparity_error, rframing_error};
+ rf_push <= 1'b1;
+ rstate <= sr_idle;
+ end
+ else if(~rframing_error) // There's always a framing before break_error -> wait for break or srx_pad_i
+ begin
+ rf_data_in <= {rshift, 1'b0, rparity_error, rframing_error};
+ rf_push <= 1'b1;
+ rcounter16 <= 4'b1110;
+ rstate <= sr_rec_start;
+ end
+
+ end
+ default : rstate <= sr_idle;
+ endcase
+ end // if (enable)
+end // always of receiver
+
+always @ (posedge clk or posedge wb_rst_i)
+begin
+ if(wb_rst_i)
+ rf_push_q <= 0;
+ else
+ rf_push_q <= rf_push;
+end
+
+assign rf_push_pulse = rf_push & ~rf_push_q;
+
+
+//
+// Break condition detection.
+// Works in conjuction with the receiver state machine
+
+reg [9:0] toc_value; // value to be set to timeout counter
+
+always @(lcr)
+ case (lcr[3:0])
+ 4'b0000 : toc_value = 447; // 7 bits
+ 4'b0100 : toc_value = 479; // 7.5 bits
+ 4'b0001, 4'b1000 : toc_value = 511; // 8 bits
+ 4'b1100 : toc_value = 543; // 8.5 bits
+ 4'b0010, 4'b0101, 4'b1001 : toc_value = 575; // 9 bits
+ 4'b0011, 4'b0110, 4'b1010, 4'b1101 : toc_value = 639; // 10 bits
+ 4'b0111, 4'b1011, 4'b1110 : toc_value = 703; // 11 bits
+ 4'b1111 : toc_value = 767; // 12 bits
+ endcase // case(lcr[3:0])
+
+wire [7:0] brc_value; // value to be set to break counter
+assign brc_value = toc_value[9:2]; // the same as timeout but 1 insead of 4 character times
+
+always @(posedge clk or posedge wb_rst_i)
+begin
+ if (wb_rst_i)
+ counter_b <= 8'd159;
+ else
+ if (srx_pad_i)
+ counter_b <= brc_value; // character time length - 1
+ else
+ if(enable & counter_b != 8'b0) // only work on enable times break not reached.
+ counter_b <= counter_b - 1; // decrement break counter
+end // always of break condition detection
+
+///
+/// Timeout condition detection
+reg [9:0] counter_t; // counts the timeout condition clocks
+
+always @(posedge clk or posedge wb_rst_i)
+begin
+ if (wb_rst_i)
+ counter_t <= 10'd639; // 10 bits for the default 8N1
+ else
+ if(rf_push_pulse || rf_pop || rf_count == 0) // counter is reset when RX FIFO is empty, accessed or above trigger level
+ counter_t <= toc_value;
+ else
+ if (enable && counter_t != 10'b0) // we don't want to underflow
+ counter_t <= counter_t - 1;
+end
+
+endmodule
Index: zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_regs.v
===================================================================
--- zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_regs.v (nonexistent)
+++ zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_regs.v (revision 43)
@@ -0,0 +1,892 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// uart_regs.v ////
+//// ////
+//// ////
+//// This file is part of the "UART 16550 compatible" project ////
+//// http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Documentation related to this project: ////
+//// - http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Projects compatibility: ////
+//// - WISHBONE ////
+//// RS232 Protocol ////
+//// 16550D uart (mostly supported) ////
+//// ////
+//// Overview (main Features): ////
+//// Registers of the uart 16550 core ////
+//// ////
+//// Known problems (limits): ////
+//// Inserts 1 wait state in all WISHBONE transfers ////
+//// ////
+//// To Do: ////
+//// Nothing or verification. ////
+//// ////
+//// Author(s): ////
+//// - gorban@opencores.org ////
+//// - Jacob Gorban ////
+//// - Igor Mohor (igorm@opencores.org) ////
+//// ////
+//// Created: 2001/05/12 ////
+//// Last Updated: (See log for the revision history ////
+//// Modified for use in the ZAP project by Revanth Kamaraj ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000, 2001 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.41 2004/05/21 11:44:41 tadejm
+// Added synchronizer flops for RX input.
+//
+// Revision 1.40 2003/06/11 16:37:47 gorban
+// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
+//
+// Revision 1.39 2002/07/29 21:16:18 gorban
+// The uart_defines.v file is included again in sources.
+//
+// Revision 1.38 2002/07/22 23:02:23 gorban
+// Bug Fixes:
+// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
+// Problem reported by Kenny.Tung.
+// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
+//
+// Improvements:
+// * Made FIFO's as general inferrable memory where possible.
+// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
+// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
+//
+// * Added optional baudrate output (baud_o).
+// This is identical to BAUDOUT* signal on 16550 chip.
+// It outputs 16xbit_clock_rate - the divided clock.
+// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
+//
+// Revision 1.37 2001/12/27 13:24:09 mohor
+// lsr[7] was not showing overrun errors.
+//
+// Revision 1.36 2001/12/20 13:25:46 mohor
+// rx push changed to be only one cycle wide.
+//
+// Revision 1.35 2001/12/19 08:03:34 mohor
+// Warnings cleared.
+//
+// Revision 1.34 2001/12/19 07:33:54 mohor
+// Synplicity was having troubles with the comment.
+//
+// Revision 1.33 2001/12/17 10:14:43 mohor
+// Things related to msr register changed. After THRE IRQ occurs, and one
+// character is written to the transmit fifo, the detection of the THRE bit in the
+// LSR is delayed for one character time.
+//
+// Revision 1.32 2001/12/14 13:19:24 mohor
+// MSR register fixed.
+//
+// Revision 1.31 2001/12/14 10:06:58 mohor
+// After reset modem status register MSR should be reset.
+//
+// Revision 1.30 2001/12/13 10:09:13 mohor
+// thre irq should be cleared only when being source of interrupt.
+//
+// Revision 1.29 2001/12/12 09:05:46 mohor
+// LSR status bit 0 was not cleared correctly in case of reseting the FCR (rx fifo).
+//
+// Revision 1.28 2001/12/10 19:52:41 gorban
+// Scratch register added
+//
+// Revision 1.27 2001/12/06 14:51:04 gorban
+// Bug in LSR[0] is fixed.
+// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
+//
+// Revision 1.26 2001/12/03 21:44:29 gorban
+// Updated specification documentation.
+// Added full 32-bit data bus interface, now as default.
+// Address is 5-bit wide in 32-bit data bus mode.
+// Added wb_sel_i input to the core. It's used in the 32-bit mode.
+// Added debug interface with two 32-bit read-only registers in 32-bit mode.
+// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
+// My small test bench is modified to work with 32-bit mode.
+//
+// Revision 1.25 2001/11/28 19:36:39 gorban
+// Fixed: timeout and break didn't pay attention to current data format when counting time
+//
+// Revision 1.24 2001/11/26 21:38:54 gorban
+// Lots of fixes:
+// Break condition wasn't handled correctly at all.
+// LSR bits could lose their values.
+// LSR value after reset was wrong.
+// Timing of THRE interrupt signal corrected.
+// LSR bit 0 timing corrected.
+//
+// Revision 1.23 2001/11/12 21:57:29 gorban
+// fixed more typo bugs
+//
+// Revision 1.22 2001/11/12 15:02:28 mohor
+// lsr1r error fixed.
+//
+// Revision 1.21 2001/11/12 14:57:27 mohor
+// ti_int_pnd error fixed.
+//
+// Revision 1.20 2001/11/12 14:50:27 mohor
+// ti_int_d error fixed.
+//
+// Revision 1.19 2001/11/10 12:43:21 gorban
+// Logic Synthesis bugs fixed. Some other minor changes
+//
+// Revision 1.18 2001/11/08 14:54:23 mohor
+// Comments in Slovene language deleted, few small fixes for better work of
+// old tools. IRQs need to be fix.
+//
+// Revision 1.17 2001/11/07 17:51:52 gorban
+// Heavily rewritten interrupt and LSR subsystems.
+// Many bugs hopefully squashed.
+//
+// Revision 1.16 2001/11/02 09:55:16 mohor
+// no message
+//
+// Revision 1.15 2001/10/31 15:19:22 gorban
+// Fixes to break and timeout conditions
+//
+// Revision 1.14 2001/10/29 17:00:46 gorban
+// fixed parity sending and tx_fifo resets over- and underrun
+//
+// Revision 1.13 2001/10/20 09:58:40 gorban
+// Small synopsis fixes
+//
+// Revision 1.12 2001/10/19 16:21:40 gorban
+// Changes data_out to be synchronous again as it should have been.
+//
+// Revision 1.11 2001/10/18 20:35:45 gorban
+// small fix
+//
+// Revision 1.10 2001/08/24 21:01:12 mohor
+// Things connected to parity changed.
+// Clock devider changed.
+//
+// Revision 1.9 2001/08/23 16:05:05 mohor
+// Stop bit bug fixed.
+// Parity bug fixed.
+// WISHBONE read cycle bug fixed,
+// OE indicator (Overrun Error) bug fixed.
+// PE indicator (Parity Error) bug fixed.
+// Register read bug fixed.
+//
+// Revision 1.10 2001/06/23 11:21:48 gorban
+// DL made 16-bit long. Fixed transmission/reception bugs.
+//
+// Revision 1.9 2001/05/31 20:08:01 gorban
+// FIFO changes and other corrections.
+//
+// Revision 1.8 2001/05/29 20:05:04 gorban
+// Fixed some bugs and synthesis problems.
+//
+// Revision 1.7 2001/05/27 17:37:49 gorban
+// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
+//
+// Revision 1.6 2001/05/21 19:12:02 gorban
+// Corrected some Linter messages.
+//
+// Revision 1.5 2001/05/17 18:34:18 gorban
+// First 'stable' release. Should be sythesizable now. Also added new header.
+//
+// Revision 1.0 2001-05-17 21:27:11+02 jacob
+// Initial revision
+//
+//
+//// Modified for use in the ZAP project by Revanth Kamaraj ////
+
+
+`include "uart_defines.v"
+
+`define UART_DL1 7:0
+`define UART_DL2 15:8
+
+module uart_regs (clk,
+ wb_rst_i, wb_addr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_re_i,
+
+// additional signals
+ modem_inputs,
+ stx_pad_o, srx_pad_i,
+
+`ifdef DATA_BUS_WIDTH_8
+`else
+// debug interface signals enabled
+ier, iir, fcr, mcr, lcr, msr, lsr, rf_count, tf_count, tstate, rstate,
+`endif
+ rts_pad_o, dtr_pad_o, int_o
+`ifdef UART_HAS_BAUDRATE_OUTPUT
+ , baud_o
+`endif
+
+ );
+
+input clk;
+input wb_rst_i;
+input [`UART_ADDR_WIDTH-1:0] wb_addr_i;
+input [7:0] wb_dat_i;
+output [7:0] wb_dat_o;
+input wb_we_i;
+input wb_re_i;
+
+output stx_pad_o;
+input srx_pad_i;
+
+input [3:0] modem_inputs;
+output rts_pad_o;
+output dtr_pad_o;
+output int_o;
+`ifdef UART_HAS_BAUDRATE_OUTPUT
+output baud_o;
+`endif
+
+`ifdef DATA_BUS_WIDTH_8
+`else
+// if 32-bit databus and debug interface are enabled
+output [3:0] ier;
+output [3:0] iir;
+output [1:0] fcr; /// bits 7 and 6 of fcr. Other bits are ignored
+output [4:0] mcr;
+output [7:0] lcr;
+output [7:0] msr;
+output [7:0] lsr;
+output [`UART_FIFO_COUNTER_W-1:0] rf_count;
+output [`UART_FIFO_COUNTER_W-1:0] tf_count;
+output [2:0] tstate;
+output [3:0] rstate;
+
+`endif
+
+wire [3:0] modem_inputs;
+reg enable;
+`ifdef UART_HAS_BAUDRATE_OUTPUT
+assign baud_o = enable; // baud_o is actually the enable signal
+`endif
+
+
+wire stx_pad_o; // received from transmitter module
+wire srx_pad_i;
+wire srx_pad;
+
+reg [7:0] wb_dat_o;
+
+wire [`UART_ADDR_WIDTH-1:0] wb_addr_i;
+wire [7:0] wb_dat_i;
+
+
+reg [3:0] ier;
+reg [3:0] iir;
+reg [1:0] fcr; /// bits 7 and 6 of fcr. Other bits are ignored
+reg [4:0] mcr;
+reg [7:0] lcr;
+reg [7:0] msr;
+reg [15:0] dl; // 32-bit divisor latch
+reg [7:0] scratch; // UART scratch register
+reg start_dlc; // activate dlc on writing to UART_DL1
+reg lsr_mask_d; // delay for lsr_mask condition
+reg msi_reset; // reset MSR 4 lower bits indicator
+//reg threi_clear; // THRE interrupt clear flag
+reg [15:0] dlc; // 32-bit divisor latch counter
+reg int_o;
+
+reg [3:0] trigger_level; // trigger level of the receiver FIFO
+reg rx_reset;
+reg tx_reset;
+
+wire dlab; // divisor latch access bit
+wire cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i; // modem status bits
+wire loopback; // loopback bit (MCR bit 4)
+wire cts, dsr, ri, dcd; // effective signals
+wire cts_c, dsr_c, ri_c, dcd_c; // Complement effective signals (considering loopback)
+wire rts_pad_o, dtr_pad_o; // modem control outputs
+
+// LSR bits wires and regs
+wire [7:0] lsr;
+wire lsr0, lsr1, lsr2, lsr3, lsr4, lsr5, lsr6, lsr7;
+reg lsr0r, lsr1r, lsr2r, lsr3r, lsr4r, lsr5r, lsr6r, lsr7r;
+wire lsr_mask; // lsr_mask
+
+//
+// ASSINGS
+//
+
+assign lsr[7:0] = { lsr7r, lsr6r, lsr5r, lsr4r, lsr3r, lsr2r, lsr1r, lsr0r };
+
+assign {cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i} = modem_inputs;
+assign {cts, dsr, ri, dcd} = ~{cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
+
+assign {cts_c, dsr_c, ri_c, dcd_c} = loopback ? {mcr[`UART_MC_RTS],mcr[`UART_MC_DTR],mcr[`UART_MC_OUT1],mcr[`UART_MC_OUT2]}
+ : {cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
+
+assign dlab = lcr[`UART_LC_DL];
+assign loopback = mcr[4];
+
+// assign modem outputs
+assign rts_pad_o = mcr[`UART_MC_RTS];
+assign dtr_pad_o = mcr[`UART_MC_DTR];
+
+// Interrupt signals
+wire rls_int; // receiver line status interrupt
+wire rda_int; // receiver data available interrupt
+wire ti_int; // timeout indicator interrupt
+wire thre_int; // transmitter holding register empty interrupt
+wire ms_int; // modem status interrupt
+
+// FIFO signals
+reg tf_push;
+reg rf_pop;
+wire [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
+wire rf_error_bit; // an error (parity or framing) is inside the fifo
+wire [`UART_FIFO_COUNTER_W-1:0] rf_count;
+wire [`UART_FIFO_COUNTER_W-1:0] tf_count;
+wire [2:0] tstate;
+wire [3:0] rstate;
+wire [9:0] counter_t;
+
+wire thre_set_en; // THRE status is delayed one character time when a character is written to fifo.
+reg [7:0] block_cnt; // While counter counts, THRE status is blocked (delayed one character cycle)
+reg [7:0] block_value; // One character length minus stop bit
+
+// Transmitter Instance
+wire serial_out;
+
+uart_transmitter transmitter(clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, serial_out, tstate, tf_count, tx_reset, lsr_mask);
+
+ // Synchronizing and sampling serial RX input
+ uart_sync_flops i_uart_sync_flops
+ (
+ .rst_i (wb_rst_i),
+ .clk_i (clk),
+ .stage1_rst_i (1'b0),
+ .stage1_clk_en_i (1'b1),
+ .async_dat_i (srx_pad_i),
+ .sync_dat_o (srx_pad)
+ );
+ defparam i_uart_sync_flops.width = 1;
+ defparam i_uart_sync_flops.init_value = 1'b1;
+
+// handle loopback
+wire serial_in = loopback ? serial_out : srx_pad;
+assign stx_pad_o = loopback ? 1'b1 : serial_out;
+
+// Receiver Instance
+uart_receiver receiver(clk, wb_rst_i, lcr, rf_pop, serial_in, enable,
+ counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask, rstate, rf_push_pulse);
+
+
+// Asynchronous reading here because the outputs are sampled in uart_wb.v file
+always @(dl or dlab or ier or iir or scratch
+ or lcr or lsr or msr or rf_data_out or wb_addr_i or wb_re_i) // asynchrounous reading
+begin
+ case (wb_addr_i)
+ `UART_REG_RB : wb_dat_o = dlab ? dl[`UART_DL1] : rf_data_out[10:3];
+ `UART_REG_IE : wb_dat_o = dlab ? dl[`UART_DL2] : ier;
+ `UART_REG_II : wb_dat_o = {4'b1100,iir};
+ `UART_REG_LC : wb_dat_o = lcr;
+ `UART_REG_LS : wb_dat_o = lsr;
+ `UART_REG_MS : wb_dat_o = msr;
+ `UART_REG_SR : wb_dat_o = scratch;
+ default: wb_dat_o = 8'b0; // ??
+ endcase // case(wb_addr_i)
+end // always @ (dl or dlab or ier or iir or scratch...
+
+
+// rf_pop signal handling
+always @(posedge clk or posedge wb_rst_i)
+begin
+ if (wb_rst_i)
+ rf_pop <= 0;
+ else
+ if (rf_pop) // restore the signal to 0 after one clock cycle
+ rf_pop <= 0;
+ else
+ if (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab)
+ rf_pop <= 1; // advance read pointer
+end
+
+wire lsr_mask_condition;
+wire iir_read;
+wire msr_read;
+wire fifo_read;
+wire fifo_write;
+
+assign lsr_mask_condition = (wb_re_i && wb_addr_i == `UART_REG_LS && !dlab);
+assign iir_read = (wb_re_i && wb_addr_i == `UART_REG_II && !dlab);
+assign msr_read = (wb_re_i && wb_addr_i == `UART_REG_MS && !dlab);
+assign fifo_read = (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab);
+assign fifo_write = (wb_we_i && wb_addr_i == `UART_REG_TR && !dlab);
+
+// lsr_mask_d delayed signal handling
+always @(posedge clk or posedge wb_rst_i)
+begin
+ if (wb_rst_i)
+ lsr_mask_d <= 0;
+ else // reset bits in the Line Status Register
+ lsr_mask_d <= lsr_mask_condition;
+end
+
+// lsr_mask is rise detected
+assign lsr_mask = lsr_mask_condition && ~lsr_mask_d;
+
+// msi_reset signal handling
+always @(posedge clk or posedge wb_rst_i)
+begin
+ if (wb_rst_i)
+ msi_reset <= 1;
+ else
+ if (msi_reset)
+ msi_reset <= 0;
+ else
+ if (msr_read)
+ msi_reset <= 1; // reset bits in Modem Status Register
+end
+
+
+//
+// WRITES AND RESETS //
+//
+// Line Control Register
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i)
+ lcr <= 8'b00000011; // 8n1 setting
+ else
+ if (wb_we_i && wb_addr_i==`UART_REG_LC)
+ lcr <= wb_dat_i;
+
+// Interrupt Enable Register or UART_DL2
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i)
+ begin
+ ier <= 4'b0000; // no interrupts after reset
+ dl[`UART_DL2] <= 8'b0;
+ end
+ else
+ if (wb_we_i && wb_addr_i==`UART_REG_IE)
+ if (dlab)
+ begin
+ dl[`UART_DL2] <= wb_dat_i;
+ end
+ else
+ ier <= wb_dat_i[3:0]; // ier uses only 4 lsb
+
+
+// FIFO Control Register and rx_reset, tx_reset signals
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) begin
+ fcr <= 2'b11;
+ rx_reset <= 0;
+ tx_reset <= 0;
+ end else
+ if (wb_we_i && wb_addr_i==`UART_REG_FC) begin
+ fcr <= wb_dat_i[7:6];
+ rx_reset <= wb_dat_i[1];
+ tx_reset <= wb_dat_i[2];
+ end else begin
+ rx_reset <= 0;
+ tx_reset <= 0;
+ end
+
+// Modem Control Register
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i)
+ mcr <= 5'b0;
+ else
+ if (wb_we_i && wb_addr_i==`UART_REG_MC)
+ mcr <= wb_dat_i[4:0];
+
+// Scratch register
+// Line Control Register
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i)
+ scratch <= 0; // 8n1 setting
+ else
+ if (wb_we_i && wb_addr_i==`UART_REG_SR)
+ scratch <= wb_dat_i;
+
+// TX_FIFO or UART_DL1
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i)
+ begin
+ dl[`UART_DL1] <= 8'b0;
+ tf_push <= 1'b0;
+ start_dlc <= 1'b0;
+ end
+ else
+ if (wb_we_i && wb_addr_i==`UART_REG_TR)
+ if (dlab)
+ begin
+ dl[`UART_DL1] <= wb_dat_i;
+ start_dlc <= 1'b1; // enable DL counter
+ tf_push <= 1'b0;
+ end
+ else
+ begin
+ tf_push <= 1'b1;
+ start_dlc <= 1'b0;
+ end // else: !if(dlab)
+ else
+ begin
+ start_dlc <= 1'b0;
+ tf_push <= 1'b0;
+ end // else: !if(dlab)
+
+// Receiver FIFO trigger level selection logic (asynchronous mux)
+always @(fcr)
+ case (fcr[`UART_FC_TL])
+ 2'b00 : trigger_level = 1;
+ 2'b01 : trigger_level = 4;
+ 2'b10 : trigger_level = 8;
+ 2'b11 : trigger_level = 14;
+ endcase // case(fcr[`UART_FC_TL])
+
+//
+// STATUS REGISTERS //
+//
+
+// Modem Status Register
+reg [3:0] delayed_modem_signals;
+always @(posedge clk or posedge wb_rst_i)
+begin
+ if (wb_rst_i)
+ begin
+ msr <= 0;
+ delayed_modem_signals[3:0] <= 0;
+ end
+ else begin
+ msr[`UART_MS_DDCD:`UART_MS_DCTS] <= msi_reset ? 4'b0 :
+ msr[`UART_MS_DDCD:`UART_MS_DCTS] | ({dcd, ri, dsr, cts} ^ delayed_modem_signals[3:0]);
+ msr[`UART_MS_CDCD:`UART_MS_CCTS] <= {dcd_c, ri_c, dsr_c, cts_c};
+ delayed_modem_signals[3:0] <= {dcd, ri, dsr, cts};
+ end
+end
+
+
+// Line Status Register
+
+// activation conditions
+assign lsr0 = (rf_count==0 && rf_push_pulse); // data in receiver fifo available set condition
+assign lsr1 = rf_overrun; // Receiver overrun error
+assign lsr2 = rf_data_out[1]; // parity error bit
+assign lsr3 = rf_data_out[0]; // framing error bit
+assign lsr4 = rf_data_out[2]; // break error in the character
+assign lsr5 = (tf_count==5'b0 && thre_set_en); // transmitter fifo is empty
+assign lsr6 = (tf_count==5'b0 && thre_set_en && (tstate == /*`S_IDLE */ 0)); // transmitter empty
+assign lsr7 = rf_error_bit | rf_overrun;
+
+// lsr bit0 (receiver data available)
+reg lsr0_d;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr0_d <= 0;
+ else lsr0_d <= lsr0;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr0r <= 0;
+ else lsr0r <= (rf_count==1 && rf_pop && !rf_push_pulse || rx_reset) ? 0 : // deassert condition
+ lsr0r || (lsr0 && ~lsr0_d); // set on rise of lsr0 and keep asserted until deasserted
+
+// lsr bit 1 (receiver overrun)
+reg lsr1_d; // delayed
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr1_d <= 0;
+ else lsr1_d <= lsr1;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr1r <= 0;
+ else lsr1r <= lsr_mask ? 0 : lsr1r || (lsr1 && ~lsr1_d); // set on rise
+
+// lsr bit 2 (parity error)
+reg lsr2_d; // delayed
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr2_d <= 0;
+ else lsr2_d <= lsr2;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr2r <= 0;
+ else lsr2r <= lsr_mask ? 0 : lsr2r || (lsr2 && ~lsr2_d); // set on rise
+
+// lsr bit 3 (framing error)
+reg lsr3_d; // delayed
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr3_d <= 0;
+ else lsr3_d <= lsr3;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr3r <= 0;
+ else lsr3r <= lsr_mask ? 0 : lsr3r || (lsr3 && ~lsr3_d); // set on rise
+
+// lsr bit 4 (break indicator)
+reg lsr4_d; // delayed
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr4_d <= 0;
+ else lsr4_d <= lsr4;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr4r <= 0;
+ else lsr4r <= lsr_mask ? 0 : lsr4r || (lsr4 && ~lsr4_d);
+
+// lsr bit 5 (transmitter fifo is empty)
+reg lsr5_d;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr5_d <= 1;
+ else lsr5_d <= lsr5;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr5r <= 1;
+ else lsr5r <= (fifo_write) ? 0 : lsr5r || (lsr5 && ~lsr5_d);
+
+// lsr bit 6 (transmitter empty indicator)
+reg lsr6_d;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr6_d <= 1;
+ else lsr6_d <= lsr6;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr6r <= 1;
+ else lsr6r <= (fifo_write) ? 0 : lsr6r || (lsr6 && ~lsr6_d);
+
+// lsr bit 7 (error in fifo)
+reg lsr7_d;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr7_d <= 0;
+ else lsr7_d <= lsr7;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) lsr7r <= 0;
+ else lsr7r <= lsr_mask ? 0 : lsr7r || (lsr7 && ~lsr7_d);
+
+// Frequency divider
+always @(posedge clk or posedge wb_rst_i)
+begin
+ if (wb_rst_i)
+ dlc <= 0;
+ else
+ if (start_dlc | ~ (|dlc))
+ dlc <= dl - 1; // preset counter
+ else
+ dlc <= dlc - 1; // decrement counter
+end
+
+// Enable signal generation logic
+always @(posedge clk or posedge wb_rst_i)
+begin
+ if (wb_rst_i)
+ enable <= 1'b0;
+ else
+ if (|dl & ~(|dlc)) // dl>0 & dlc==0
+ enable <= 1'b1;
+ else
+ enable <= 1'b0;
+end
+
+// Delaying THRE status for one character cycle after a character is written to an empty fifo.
+always @(lcr)
+ case (lcr[3:0])
+ 4'b0000 : block_value = 95; // 6 bits
+ 4'b0100 : block_value = 103; // 6.5 bits
+ 4'b0001, 4'b1000 : block_value = 111; // 7 bits
+ 4'b1100 : block_value = 119; // 7.5 bits
+ 4'b0010, 4'b0101, 4'b1001 : block_value = 127; // 8 bits
+ 4'b0011, 4'b0110, 4'b1010, 4'b1101 : block_value = 143; // 9 bits
+ 4'b0111, 4'b1011, 4'b1110 : block_value = 159; // 10 bits
+ 4'b1111 : block_value = 175; // 11 bits
+ endcase // case(lcr[3:0])
+
+// Counting time of one character minus stop bit
+always @(posedge clk or posedge wb_rst_i)
+begin
+ if (wb_rst_i)
+ block_cnt <= 8'd0;
+ else
+ if(lsr5r & fifo_write) // THRE bit set & write to fifo occured
+ block_cnt <= block_value;
+ else
+ if (enable & block_cnt != 8'b0) // only work on enable times
+ block_cnt <= block_cnt - 1; // decrement break counter
+end // always of break condition detection
+
+// Generating THRE status enable signal
+assign thre_set_en = ~(|block_cnt);
+
+
+//
+// INTERRUPT LOGIC
+//
+
+assign rls_int = ier[`UART_IE_RLS] && (lsr[`UART_LS_OE] || lsr[`UART_LS_PE] || lsr[`UART_LS_FE] || lsr[`UART_LS_BI]);
+assign rda_int = ier[`UART_IE_RDA] && (rf_count >= {1'b0,trigger_level});
+assign thre_int = ier[`UART_IE_THRE] && lsr[`UART_LS_TFE];
+assign ms_int = ier[`UART_IE_MS] && (| msr[3:0]);
+assign ti_int = ier[`UART_IE_RDA] && (counter_t == 10'b0) && (|rf_count);
+
+reg rls_int_d;
+reg thre_int_d;
+reg ms_int_d;
+reg ti_int_d;
+reg rda_int_d;
+
+// delay lines
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) rls_int_d <= 0;
+ else rls_int_d <= rls_int;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) rda_int_d <= 0;
+ else rda_int_d <= rda_int;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) thre_int_d <= 0;
+ else thre_int_d <= thre_int;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) ms_int_d <= 0;
+ else ms_int_d <= ms_int;
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) ti_int_d <= 0;
+ else ti_int_d <= ti_int;
+
+// rise detection signals
+
+wire rls_int_rise;
+wire thre_int_rise;
+wire ms_int_rise;
+wire ti_int_rise;
+wire rda_int_rise;
+
+assign rda_int_rise = rda_int & ~rda_int_d;
+assign rls_int_rise = rls_int & ~rls_int_d;
+assign thre_int_rise = thre_int & ~thre_int_d;
+assign ms_int_rise = ms_int & ~ms_int_d;
+assign ti_int_rise = ti_int & ~ti_int_d;
+
+// interrupt pending flags
+reg rls_int_pnd;
+reg rda_int_pnd;
+reg thre_int_pnd;
+reg ms_int_pnd;
+reg ti_int_pnd;
+
+// interrupt pending flags assignments
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) rls_int_pnd <= 0;
+ else
+ rls_int_pnd <= lsr_mask ? 0 : // reset condition
+ rls_int_rise ? 1 : // latch condition
+ rls_int_pnd && ier[`UART_IE_RLS]; // default operation: remove if masked
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) rda_int_pnd <= 0;
+ else
+ rda_int_pnd <= ((rf_count == {1'b0,trigger_level}) && fifo_read) ? 0 : // reset condition
+ rda_int_rise ? 1 : // latch condition
+ rda_int_pnd && ier[`UART_IE_RDA]; // default operation: remove if masked
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) thre_int_pnd <= 0;
+ else
+ thre_int_pnd <= fifo_write || (iir_read & ~iir[`UART_II_IP] & iir[`UART_II_II] == `UART_II_THRE)? 0 :
+ thre_int_rise ? 1 :
+ thre_int_pnd && ier[`UART_IE_THRE];
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) ms_int_pnd <= 0;
+ else
+ ms_int_pnd <= msr_read ? 0 :
+ ms_int_rise ? 1 :
+ ms_int_pnd && ier[`UART_IE_MS];
+
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) ti_int_pnd <= 0;
+ else
+ ti_int_pnd <= fifo_read ? 0 :
+ ti_int_rise ? 1 :
+ ti_int_pnd && ier[`UART_IE_RDA];
+// end of pending flags
+
+// INT_O logic
+always @(posedge clk or posedge wb_rst_i)
+begin
+ if (wb_rst_i)
+ int_o <= 1'b0;
+ else
+ int_o <=
+ rls_int_pnd ? ~lsr_mask :
+ rda_int_pnd ? 1 :
+ ti_int_pnd ? ~fifo_read :
+ thre_int_pnd ? !(fifo_write & iir_read) :
+ ms_int_pnd ? ~msr_read :
+ 0; // if no interrupt are pending
+end
+
+
+// Interrupt Identification register
+always @(posedge clk or posedge wb_rst_i)
+begin
+ if (wb_rst_i)
+ iir <= 1;
+ else
+ if (rls_int_pnd) // interrupt is pending
+ begin
+ iir[`UART_II_II] <= `UART_II_RLS; // set identification register to correct value
+ iir[`UART_II_IP] <= 1'b0; // and clear the IIR bit 0 (interrupt pending)
+ end else // the sequence of conditions determines priority of interrupt identification
+ if (rda_int)
+ begin
+ iir[`UART_II_II] <= `UART_II_RDA;
+ iir[`UART_II_IP] <= 1'b0;
+ end
+ else if (ti_int_pnd)
+ begin
+ iir[`UART_II_II] <= `UART_II_TI;
+ iir[`UART_II_IP] <= 1'b0;
+ end
+ else if (thre_int_pnd)
+ begin
+ iir[`UART_II_II] <= `UART_II_THRE;
+ iir[`UART_II_IP] <= 1'b0;
+ end
+ else if (ms_int_pnd)
+ begin
+ iir[`UART_II_II] <= `UART_II_MS;
+ iir[`UART_II_IP] <= 1'b0;
+ end else // no interrupt is pending
+ begin
+ iir[`UART_II_II] <= 0;
+ iir[`UART_II_IP] <= 1'b1;
+ end
+end
+
+endmodule
Index: zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_rfifo.v
===================================================================
--- zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_rfifo.v (nonexistent)
+++ zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_rfifo.v (revision 43)
@@ -0,0 +1,318 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// uart_rfifo.v (Modified from uart_fifo.v) ////
+//// ////
+//// ////
+//// This file is part of the "UART 16550 compatible" project ////
+//// http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Documentation related to this project: ////
+//// - http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Projects compatibility: ////
+//// - WISHBONE ////
+//// RS232 Protocol ////
+//// 16550D uart (mostly supported) ////
+//// ////
+//// Overview (main Features): ////
+//// UART core receiver FIFO ////
+//// ////
+//// To Do: ////
+//// Nothing. ////
+//// ////
+//// Author(s): ////
+//// - gorban@opencores.org ////
+//// - Jacob Gorban ////
+//// - Igor Mohor (igorm@opencores.org) ////
+//// ////
+//// Created: 2001/05/12 ////
+//// Last Updated: 2002/07/22 ////
+//// (See log for the revision history) ////
+//// ////
+//// Modified for use in the ZAP project by Revanth Kamaraj ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000, 2001 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.3 2003/06/11 16:37:47 gorban
+// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
+//
+// Revision 1.2 2002/07/29 21:16:18 gorban
+// The uart_defines.v file is included again in sources.
+//
+// Revision 1.1 2002/07/22 23:02:23 gorban
+// Bug Fixes:
+// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
+// Problem reported by Kenny.Tung.
+// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
+//
+// Improvements:
+// * Made FIFO's as general inferrable memory where possible.
+// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
+// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
+//
+// * Added optional baudrate output (baud_o).
+// This is identical to BAUDOUT* signal on 16550 chip.
+// It outputs 16xbit_clock_rate - the divided clock.
+// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
+//
+// Revision 1.16 2001/12/20 13:25:46 mohor
+// rx push changed to be only one cycle wide.
+//
+// Revision 1.15 2001/12/18 09:01:07 mohor
+// Bug that was entered in the last update fixed (rx state machine).
+//
+// Revision 1.14 2001/12/17 14:46:48 mohor
+// overrun signal was moved to separate block because many sequential lsr
+// reads were preventing data from being written to rx fifo.
+// underrun signal was not used and was removed from the project.
+//
+// Revision 1.13 2001/11/26 21:38:54 gorban
+// Lots of fixes:
+// Break condition wasn't handled correctly at all.
+// LSR bits could lose their values.
+// LSR value after reset was wrong.
+// Timing of THRE interrupt signal corrected.
+// LSR bit 0 timing corrected.
+//
+// Revision 1.12 2001/11/08 14:54:23 mohor
+// Comments in Slovene language deleted, few small fixes for better work of
+// old tools. IRQs need to be fix.
+//
+// Revision 1.11 2001/11/07 17:51:52 gorban
+// Heavily rewritten interrupt and LSR subsystems.
+// Many bugs hopefully squashed.
+//
+// Revision 1.10 2001/10/20 09:58:40 gorban
+// Small synopsis fixes
+//
+// Revision 1.9 2001/08/24 21:01:12 mohor
+// Things connected to parity changed.
+// Clock devider changed.
+//
+// Revision 1.8 2001/08/24 08:48:10 mohor
+// FIFO was not cleared after the data was read bug fixed.
+//
+// Revision 1.7 2001/08/23 16:05:05 mohor
+// Stop bit bug fixed.
+// Parity bug fixed.
+// WISHBONE read cycle bug fixed,
+// OE indicator (Overrun Error) bug fixed.
+// PE indicator (Parity Error) bug fixed.
+// Register read bug fixed.
+//
+// Revision 1.3 2001/05/31 20:08:01 gorban
+// FIFO changes and other corrections.
+//
+// Revision 1.3 2001/05/27 17:37:48 gorban
+// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
+//
+// Revision 1.2 2001/05/17 18:34:18 gorban
+// First 'stable' release. Should be sythesizable now. Also added new header.
+//
+// Revision 1.0 2001-05-17 21:27:12+02 jacob
+// Initial revision
+//
+//
+
+
+`include "uart_defines.v"
+
+module uart_rfifo (clk,
+ wb_rst_i, data_in, data_out,
+// Control signals
+ push, // push strobe, active high
+ pop, // pop strobe, active high
+// status signals
+ overrun,
+ count,
+ error_bit,
+ fifo_reset,
+ reset_status
+ );
+
+
+// FIFO parameters
+parameter fifo_width = `UART_FIFO_WIDTH;
+parameter fifo_depth = `UART_FIFO_DEPTH;
+parameter fifo_pointer_w = `UART_FIFO_POINTER_W;
+parameter fifo_counter_w = `UART_FIFO_COUNTER_W;
+
+input clk;
+input wb_rst_i;
+input push;
+input pop;
+input [fifo_width-1:0] data_in;
+input fifo_reset;
+input reset_status;
+
+output [fifo_width-1:0] data_out;
+output overrun;
+output [fifo_counter_w-1:0] count;
+output error_bit;
+
+wire [fifo_width-1:0] data_out;
+wire [7:0] data8_out;
+// flags FIFO
+reg [2:0] fifo[fifo_depth-1:0];
+
+// FIFO pointers
+reg [fifo_pointer_w-1:0] top;
+reg [fifo_pointer_w-1:0] bottom;
+
+reg [fifo_counter_w-1:0] count;
+reg overrun;
+
+wire [fifo_pointer_w-1:0] top_plus_1 = top + 1'b1;
+
+raminfr #(fifo_pointer_w,8,fifo_depth) rfifo
+ (.clk(clk),
+ .we(push),
+ .a(top),
+ .dpra(bottom),
+ .di(data_in[fifo_width-1:fifo_width-8]),
+ .dpo(data8_out)
+ );
+
+always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
+begin
+ if (wb_rst_i)
+ begin
+ top <= 0;
+ bottom <= 1'b0;
+ count <= 0;
+ fifo[0] <= 0;
+ fifo[1] <= 0;
+ fifo[2] <= 0;
+ fifo[3] <= 0;
+ fifo[4] <= 0;
+ fifo[5] <= 0;
+ fifo[6] <= 0;
+ fifo[7] <= 0;
+ fifo[8] <= 0;
+ fifo[9] <= 0;
+ fifo[10] <= 0;
+ fifo[11] <= 0;
+ fifo[12] <= 0;
+ fifo[13] <= 0;
+ fifo[14] <= 0;
+ fifo[15] <= 0;
+ end
+ else
+ if (fifo_reset) begin
+ top <= 0;
+ bottom <= 1'b0;
+ count <= 0;
+ fifo[0] <= 0;
+ fifo[1] <= 0;
+ fifo[2] <= 0;
+ fifo[3] <= 0;
+ fifo[4] <= 0;
+ fifo[5] <= 0;
+ fifo[6] <= 0;
+ fifo[7] <= 0;
+ fifo[8] <= 0;
+ fifo[9] <= 0;
+ fifo[10] <= 0;
+ fifo[11] <= 0;
+ fifo[12] <= 0;
+ fifo[13] <= 0;
+ fifo[14] <= 0;
+ fifo[15] <= 0;
+ end
+ else
+ begin
+ case ({push, pop})
+ 2'b10 : if (count0)
+ begin
+ fifo[bottom] <= 0;
+ bottom <= bottom + 1'b1;
+ count <= count - 1'b1;
+ end
+ 2'b11 : begin
+ bottom <= bottom + 1'b1;
+ top <= top_plus_1;
+ fifo[top] <= data_in[2:0];
+ end
+ default: ;
+ endcase
+ end
+end // always
+
+always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
+begin
+ if (wb_rst_i)
+ overrun <= 1'b0;
+ else
+ if(fifo_reset | reset_status)
+ overrun <= 1'b0;
+ else
+ if(push & ~pop & (count==fifo_depth))
+ overrun <= 1'b1;
+end // always
+
+
+// please note though that data_out is only valid one clock after pop signal
+assign data_out = {data8_out,fifo[bottom]};
+
+// Additional logic for detection of error conditions (parity and framing) inside the FIFO
+// for the Line Status Register bit 7
+
+wire [2:0] word0 = fifo[0];
+wire [2:0] word1 = fifo[1];
+wire [2:0] word2 = fifo[2];
+wire [2:0] word3 = fifo[3];
+wire [2:0] word4 = fifo[4];
+wire [2:0] word5 = fifo[5];
+wire [2:0] word6 = fifo[6];
+wire [2:0] word7 = fifo[7];
+
+wire [2:0] word8 = fifo[8];
+wire [2:0] word9 = fifo[9];
+wire [2:0] word10 = fifo[10];
+wire [2:0] word11 = fifo[11];
+wire [2:0] word12 = fifo[12];
+wire [2:0] word13 = fifo[13];
+wire [2:0] word14 = fifo[14];
+wire [2:0] word15 = fifo[15];
+
+// a 1 is returned if any of the error bits in the fifo is 1
+assign error_bit = |(word0[2:0] | word1[2:0] | word2[2:0] | word3[2:0] |
+ word4[2:0] | word5[2:0] | word6[2:0] | word7[2:0] |
+ word8[2:0] | word9[2:0] | word10[2:0] | word11[2:0] |
+ word12[2:0] | word13[2:0] | word14[2:0] | word15[2:0] );
+
+endmodule
Index: zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_sync_flops.v
===================================================================
--- zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_sync_flops.v (nonexistent)
+++ zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_sync_flops.v (revision 43)
@@ -0,0 +1,122 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// uart_sync_flops.v ////
+//// ////
+//// ////
+//// This file is part of the "UART 16550 compatible" project ////
+//// http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Documentation related to this project: ////
+//// - http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Projects compatibility: ////
+//// - WISHBONE ////
+//// RS232 Protocol ////
+//// 16550D uart (mostly supported) ////
+//// ////
+//// Overview (main Features): ////
+//// UART core receiver logic ////
+//// ////
+//// Known problems (limits): ////
+//// None known ////
+//// ////
+//// To Do: ////
+//// Thourough testing. ////
+//// ////
+//// Author(s): ////
+//// - Andrej Erzen (andreje@flextronics.si) ////
+//// - Tadej Markovic (tadejm@flextronics.si) ////
+//// ////
+//// Created: 2004/05/20 ////
+//// Last Updated: 2004/05/20 ////
+//// (See log for the revision history) ////
+//// Modified for use in the ZAP project by Revanth Kamaraj ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000, 2001 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+//
+
+
+
+
+module uart_sync_flops
+(
+ // internal signals
+ rst_i,
+ clk_i,
+ stage1_rst_i,
+ stage1_clk_en_i,
+ async_dat_i,
+ sync_dat_o
+);
+
+parameter Tp = 1;
+parameter width = 1;
+parameter init_value = 1'b0;
+
+input rst_i; // reset input
+input clk_i; // clock input
+input stage1_rst_i; // synchronous reset for stage 1 FF
+input stage1_clk_en_i; // synchronous clock enable for stage 1 FF
+input [width-1:0] async_dat_i; // asynchronous data input
+output [width-1:0] sync_dat_o; // synchronous data output
+
+
+//
+// Interal signal declarations
+//
+
+reg [width-1:0] sync_dat_o;
+reg [width-1:0] flop_0;
+
+
+// first stage
+always @ (posedge clk_i or posedge rst_i)
+begin
+ if (rst_i)
+ flop_0 <= #Tp {width{init_value}};
+ else
+ flop_0 <= #Tp async_dat_i;
+end
+
+// second stage
+always @ (posedge clk_i or posedge rst_i)
+begin
+ if (rst_i)
+ sync_dat_o <= #Tp {width{init_value}};
+ else if (stage1_rst_i)
+ sync_dat_o <= #Tp {width{init_value}};
+ else if (stage1_clk_en_i)
+ sync_dat_o <= #Tp flop_0;
+end
+
+endmodule
Index: zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_tfifo.v
===================================================================
--- zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_tfifo.v (nonexistent)
+++ zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_tfifo.v (revision 43)
@@ -0,0 +1,241 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// uart_tfifo.v ////
+//// ////
+//// ////
+//// This file is part of the "UART 16550 compatible" project ////
+//// http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Documentation related to this project: ////
+//// - http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Projects compatibility: ////
+//// - WISHBONE ////
+//// RS232 Protocol ////
+//// 16550D uart (mostly supported) ////
+//// ////
+//// Overview (main Features): ////
+//// UART core transmitter FIFO ////
+//// ////
+//// To Do: ////
+//// Nothing. ////
+//// ////
+//// Author(s): ////
+//// - gorban@opencores.org ////
+//// - Jacob Gorban ////
+//// - Igor Mohor (igorm@opencores.org) ////
+//// ////
+//// Created: 2001/05/12 ////
+//// Last Updated: 2002/07/22 ////
+//// (See log for the revision history) ////
+//// Modified for use in the ZAP project by Revanth Kamaraj ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000, 2001 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.1 2002/07/22 23:02:23 gorban
+// Bug Fixes:
+// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
+// Problem reported by Kenny.Tung.
+// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
+//
+// Improvements:
+// * Made FIFO's as general inferrable memory where possible.
+// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
+// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
+//
+// * Added optional baudrate output (baud_o).
+// This is identical to BAUDOUT* signal on 16550 chip.
+// It outputs 16xbit_clock_rate - the divided clock.
+// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
+//
+// Revision 1.16 2001/12/20 13:25:46 mohor
+// rx push changed to be only one cycle wide.
+//
+// Revision 1.15 2001/12/18 09:01:07 mohor
+// Bug that was entered in the last update fixed (rx state machine).
+//
+// Revision 1.14 2001/12/17 14:46:48 mohor
+// overrun signal was moved to separate block because many sequential lsr
+// reads were preventing data from being written to rx fifo.
+// underrun signal was not used and was removed from the project.
+//
+// Revision 1.13 2001/11/26 21:38:54 gorban
+// Lots of fixes:
+// Break condition wasn't handled correctly at all.
+// LSR bits could lose their values.
+// LSR value after reset was wrong.
+// Timing of THRE interrupt signal corrected.
+// LSR bit 0 timing corrected.
+//
+// Revision 1.12 2001/11/08 14:54:23 mohor
+// Comments in Slovene language deleted, few small fixes for better work of
+// old tools. IRQs need to be fix.
+//
+// Revision 1.11 2001/11/07 17:51:52 gorban
+// Heavily rewritten interrupt and LSR subsystems.
+// Many bugs hopefully squashed.
+//
+// Revision 1.10 2001/10/20 09:58:40 gorban
+// Small synopsis fixes
+//
+// Revision 1.9 2001/08/24 21:01:12 mohor
+// Things connected to parity changed.
+// Clock devider changed.
+//
+// Revision 1.8 2001/08/24 08:48:10 mohor
+// FIFO was not cleared after the data was read bug fixed.
+//
+// Revision 1.7 2001/08/23 16:05:05 mohor
+// Stop bit bug fixed.
+// Parity bug fixed.
+// WISHBONE read cycle bug fixed,
+// OE indicator (Overrun Error) bug fixed.
+// PE indicator (Parity Error) bug fixed.
+// Register read bug fixed.
+//
+// Revision 1.3 2001/05/31 20:08:01 gorban
+// FIFO changes and other corrections.
+//
+// Revision 1.3 2001/05/27 17:37:48 gorban
+// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
+//
+// Revision 1.2 2001/05/17 18:34:18 gorban
+// First 'stable' release. Should be sythesizable now. Also added new header.
+//
+// Revision 1.0 2001-05-17 21:27:12+02 jacob
+// Initial revision
+//
+//
+
+
+`include "uart_defines.v"
+
+module uart_tfifo (clk,
+ wb_rst_i, data_in, data_out,
+// Control signals
+ push, // push strobe, active high
+ pop, // pop strobe, active high
+// status signals
+ overrun,
+ count,
+ fifo_reset,
+ reset_status
+ );
+
+
+// FIFO parameters
+parameter fifo_width = `UART_FIFO_WIDTH;
+parameter fifo_depth = `UART_FIFO_DEPTH;
+parameter fifo_pointer_w = `UART_FIFO_POINTER_W;
+parameter fifo_counter_w = `UART_FIFO_COUNTER_W;
+
+input clk;
+input wb_rst_i;
+input push;
+input pop;
+input [fifo_width-1:0] data_in;
+input fifo_reset;
+input reset_status;
+
+output [fifo_width-1:0] data_out;
+output overrun;
+output [fifo_counter_w-1:0] count;
+
+wire [fifo_width-1:0] data_out;
+
+// FIFO pointers
+reg [fifo_pointer_w-1:0] top;
+reg [fifo_pointer_w-1:0] bottom;
+
+reg [fifo_counter_w-1:0] count;
+reg overrun;
+wire [fifo_pointer_w-1:0] top_plus_1 = top + 1'b1;
+
+raminfr #(fifo_pointer_w,fifo_width,fifo_depth) tfifo
+ (.clk(clk),
+ .we(push),
+ .a(top),
+ .dpra(bottom),
+ .di(data_in),
+ .dpo(data_out)
+ );
+
+
+always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
+begin
+ if (wb_rst_i)
+ begin
+ top <= 0;
+ bottom <= 1'b0;
+ count <= 0;
+ end
+ else
+ if (fifo_reset) begin
+ top <= 0;
+ bottom <= 1'b0;
+ count <= 0;
+ end
+ else
+ begin
+ case ({push, pop})
+ 2'b10 : if (count0)
+ begin
+ bottom <= bottom + 1'b1;
+ count <= count - 1'b1;
+ end
+ 2'b11 : begin
+ bottom <= bottom + 1'b1;
+ top <= top_plus_1;
+ end
+ default: ;
+ endcase
+ end
+end // always
+
+always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
+begin
+ if (wb_rst_i)
+ overrun <= 1'b0;
+ else
+ if(fifo_reset | reset_status)
+ overrun <= 1'b0;
+ else
+ if(push & (count==fifo_depth))
+ overrun <= 1'b1;
+end // always
+
+endmodule
Index: zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_top.v
===================================================================
--- zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_top.v (nonexistent)
+++ zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_top.v (revision 43)
@@ -0,0 +1,338 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// uart_top.v ////
+//// ////
+//// ////
+//// This file is part of the "UART 16550 compatible" project ////
+//// http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Documentation related to this project: ////
+//// - http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Projects compatibility: ////
+//// - WISHBONE ////
+//// RS232 Protocol ////
+//// 16550D uart (mostly supported) ////
+//// ////
+//// Overview (main Features): ////
+//// UART core top level. ////
+//// ////
+//// Known problems (limits): ////
+//// Note that transmitter and receiver instances are inside ////
+//// the uart_regs.v file. ////
+//// ////
+//// To Do: ////
+//// Nothing so far. ////
+//// ////
+//// Author(s): ////
+//// - gorban@opencores.org ////
+//// - Jacob Gorban ////
+//// - Igor Mohor (igorm@opencores.org) ////
+//// ////
+//// Created: 2001/05/12 ////
+//// Last Updated: 2001/05/17 ////
+//// (See log for the revision history) ////
+//// ////
+//// Modified for use in the ZAP project by Revanth Kamaraj ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000, 2001 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.18 2002/07/22 23:02:23 gorban
+// Bug Fixes:
+// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
+// Problem reported by Kenny.Tung.
+// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
+//
+// Improvements:
+// * Made FIFO's as general inferrable memory where possible.
+// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
+// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
+//
+// * Added optional baudrate output (baud_o).
+// This is identical to BAUDOUT* signal on 16550 chip.
+// It outputs 16xbit_clock_rate - the divided clock.
+// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
+//
+// Revision 1.17 2001/12/19 08:40:03 mohor
+// Warnings fixed (unused signals removed).
+//
+// Revision 1.16 2001/12/06 14:51:04 gorban
+// Bug in LSR[0] is fixed.
+// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
+//
+// Revision 1.15 2001/12/03 21:44:29 gorban
+// Updated specification documentation.
+// Added full 32-bit data bus interface, now as default.
+// Address is 5-bit wide in 32-bit data bus mode.
+// Added wb_sel_i input to the core. It's used in the 32-bit mode.
+// Added debug interface with two 32-bit read-only registers in 32-bit mode.
+// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
+// My small test bench is modified to work with 32-bit mode.
+//
+// Revision 1.14 2001/11/07 17:51:52 gorban
+// Heavily rewritten interrupt and LSR subsystems.
+// Many bugs hopefully squashed.
+//
+// Revision 1.13 2001/10/20 09:58:40 gorban
+// Small synopsis fixes
+//
+// Revision 1.12 2001/08/25 15:46:19 gorban
+// Modified port names again
+//
+// Revision 1.11 2001/08/24 21:01:12 mohor
+// Things connected to parity changed.
+// Clock devider changed.
+//
+// Revision 1.10 2001/08/23 16:05:05 mohor
+// Stop bit bug fixed.
+// Parity bug fixed.
+// WISHBONE read cycle bug fixed,
+// OE indicator (Overrun Error) bug fixed.
+// PE indicator (Parity Error) bug fixed.
+// Register read bug fixed.
+//
+// Revision 1.4 2001/05/31 20:08:01 gorban
+// FIFO changes and other corrections.
+//
+// Revision 1.3 2001/05/21 19:12:02 gorban
+// Corrected some Linter messages.
+//
+// Revision 1.2 2001/05/17 18:34:18 gorban
+// First 'stable' release. Should be sythesizable now. Also added new header.
+//
+// Revision 1.0 2001-05-17 21:27:12+02 jacob
+// Initial revision
+//
+//
+
+`include "uart_defines.v"
+
+module uart_top (
+ wb_clk_i,
+
+ // Wishbone signals
+ wb_rst_i, wb_adr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_sel_i,
+ int_o, // interrupt request
+
+ // UART signals
+ // serial input/output
+ stx_pad_o, srx_pad_i,
+
+ // modem signals
+ rts_pad_o, cts_pad_i, dtr_pad_o, dsr_pad_i, ri_pad_i, dcd_pad_i
+`ifdef UART_HAS_BAUDRATE_OUTPUT
+ , baud_o
+`endif
+ );
+
+parameter uart_data_width = `UART_DATA_WIDTH;
+parameter uart_addr_width = `UART_ADDR_WIDTH;
+
+input wb_clk_i;
+
+// WISHBONE interface
+input wb_rst_i;
+input [uart_addr_width-1:0] wb_adr_i;
+input [uart_data_width-1:0] wb_dat_i;
+output [uart_data_width-1:0] wb_dat_o;
+input wb_we_i;
+input wb_stb_i;
+input wb_cyc_i;
+input [3:0] wb_sel_i;
+output wb_ack_o;
+output int_o;
+
+// UART signals
+input srx_pad_i;
+output stx_pad_o;
+output rts_pad_o;
+input cts_pad_i;
+output dtr_pad_o;
+input dsr_pad_i;
+input ri_pad_i;
+input dcd_pad_i;
+
+// optional baudrate output
+`ifdef UART_HAS_BAUDRATE_OUTPUT
+output baud_o;
+`endif
+
+
+wire stx_pad_o;
+wire rts_pad_o;
+wire dtr_pad_o;
+
+wire [uart_addr_width-1:0] wb_adr_i;
+wire [uart_data_width-1:0] wb_dat_i;
+wire [uart_data_width-1:0] wb_dat_o;
+
+wire [7:0] wb_dat8_i; // 8-bit internal data input
+wire [7:0] wb_dat8_o; // 8-bit internal data output
+wire [31:0] wb_dat32_o; // debug interface 32-bit output
+wire [3:0] wb_sel_i; // WISHBONE select signal
+wire [uart_addr_width-1:0] wb_adr_int;
+wire we_o; // Write enable for registers
+wire re_o; // Read enable for registers
+//
+// MODULE INSTANCES
+//
+
+`ifdef DATA_BUS_WIDTH_8
+`else
+// debug interface wires
+wire [3:0] ier;
+wire [3:0] iir;
+wire [1:0] fcr;
+wire [4:0] mcr;
+wire [7:0] lcr;
+wire [7:0] msr;
+wire [7:0] lsr;
+wire [`UART_FIFO_COUNTER_W-1:0] rf_count;
+wire [`UART_FIFO_COUNTER_W-1:0] tf_count;
+wire [2:0] tstate;
+wire [3:0] rstate;
+`endif
+
+`ifdef DATA_BUS_WIDTH_8
+//// WISHBONE interface module
+uart_wb wb_interface(
+ .clk( wb_clk_i ),
+ .wb_rst_i( wb_rst_i ),
+ .wb_dat_i(wb_dat_i),
+ .wb_dat_o(wb_dat_o),
+ .wb_dat8_i(wb_dat8_i),
+ .wb_dat8_o(wb_dat8_o),
+ .wb_dat32_o(32'b0),
+ .wb_sel_i(4'b0),
+ .wb_we_i( wb_we_i ),
+ .wb_stb_i( wb_stb_i ),
+ .wb_cyc_i( wb_cyc_i ),
+ .wb_ack_o( wb_ack_o ),
+ .wb_adr_i(wb_adr_i),
+ .wb_adr_int(wb_adr_int),
+ .we_o( we_o ),
+ .re_o(re_o)
+ );
+`else
+uart_wb wb_interface(
+ .clk( wb_clk_i ),
+ .wb_rst_i( wb_rst_i ),
+ .wb_dat_i(wb_dat_i),
+ .wb_dat_o(wb_dat_o),
+ .wb_dat8_i(wb_dat8_i),
+ .wb_dat8_o(wb_dat8_o),
+ .wb_sel_i(wb_sel_i),
+ .wb_dat32_o(wb_dat32_o),
+ .wb_we_i( wb_we_i ),
+ .wb_stb_i( wb_stb_i ),
+ .wb_cyc_i( wb_cyc_i ),
+ .wb_ack_o( wb_ack_o ),
+ .wb_adr_i(wb_adr_i),
+ .wb_adr_int(wb_adr_int),
+ .we_o( we_o ),
+ .re_o(re_o)
+ );
+`endif
+
+// Registers
+uart_regs regs(
+ .clk( wb_clk_i ),
+ .wb_rst_i( wb_rst_i ),
+ .wb_addr_i( wb_adr_int ),
+ .wb_dat_i( wb_dat8_i ),
+ .wb_dat_o( wb_dat8_o ),
+ .wb_we_i( we_o ),
+ .wb_re_i(re_o),
+ .modem_inputs( {cts_pad_i, dsr_pad_i,
+ ri_pad_i, dcd_pad_i} ),
+ .stx_pad_o( stx_pad_o ),
+ .srx_pad_i( srx_pad_i ),
+`ifdef DATA_BUS_WIDTH_8
+`else
+// debug interface signals enabled
+.ier(ier),
+.iir(iir),
+.fcr(fcr),
+.mcr(mcr),
+.lcr(lcr),
+.msr(msr),
+.lsr(lsr),
+.rf_count(rf_count),
+.tf_count(tf_count),
+.tstate(tstate),
+.rstate(rstate),
+`endif
+ .rts_pad_o( rts_pad_o ),
+ .dtr_pad_o( dtr_pad_o ),
+ .int_o( int_o )
+`ifdef UART_HAS_BAUDRATE_OUTPUT
+ , .baud_o(baud_o)
+`endif
+
+);
+
+`ifdef DATA_BUS_WIDTH_8
+`else
+uart_debug_if dbg(/*AUTOINST*/
+ // Outputs
+ .wb_dat32_o (wb_dat32_o[31:0]),
+ // Inputs
+ .wb_adr_i (wb_adr_int[`UART_ADDR_WIDTH-1:0]),
+ .ier (ier[3:0]),
+ .iir (iir[3:0]),
+ .fcr (fcr[1:0]),
+ .mcr (mcr[4:0]),
+ .lcr (lcr[7:0]),
+ .msr (msr[7:0]),
+ .lsr (lsr[7:0]),
+ .rf_count (rf_count[`UART_FIFO_COUNTER_W-1:0]),
+ .tf_count (tf_count[`UART_FIFO_COUNTER_W-1:0]),
+ .tstate (tstate[2:0]),
+ .rstate (rstate[3:0]));
+`endif
+
+initial
+begin
+ `ifdef DATA_BUS_WIDTH_8
+ $display("(%m) UART INFO: Data bus width is 8. No Debug interface.\n");
+ `else
+ $display("(%m) UART INFO: Data bus width is 32. Debug Interface present.\n");
+ `endif
+ `ifdef UART_HAS_BAUDRATE_OUTPUT
+ $display("(%m) UART INFO: Has baudrate output\n");
+ `else
+ $display("(%m) UART INFO: Doesn't have baudrate output\n");
+ `endif
+end
+
+endmodule
+
+
Index: zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_transmitter.v
===================================================================
--- zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_transmitter.v (nonexistent)
+++ zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_transmitter.v (revision 43)
@@ -0,0 +1,349 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// uart_transmitter.v ////
+//// ////
+//// ////
+//// This file is part of the "UART 16550 compatible" project ////
+//// http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Documentation related to this project: ////
+//// - http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Projects compatibility: ////
+//// - WISHBONE ////
+//// RS232 Protocol ////
+//// 16550D uart (mostly supported) ////
+//// ////
+//// Overview (main Features): ////
+//// UART core transmitter logic ////
+//// ////
+//// Known problems (limits): ////
+//// None known ////
+//// ////
+//// To Do: ////
+//// Thourough testing. ////
+//// ////
+//// Author(s): ////
+//// - gorban@opencores.org ////
+//// - Jacob Gorban ////
+//// - Igor Mohor (igorm@opencores.org) ////
+//// ////
+//// Created: 2001/05/12 ////
+//// Last Updated: 2001/05/17 ////
+//// (See log for the revision history) ////
+//// ////
+//// Modified for use in the ZAP project by Revanth Kamaraj ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000, 2001 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.18 2002/07/22 23:02:23 gorban
+// Bug Fixes:
+// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
+// Problem reported by Kenny.Tung.
+// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
+//
+// Improvements:
+// * Made FIFO's as general inferrable memory where possible.
+// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
+// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
+//
+// * Added optional baudrate output (baud_o).
+// This is identical to BAUDOUT* signal on 16550 chip.
+// It outputs 16xbit_clock_rate - the divided clock.
+// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
+//
+// Revision 1.16 2002/01/08 11:29:40 mohor
+// tf_pop was too wide. Now it is only 1 clk cycle width.
+//
+// Revision 1.15 2001/12/17 14:46:48 mohor
+// overrun signal was moved to separate block because many sequential lsr
+// reads were preventing data from being written to rx fifo.
+// underrun signal was not used and was removed from the project.
+//
+// Revision 1.14 2001/12/03 21:44:29 gorban
+// Updated specification documentation.
+// Added full 32-bit data bus interface, now as default.
+// Address is 5-bit wide in 32-bit data bus mode.
+// Added wb_sel_i input to the core. It's used in the 32-bit mode.
+// Added debug interface with two 32-bit read-only registers in 32-bit mode.
+// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
+// My small test bench is modified to work with 32-bit mode.
+//
+// Revision 1.13 2001/11/08 14:54:23 mohor
+// Comments in Slovene language deleted, few small fixes for better work of
+// old tools. IRQs need to be fix.
+//
+// Revision 1.12 2001/11/07 17:51:52 gorban
+// Heavily rewritten interrupt and LSR subsystems.
+// Many bugs hopefully squashed.
+//
+// Revision 1.11 2001/10/29 17:00:46 gorban
+// fixed parity sending and tx_fifo resets over- and underrun
+//
+// Revision 1.10 2001/10/20 09:58:40 gorban
+// Small synopsis fixes
+//
+// Revision 1.9 2001/08/24 21:01:12 mohor
+// Things connected to parity changed.
+// Clock devider changed.
+//
+// Revision 1.8 2001/08/23 16:05:05 mohor
+// Stop bit bug fixed.
+// Parity bug fixed.
+// WISHBONE read cycle bug fixed,
+// OE indicator (Overrun Error) bug fixed.
+// PE indicator (Parity Error) bug fixed.
+// Register read bug fixed.
+//
+// Revision 1.6 2001/06/23 11:21:48 gorban
+// DL made 16-bit long. Fixed transmission/reception bugs.
+//
+// Revision 1.5 2001/06/02 14:28:14 gorban
+// Fixed receiver and transmitter. Major bug fixed.
+//
+// Revision 1.4 2001/05/31 20:08:01 gorban
+// FIFO changes and other corrections.
+//
+// Revision 1.3 2001/05/27 17:37:49 gorban
+// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
+//
+// Revision 1.2 2001/05/21 19:12:02 gorban
+// Corrected some Linter messages.
+//
+// Revision 1.1 2001/05/17 18:34:18 gorban
+// First 'stable' release. Should be sythesizable now. Also added new header.
+//
+// Revision 1.0 2001-05-17 21:27:12+02 jacob
+// Initial revision
+//
+//
+
+
+`include "uart_defines.v"
+
+module uart_transmitter (clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, stx_pad_o, tstate, tf_count, tx_reset, lsr_mask);
+
+input clk;
+input wb_rst_i;
+input [7:0] lcr;
+input tf_push;
+input [7:0] wb_dat_i;
+input enable;
+input tx_reset;
+input lsr_mask; //reset of fifo
+output stx_pad_o;
+output [2:0] tstate;
+output [`UART_FIFO_COUNTER_W-1:0] tf_count;
+
+reg [2:0] tstate;
+reg [4:0] counter;
+reg [2:0] bit_counter; // counts the bits to be sent
+reg [6:0] shift_out; // output shift register
+reg stx_o_tmp;
+reg parity_xor; // parity of the word
+reg tf_pop;
+reg bit_out;
+
+// TX FIFO instance
+//
+// Transmitter FIFO signals
+wire [`UART_FIFO_WIDTH-1:0] tf_data_in;
+wire [`UART_FIFO_WIDTH-1:0] tf_data_out;
+wire tf_push;
+wire tf_overrun;
+wire [`UART_FIFO_COUNTER_W-1:0] tf_count;
+
+assign tf_data_in = wb_dat_i;
+
+uart_tfifo fifo_tx( // error bit signal is not used in transmitter FIFO
+ .clk( clk ),
+ .wb_rst_i( wb_rst_i ),
+ .data_in( tf_data_in ),
+ .data_out( tf_data_out ),
+ .push( tf_push ),
+ .pop( tf_pop ),
+ .overrun( tf_overrun ),
+ .count( tf_count ),
+ .fifo_reset( tx_reset ),
+ .reset_status(lsr_mask)
+);
+
+// TRANSMITTER FINAL STATE MACHINE
+
+parameter s_idle = 3'd0;
+parameter s_send_start = 3'd1;
+parameter s_send_byte = 3'd2;
+parameter s_send_parity = 3'd3;
+parameter s_send_stop = 3'd4;
+parameter s_pop_byte = 3'd5;
+
+always @(posedge clk or posedge wb_rst_i)
+begin
+ if (wb_rst_i)
+ begin
+ tstate <= s_idle;
+ stx_o_tmp <= 1'b1;
+ counter <= 5'b0;
+ shift_out <= 7'b0;
+ bit_out <= 1'b0;
+ parity_xor <= 1'b0;
+ tf_pop <= 1'b0;
+ bit_counter <= 3'b0;
+ end
+ else
+ if (enable)
+ begin
+ case (tstate)
+ s_idle : if (~|tf_count) // if tf_count==0
+ begin
+ tstate <= s_idle;
+ stx_o_tmp <= 1'b1;
+ end
+ else
+ begin
+ tf_pop <= 1'b0;
+ stx_o_tmp <= 1'b1;
+ tstate <= s_pop_byte;
+ end
+ s_pop_byte : begin
+ tf_pop <= 1'b1;
+ case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word
+ 2'b00 : begin
+ bit_counter <= 3'b100;
+ parity_xor <= ^tf_data_out[4:0];
+ end
+ 2'b01 : begin
+ bit_counter <= 3'b101;
+ parity_xor <= ^tf_data_out[5:0];
+ end
+ 2'b10 : begin
+ bit_counter <= 3'b110;
+ parity_xor <= ^tf_data_out[6:0];
+ end
+ 2'b11 : begin
+ bit_counter <= 3'b111;
+ parity_xor <= ^tf_data_out[7:0];
+ end
+ endcase
+ {shift_out[6:0], bit_out} <= tf_data_out;
+ tstate <= s_send_start;
+ end
+ s_send_start : begin
+ tf_pop <= 1'b0;
+ if (~|counter)
+ counter <= 5'b01111;
+ else
+ if (counter == 5'b00001)
+ begin
+ counter <= 0;
+ tstate <= s_send_byte;
+ end
+ else
+ counter <= counter - 1'b1;
+ stx_o_tmp <= 1'b0;
+ end
+ s_send_byte : begin
+ if (~|counter)
+ counter <= 5'b01111;
+ else
+ if (counter == 5'b00001)
+ begin
+ if (bit_counter > 3'b0)
+ begin
+ bit_counter <= bit_counter - 1'b1;
+ {shift_out[5:0],bit_out } <= {shift_out[6:1], shift_out[0]};
+ tstate <= s_send_byte;
+ end
+ else // end of byte
+ if (~lcr[`UART_LC_PE])
+ begin
+ tstate <= s_send_stop;
+ end
+ else
+ begin
+ case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]})
+ 2'b00: bit_out <= ~parity_xor;
+ 2'b01: bit_out <= 1'b1;
+ 2'b10: bit_out <= parity_xor;
+ 2'b11: bit_out <= 1'b0;
+ endcase
+ tstate <= s_send_parity;
+ end
+ counter <= 0;
+ end
+ else
+ counter <= counter - 1'b1;
+ stx_o_tmp <= bit_out; // set output pin
+ end
+ s_send_parity : begin
+ if (~|counter)
+ counter <= 5'b01111;
+ else
+ if (counter == 5'b00001)
+ begin
+ counter <= 4'b0;
+ tstate <= s_send_stop;
+ end
+ else
+ counter <= counter - 1'b1;
+ stx_o_tmp <= bit_out;
+ end
+ s_send_stop : begin
+ if (~|counter)
+ begin
+ casex ({lcr[`UART_LC_SB],lcr[`UART_LC_BITS]})
+ 3'b0xx: counter <= 5'b01101; // 1 stop bit ok igor
+ 3'b100: counter <= 5'b10101; // 1.5 stop bit
+ default: counter <= 5'b11101; // 2 stop bits
+ endcase
+ end
+ else
+ if (counter == 5'b00001)
+ begin
+ counter <= 0;
+ tstate <= s_idle;
+ end
+ else
+ counter <= counter - 1'b1;
+ stx_o_tmp <= 1'b1;
+ end
+
+ default : // should never get here
+ tstate <= s_idle;
+ endcase
+ end // end if enable
+ else
+ tf_pop <= 1'b0; // tf_pop must be 1 cycle width
+end // transmitter logic
+
+assign stx_pad_o = lcr[`UART_LC_BC] ? 1'b0 : stx_o_tmp; // Break condition
+
+endmodule
Index: zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_wb.v
===================================================================
--- zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_wb.v (nonexistent)
+++ zap/trunk/src/testbench/External_IP/uart16550/rtl/uart_wb.v (revision 43)
@@ -0,0 +1,314 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// uart_wb.v ////
+//// ////
+//// ////
+//// This file is part of the "UART 16550 compatible" project ////
+//// http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Documentation related to this project: ////
+//// - http://www.opencores.org/cores/uart16550/ ////
+//// ////
+//// Projects compatibility: ////
+//// - WISHBONE ////
+//// RS232 Protocol ////
+//// 16550D uart (mostly supported) ////
+//// ////
+//// Overview (main Features): ////
+//// UART core WISHBONE interface. ////
+//// ////
+//// Known problems (limits): ////
+//// Inserts one wait state on all transfers. ////
+//// Note affected signals and the way they are affected. ////
+//// ////
+//// To Do: ////
+//// Nothing. ////
+//// ////
+//// Author(s): ////
+//// - gorban@opencores.org ////
+//// - Jacob Gorban ////
+//// - Igor Mohor (igorm@opencores.org) ////
+//// ////
+//// Created: 2001/05/12 ////
+//// Last Updated: 2001/05/17 ////
+//// (See log for the revision history) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000, 2001 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.16 2002/07/29 21:16:18 gorban
+// The uart_defines.v file is included again in sources.
+//
+// Revision 1.15 2002/07/22 23:02:23 gorban
+// Bug Fixes:
+// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
+// Problem reported by Kenny.Tung.
+// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
+//
+// Improvements:
+// * Made FIFO's as general inferrable memory where possible.
+// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
+// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
+//
+// * Added optional baudrate output (baud_o).
+// This is identical to BAUDOUT* signal on 16550 chip.
+// It outputs 16xbit_clock_rate - the divided clock.
+// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
+//
+// Revision 1.12 2001/12/19 08:03:34 mohor
+// Warnings cleared.
+//
+// Revision 1.11 2001/12/06 14:51:04 gorban
+// Bug in LSR[0] is fixed.
+// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
+//
+// Revision 1.10 2001/12/03 21:44:29 gorban
+// Updated specification documentation.
+// Added full 32-bit data bus interface, now as default.
+// Address is 5-bit wide in 32-bit data bus mode.
+// Added wb_sel_i input to the core. It's used in the 32-bit mode.
+// Added debug interface with two 32-bit read-only registers in 32-bit mode.
+// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
+// My small test bench is modified to work with 32-bit mode.
+//
+// Revision 1.9 2001/10/20 09:58:40 gorban
+// Small synopsis fixes
+//
+// Revision 1.8 2001/08/24 21:01:12 mohor
+// Things connected to parity changed.
+// Clock devider changed.
+//
+// Revision 1.7 2001/08/23 16:05:05 mohor
+// Stop bit bug fixed.
+// Parity bug fixed.
+// WISHBONE read cycle bug fixed,
+// OE indicator (Overrun Error) bug fixed.
+// PE indicator (Parity Error) bug fixed.
+// Register read bug fixed.
+//
+// Revision 1.4 2001/05/31 20:08:01 gorban
+// FIFO changes and other corrections.
+//
+// Revision 1.3 2001/05/21 19:12:01 gorban
+// Corrected some Linter messages.
+//
+// Revision 1.2 2001/05/17 18:34:18 gorban
+// First 'stable' release. Should be sythesizable now. Also added new header.
+//
+// Revision 1.0 2001-05-17 21:27:13+02 jacob
+// Initial revision
+//
+//
+
+// UART core WISHBONE interface
+//
+// Author: Jacob Gorban (jacob.gorban@flextronicssemi.com)
+// Company: Flextronics Semiconductor
+//
+
+`include "uart_defines.v"
+
+module uart_wb (clk, wb_rst_i,
+ wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_adr_i,
+ wb_adr_int, wb_dat_i, wb_dat_o, wb_dat8_i, wb_dat8_o, wb_dat32_o, wb_sel_i,
+ we_o, re_o // Write and read enable output for the core
+);
+
+input clk;
+
+// WISHBONE interface
+input wb_rst_i;
+input wb_we_i;
+input wb_stb_i;
+input wb_cyc_i;
+input [3:0] wb_sel_i;
+input [`UART_ADDR_WIDTH-1:0] wb_adr_i; //WISHBONE address line
+
+`ifdef DATA_BUS_WIDTH_8
+input [7:0] wb_dat_i; //input WISHBONE bus
+output [7:0] wb_dat_o;
+reg [7:0] wb_dat_o;
+wire [7:0] wb_dat_i;
+reg [7:0] wb_dat_is;
+`else // for 32 data bus mode
+input [31:0] wb_dat_i; //input WISHBONE bus
+output [31:0] wb_dat_o;
+reg [31:0] wb_dat_o;
+wire [31:0] wb_dat_i;
+reg [31:0] wb_dat_is;
+`endif // !`ifdef DATA_BUS_WIDTH_8
+
+output [`UART_ADDR_WIDTH-1:0] wb_adr_int; // internal signal for address bus
+input [7:0] wb_dat8_o; // internal 8 bit output to be put into wb_dat_o
+output [7:0] wb_dat8_i;
+input [31:0] wb_dat32_o; // 32 bit data output (for debug interface)
+output wb_ack_o;
+output we_o;
+output re_o;
+
+wire we_o;
+reg wb_ack_o;
+reg [7:0] wb_dat8_i;
+wire [7:0] wb_dat8_o;
+wire [`UART_ADDR_WIDTH-1:0] wb_adr_int; // internal signal for address bus
+reg [`UART_ADDR_WIDTH-1:0] wb_adr_is;
+reg wb_we_is;
+reg wb_cyc_is;
+reg wb_stb_is;
+reg [3:0] wb_sel_is;
+wire [3:0] wb_sel_i;
+reg wre ;// timing control signal for write or read enable
+
+// wb_ack_o FSM
+reg [1:0] wbstate;
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) begin
+ wb_ack_o <= 1'b0;
+ wbstate <= 0;
+ wre <= 1'b1;
+ end else
+ case (wbstate)
+ 0: begin
+ if (wb_stb_is & wb_cyc_is) begin
+ wre <= 0;
+ wbstate <= 1;
+ wb_ack_o <= 1;
+ end else begin
+ wre <= 1;
+ wb_ack_o <= 0;
+ end
+ end
+ 1: begin
+ wb_ack_o <= 0;
+ wbstate <= 2;
+ wre <= 0;
+ end
+ 2,3: begin
+ wb_ack_o <= 0;
+ wbstate <= 0;
+ wre <= 0;
+ end
+ endcase
+
+assign we_o = wb_we_is & wb_stb_is & wb_cyc_is & wre ; //WE for registers
+assign re_o = ~wb_we_is & wb_stb_is & wb_cyc_is & wre ; //RE for registers
+
+// Sample input signals
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i) begin
+ wb_adr_is <= 0;
+ wb_we_is <= 0;
+ wb_cyc_is <= 0;
+ wb_stb_is <= 0;
+ wb_dat_is <= 0;
+ wb_sel_is <= 0;
+ end else begin
+ wb_adr_is <= wb_adr_i;
+ wb_we_is <= wb_we_i;
+ wb_cyc_is <= wb_cyc_i;
+ wb_stb_is <= wb_stb_i;
+ wb_dat_is <= wb_dat_i;
+ wb_sel_is <= wb_sel_i;
+ end
+
+`ifdef DATA_BUS_WIDTH_8 // 8-bit data bus
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i)
+ wb_dat_o <= 0;
+ else
+ wb_dat_o <= wb_dat8_o;
+
+always @(wb_dat_is)
+ wb_dat8_i = wb_dat_is;
+
+assign wb_adr_int = wb_adr_is;
+
+`else // 32-bit bus
+// put output to the correct byte in 32 bits using select line
+always @(posedge clk or posedge wb_rst_i)
+ if (wb_rst_i)
+ wb_dat_o <= 0;
+ else if (re_o)
+ case (wb_sel_is)
+ 4'b0001: wb_dat_o <= {24'b0, wb_dat8_o};
+ 4'b0010: wb_dat_o <= {16'b0, wb_dat8_o, 8'b0};
+ 4'b0100: wb_dat_o <= {8'b0, wb_dat8_o, 16'b0};
+ 4'b1000: wb_dat_o <= {wb_dat8_o, 24'b0};
+ 4'b1111: wb_dat_o <= wb_dat32_o; // debug interface output
+ default: wb_dat_o <= 0;
+ endcase // case(wb_sel_i)
+
+reg [1:0] wb_adr_int_lsb;
+
+always @(wb_sel_is or wb_dat_is)
+begin
+ case (wb_sel_is)
+ 4'b0001 : wb_dat8_i = wb_dat_is[7:0];
+ 4'b0010 : wb_dat8_i = wb_dat_is[15:8];
+ 4'b0100 : wb_dat8_i = wb_dat_is[23:16];
+ 4'b1000 : wb_dat8_i = wb_dat_is[31:24];
+ default : wb_dat8_i = wb_dat_is[7:0];
+ endcase // case(wb_sel_i)
+
+ `ifdef LITLE_ENDIAN
+ case (wb_sel_is)
+ 4'b0001 : wb_adr_int_lsb = 2'h0;
+ 4'b0010 : wb_adr_int_lsb = 2'h1;
+ 4'b0100 : wb_adr_int_lsb = 2'h2;
+ 4'b1000 : wb_adr_int_lsb = 2'h3;
+ default : wb_adr_int_lsb = 2'h0;
+ endcase // case(wb_sel_i)
+ `else
+ case (wb_sel_is)
+ 4'b0001 : wb_adr_int_lsb = 2'h3;
+ 4'b0010 : wb_adr_int_lsb = 2'h2;
+ 4'b0100 : wb_adr_int_lsb = 2'h1;
+ 4'b1000 : wb_adr_int_lsb = 2'h0;
+ default : wb_adr_int_lsb = 2'h0;
+ endcase // case(wb_sel_i)
+ `endif
+end
+
+assign wb_adr_int = {wb_adr_is[`UART_ADDR_WIDTH-1:2], wb_adr_int_lsb};
+
+`endif // !`ifdef DATA_BUS_WIDTH_8
+
+endmodule
+
+
+
+
+
+
+
+
+
+
Index: zap/trunk/src/testbench/chip_top.v
===================================================================
--- zap/trunk/src/testbench/chip_top.v (nonexistent)
+++ zap/trunk/src/testbench/chip_top.v (revision 43)
@@ -0,0 +1,326 @@
+// -----------------------------------------------------------------------------
+// -- --
+// -- (C) 2016-2018 Revanth Kamaraj. --
+// -- --
+// -- --------------------------------------------------------------------------
+// -- --
+// -- This program is free software; you can redistribute it and/or --
+// -- modify it under the terms of the GNU General Public License --
+// -- as published by the Free Software Foundation; either version 2 --
+// -- of the License, or (at your option) any later version. --
+// -- --
+// -- This program is distributed in the hope that it will be useful, --
+// -- but WITHOUT ANY WARRANTY; without even the implied warranty of --
+// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
+// -- GNU General Public License for more details. --
+// -- --
+// -- You should have received a copy of the GNU General Public License --
+// -- along with this program; if not, write to the Free Software --
+// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
+// -- 02110-1301, USA. --
+// -- --
+// -----------------------------------------------------------------------------
+//
+// This is the chip top that contains the ZAP core along with
+// 2 x UARTs
+// 2 x Timers
+// 1 x VIC
+//
+// UART0 address space FFFFFFE0 to FFFFFFFF
+// Timer0 address space FFFFFFC0 to FFFFFFDF
+// VIC0 address space FFFFFFA0 to FFFFFFBF
+// UART1 address space FFFFFF80 to FFFFFF9F
+// Timer1 address space FFFFFF60 to FFFFFF7F
+//
+// Accesses outside this go the the wishbone interface.
+//
+// An extenal Wishbone interface is provided to allow connection to an external
+// Wishbone network for RAMs, ROMs etc.
+//
+// -----------------------------------------------------------------------------
+
+module chip_top #(
+
+// CPU config.
+parameter DATA_SECTION_TLB_ENTRIES = 4,
+parameter DATA_LPAGE_TLB_ENTRIES = 8,
+parameter DATA_SPAGE_TLB_ENTRIES = 16,
+parameter DATA_CACHE_SIZE = 1024,
+parameter CODE_SECTION_TLB_ENTRIES = 4,
+parameter CODE_LPAGE_TLB_ENTRIES = 8,
+parameter CODE_SPAGE_TLB_ENTRIES = 16,
+parameter CODE_CACHE_SIZE = 1024,
+parameter FIFO_DEPTH = 4,
+parameter BP_ENTRIES = 1024,
+parameter STORE_BUFFER_DEPTH = 32
+
+)(
+ // Clk and rst
+ input wire SYS_CLK,
+ input wire SYS_RST,
+
+ // UART 0
+ input wire UART0_RXD,
+ output wire UART0_TXD,
+
+ // UART 1
+ input wire UART1_RXD,
+ output wire UART1_TXD,
+
+ // Remaining IRQs to the interrupt controller.
+ input wire [27:0] I_IRQ,
+
+ // Single FIQ input directly to ZAP CPU.
+ input wire I_FIQ,
+
+ // External Wishbone Connection (for RAMs etc).
+ output wire O_WB_STB,
+ output wire O_WB_CYC,
+ output wire [31:0] O_WB_DAT,
+ output wire [31:0] O_WB_ADR,
+ output wire [3:0] O_WB_SEL,
+ output wire O_WB_WE,
+ input wire I_WB_ACK,
+ input wire [31:0] I_WB_DAT
+);
+
+`include "zap_defines.vh"
+`include "zap_localparams.vh"
+`include "zap_functions.vh"
+
+// Peripheral addresses.
+localparam UART0_LO = 32'hFFFFFFE0;
+localparam UART0_HI = 32'hFFFFFFFF;
+localparam TIMER0_LO = 32'hFFFFFFC0;
+localparam TIMER0_HI = 32'hFFFFFFDF;
+localparam VIC_LO = 32'hFFFFFFA0;
+localparam VIC_HI = 32'hFFFFFFBF;
+localparam UART1_LO = 32'hFFFFFF80;
+localparam UART1_HI = 32'hFFFFFF9F;
+localparam TIMER1_LO = 32'hFFFFFF60;
+localparam TIMER1_HI = 32'hFFFFFF7F;
+
+// Internal signals.
+wire i_clk = SYS_CLK;
+wire i_reset = SYS_RST;
+wire [1:0] uart_in = {UART1_RXD, UART0_RXD};
+wire [1:0] uart_out;
+assign {UART1_TXD, UART0_TXD} = uart_out;
+wire data_wb_cyc;
+wire data_wb_stb;
+reg [31:0] data_wb_din;
+reg data_wb_ack;
+reg data_wb_cyc_ram, data_wb_cyc_uart [1:0], data_wb_cyc_timer [1:0], data_wb_cyc_vic;
+reg data_wb_stb_ram, data_wb_stb_uart [1:0], data_wb_stb_timer [1:0], data_wb_stb_vic;
+wire [31:0] data_wb_din_ram, data_wb_din_uart [1:0], data_wb_din_timer [1:0], data_wb_din_vic;
+wire data_wb_ack_ram, data_wb_ack_uart [1:0], data_wb_ack_timer [1:0], data_wb_ack_vic;
+wire [3:0] data_wb_sel;
+wire data_wb_we;
+wire [31:0] data_wb_dout;
+wire [31:0] data_wb_adr;
+wire [2:0] data_wb_cti; // Cycle Type Indicator.
+wire global_irq;
+wire [1:0] uart_irq;
+wire [1:0] timer_irq;
+wire ext_stb;
+wire ext_cyc;
+wire [31:0] ext_adr;
+
+// Assigns.
+assign O_WB_CYC = data_wb_cyc_ram;
+assign O_WB_STB = data_wb_stb_ram;
+assign O_WB_ADR = data_wb_adr;
+assign O_WB_WE = data_wb_we;
+assign O_WB_DAT = data_wb_dout;
+assign O_WB_SEL = data_wb_sel;
+assign data_wb_din_ram = I_WB_DAT;
+assign data_wb_ack_ram = I_WB_ACK;
+
+// Wishbone selector.
+always @*
+begin:blk1
+ integer ii;
+
+ for(ii=0;ii<=1;ii=ii+1)
+ begin
+ data_wb_cyc_uart [ii] = 0;
+ data_wb_stb_uart [ii] = 0;
+ data_wb_cyc_timer[ii] = 0;
+ data_wb_stb_timer[ii] = 0;
+ end
+
+ data_wb_cyc_vic = 0;
+ data_wb_stb_vic = 0;
+
+ if ( data_wb_adr >= UART0_LO && data_wb_adr <= UART0_HI ) // UART0 access
+ begin
+ data_wb_cyc_uart[0] = data_wb_cyc;
+ data_wb_stb_uart[0] = data_wb_stb;
+ data_wb_ack = data_wb_ack_uart[0];
+ data_wb_din = data_wb_din_uart[0];
+ end
+ else if ( data_wb_adr >= TIMER0_LO && data_wb_adr <= TIMER0_HI ) // Timer0 access
+ begin
+ data_wb_cyc_timer[0] = data_wb_cyc;
+ data_wb_stb_timer[0] = data_wb_stb;
+ data_wb_ack = data_wb_ack_timer[0];
+ data_wb_din = data_wb_din_timer[0];
+ end
+ else if ( data_wb_adr >= VIC_LO && data_wb_adr <= VIC_HI ) // VIC access.
+ begin
+ data_wb_cyc_vic = data_wb_cyc;
+ data_wb_stb_vic = data_wb_stb;
+ data_wb_ack = data_wb_ack_vic;
+ data_wb_din = data_wb_din_vic;
+ end
+ else if ( data_wb_adr >= UART1_LO && data_wb_adr <= UART1_HI ) // UART1 access
+ begin
+ data_wb_cyc_uart[1] = data_wb_cyc;
+ data_wb_stb_uart[1] = data_wb_stb;
+ data_wb_ack = data_wb_ack_uart[1];
+ data_wb_din = data_wb_din_uart[1];
+ end
+ else if ( data_wb_adr >= TIMER1_LO && data_wb_adr <= TIMER1_HI ) // Timer1 access
+ begin
+ data_wb_cyc_timer[1] = data_wb_cyc;
+ data_wb_stb_timer[1] = data_wb_stb;
+ data_wb_ack = data_wb_ack_timer[1];
+ data_wb_din = data_wb_din_timer[1];
+ end
+ else // External WB access.
+ begin
+ data_wb_ack = data_wb_ack_ram;
+ data_wb_din = data_wb_din_ram;
+ end
+end
+
+always @ (posedge i_clk)
+begin
+ if ( ext_adr < TIMER1_LO )
+ begin
+ data_wb_cyc_ram <= ext_cyc;
+ data_wb_stb_ram <= ext_stb;
+ end
+ else
+ begin
+ data_wb_cyc_ram <= 1'd0;
+ data_wb_stb_ram <= 1'd0;
+ end
+end
+
+// =========================
+// Processor core.
+// =========================
+
+zap_top #(
+ .FIFO_DEPTH(FIFO_DEPTH),
+ .BP_ENTRIES(BP_ENTRIES),
+ .STORE_BUFFER_DEPTH(STORE_BUFFER_DEPTH),
+ .DATA_SECTION_TLB_ENTRIES(DATA_SECTION_TLB_ENTRIES),
+ .DATA_LPAGE_TLB_ENTRIES(DATA_LPAGE_TLB_ENTRIES),
+ .DATA_SPAGE_TLB_ENTRIES(DATA_SPAGE_TLB_ENTRIES),
+ .DATA_CACHE_SIZE(DATA_CACHE_SIZE),
+ .CODE_SECTION_TLB_ENTRIES(CODE_SECTION_TLB_ENTRIES),
+ .CODE_LPAGE_TLB_ENTRIES(CODE_LPAGE_TLB_ENTRIES),
+ .CODE_SPAGE_TLB_ENTRIES(CODE_SPAGE_TLB_ENTRIES),
+ .CODE_CACHE_SIZE(CODE_CACHE_SIZE)
+)
+u_zap_top
+(
+ .i_clk(i_clk),
+ .i_reset(i_reset),
+ .i_irq(global_irq),
+ .i_fiq (I_FIQ),
+ .o_wb_cyc (data_wb_cyc),
+ .o_wb_stb (data_wb_stb),
+ .o_wb_adr (data_wb_adr),
+ .o_wb_we (data_wb_we),
+ .o_wb_cti (data_wb_cti),
+ .i_wb_dat (data_wb_din),
+ .o_wb_dat (data_wb_dout),
+ .i_wb_ack (data_wb_ack),
+ .o_wb_sel (data_wb_sel),
+
+ // Strobe and CYC nxt pins.
+ .o_wb_stb_nxt (ext_stb),
+ .o_wb_cyc_nxt (ext_cyc),
+ .o_wb_adr_nxt (ext_adr),
+
+ .o_wb_bte () // Always zero.
+
+);
+
+// ===============================
+// 2 x UART + 2 x Timer
+// ===============================
+
+genvar gi;
+generate
+begin
+ for(gi=0;gi<=1;gi=gi+1)
+ begin: uart_gen
+ uart_top u_uart_top (
+
+ // WISHBONE interface
+ .wb_clk_i(i_clk),
+ .wb_rst_i(i_reset),
+ .wb_adr_i(data_wb_adr),
+ .wb_dat_i(data_wb_dout),
+ .wb_dat_o(data_wb_din_uart[gi]),
+ .wb_we_i (data_wb_we),
+ .wb_stb_i(data_wb_stb_uart[gi]),
+ .wb_cyc_i(data_wb_cyc_uart[gi]),
+ .wb_sel_i(data_wb_sel),
+ .wb_ack_o(data_wb_ack_uart[gi]),
+ .int_o (uart_irq[gi]), // Interrupt.
+
+ // UART signals.
+ .srx_pad_i (uart_in[gi]),
+ .stx_pad_o (uart_out[gi]),
+
+ // Tied or open.
+ .rts_pad_o(),
+ .cts_pad_i(1'd0),
+ .dtr_pad_o(),
+ .dsr_pad_i(1'd0),
+ .ri_pad_i (1'd0),
+ .dcd_pad_i(1'd0)
+ );
+
+ timer u_timer (
+ .i_clk(i_clk),
+ .i_rst(i_reset),
+ .i_wb_adr(data_wb_adr),
+ .i_wb_dat(data_wb_dout),
+ .i_wb_stb(data_wb_stb_timer[gi]),
+ .i_wb_cyc(data_wb_cyc_timer[gi]), // From core
+ .i_wb_wen(data_wb_we),
+ .i_wb_sel(data_wb_sel),
+ .o_wb_dat(data_wb_din_timer[gi]), // To core.
+ .o_wb_ack(data_wb_ack_timer[gi]),
+ .o_irq(timer_irq[gi]) // Interrupt
+ );
+ end
+end
+endgenerate
+
+// ===============================
+// VIC
+// ===============================
+
+vic #(.SOURCES(32)) u_vic (
+ .i_clk (i_clk),
+ .i_rst (i_reset),
+ .i_wb_adr(data_wb_adr),
+ .i_wb_dat(data_wb_dout),
+ .i_wb_stb(data_wb_stb_vic),
+ .i_wb_cyc(data_wb_cyc_vic), // From core
+ .i_wb_wen(data_wb_we),
+ .i_wb_sel(data_wb_sel),
+ .o_wb_dat(data_wb_din_vic), // To core.
+ .o_wb_ack(data_wb_ack_vic),
+ .i_irq({I_IRQ, timer_irq[1], uart_irq[1], timer_irq[0], uart_irq[0]}), // Concatenate 32 interrupt sources.
+ .o_irq(global_irq) // Interrupt out
+);
+
+endmodule // chip_top
Index: zap/trunk/src/testbench/ram.v
===================================================================
--- zap/trunk/src/testbench/ram.v (nonexistent)
+++ zap/trunk/src/testbench/ram.v (revision 43)
@@ -0,0 +1,102 @@
+// -----------------------------------------------------------------------------
+// -- --
+// -- (C) 2016-2018 Revanth Kamaraj. --
+// -- --
+// -- --------------------------------------------------------------------------
+// -- --
+// -- This program is free software; you can redistribute it and/or --
+// -- modify it under the terms of the GNU General Public License --
+// -- as published by the Free Software Foundation; either version 2 --
+// -- of the License, or (at your option) any later version. --
+// -- --
+// -- This program is distributed in the hope that it will be useful, --
+// -- but WITHOUT ANY WARRANTY; without even the implied warranty of --
+// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
+// -- GNU General Public License for more details. --
+// -- --
+// -- You should have received a copy of the GNU General Public License --
+// -- along with this program; if not, write to the Free Software --
+// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
+// -- 02110-1301, USA. --
+// -- --
+// -----------------------------------------------------------------------------
+
+`default_nettype none
+
+module ram #(parameter SIZE_IN_BYTES = 4096) (
+
+input wire i_clk,
+input wire i_wb_cyc,
+input wire i_wb_stb,
+input wire [31:0] i_wb_adr,
+input wire [31:0] i_wb_dat,
+input wire [3:0] i_wb_sel,
+input wire i_wb_we,
+output reg [31:0] o_wb_dat = 32'd0,
+output reg o_wb_ack = 1'd0
+
+);
+
+`include "zap_defines.vh"
+`include "zap_localparams.vh"
+`include "zap_functions.vh"
+
+integer seed = `SEED;
+reg [31:0] ram [SIZE_IN_BYTES/4 -1:0];
+
+// Initialize the RAM with the generated image.
+initial
+begin:blk1
+ integer i;
+ integer j;
+
+ reg [7:0] mem [SIZE_IN_BYTES-1:0];
+
+ j = 0;
+
+ for ( i=0;i> 2 ];
+ end
+ else if ( i_wb_we && i_wb_cyc && i_wb_stb && !stall )
+ begin
+ o_wb_ack <= 1'd1;
+ o_wb_dat <= 'dx;
+
+ if ( i_wb_sel[0] ) ram [ i_wb_adr >> 2 ][7:0] <= i_wb_dat[7:0];
+ if ( i_wb_sel[1] ) ram [ i_wb_adr >> 2 ][15:8] <= i_wb_dat[15:8];
+ if ( i_wb_sel[2] ) ram [ i_wb_adr >> 2 ][23:16] <= i_wb_dat[23:16];
+ if ( i_wb_sel[3] ) ram [ i_wb_adr >> 2 ][31:24] <= i_wb_dat[31:24];
+ end
+ else
+ begin
+ o_wb_ack <= 1'd0;
+ o_wb_dat <= 'dx;
+ end
+ end
+
+endmodule // ram
+
+`default_nettype wire
Index: zap/trunk/src/testbench/timer.v
===================================================================
--- zap/trunk/src/testbench/timer.v (nonexistent)
+++ zap/trunk/src/testbench/timer.v (revision 43)
@@ -0,0 +1,270 @@
+`default_nettype none
+
+// -----------------------------------------------------------------------------
+// -- --
+// -- (C) 2016-2018 Revanth Kamaraj. --
+// -- --
+// -- --------------------------------------------------------------------------
+// -- --
+// -- This program is free software; you can redistribute it and/or --
+// -- modify it under the terms of the GNU General Public License --
+// -- as published by the Free Software Foundation; either version 2 --
+// -- of the License, or (at your option) any later version. --
+// -- --
+// -- This program is distributed in the hope that it will be useful, --
+// -- but WITHOUT ANY WARRANTY; without even the implied warranty of --
+// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
+// -- GNU General Public License for more details. --
+// -- --
+// -- You should have received a copy of the GNU General Public License --
+// -- along with this program; if not, write to the Free Software --
+// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
+// -- 02110-1301, USA. --
+// -- --
+// -----------------------------------------------------------------------------
+// --
+// This is a Wishbone timer peripheral with simple controls. --
+// --
+// Registers:
+// 0x0 (DEVEN) - 0x1 to enable the timer unit. 0x0 to disable the unit. --
+// 0x4 (DEVPR) - Timer length in number of Wishbone clocks. --
+// 0x8 (DEVAK) - Write: 0x1 to acknowledge interrupt. Read: 0x1 reveals timer --
+// interrupt occured. --
+// 0xC (DEVST) - 0x1 to start the timer. Write only. Always reads 0x0. --
+// --
+// ------------------------------------------------------------------------------
+
+module timer #(
+
+ // Register addresses.
+ parameter [31:0] TIMER_ENABLE_REGISTER = 32'h0,
+ parameter [31:0] TIMER_LIMIT_REGISTER = 32'h4,
+ parameter [31:0] TIMER_INTACK_REGISTER = 32'h8,
+ parameter [31:0] TIMER_START_REGISTER = 32'hC
+
+) (
+
+// Clock and reset.
+input wire i_clk,
+input wire i_rst,
+
+// Wishbone interface.
+input wire [31:0] i_wb_dat,
+input wire [3:0] i_wb_adr,
+input wire i_wb_stb,
+input wire i_wb_cyc,
+input wire i_wb_wen,
+input wire [3:0] i_wb_sel,
+output reg [31:0] o_wb_dat,
+output reg o_wb_ack,
+
+
+// Interrupt output. Level interrupt.
+output reg o_irq
+
+);
+
+// Timer registers.
+reg [31:0] DEVEN;
+reg [31:0] DEVPR;
+reg [31:0] DEVAK;
+reg [31:0] DEVST;
+
+`ifndef ZAP_SOC_TIMER
+`define ZAP_SOC_TIMER
+ `define DEVEN TIMER_ENABLE_REGISTER
+ `define DEVPR TIMER_LIMIT_REGISTER
+ `define DEVAK TIMER_INTACK_REGISTER
+ `define DEVST TIMER_START_REGISTER
+`endif
+
+// Timer core.
+reg [31:0] ctr; // Core counter.
+reg start; // Pulse to start the timer. Done signal is cleared.
+reg done; // Asserted when timer is done.
+reg clr; // Clears the done signal.
+reg [31:0] state; // State
+reg enable; // 1 to enable the timer.
+reg [31:0] finalval; // Final value to count.
+reg [31:0] wbstate;
+
+localparam IDLE = 0;
+localparam COUNTING = 1;
+localparam DONE = 2;
+
+localparam WBIDLE = 0;
+localparam WBREAD = 1;
+localparam WBWRITE = 2;
+localparam WBACK = 3;
+localparam WBDONE = 4;
+
+always @ (*)
+ o_irq = done;
+
+always @ (*)
+begin
+ start = DEVST[0];
+ enable = DEVEN[0];
+ finalval = DEVPR;
+ clr = DEVAK[0];
+end
+
+always @ ( posedge i_clk )
+begin
+ DEVST <= 0;
+
+ if ( i_rst )
+ begin
+ DEVEN <= 0;
+ DEVPR <= 0;
+ DEVAK <= 0;
+ DEVST <= 0;
+ wbstate <= WBIDLE;
+ o_wb_dat <= 0;
+ o_wb_ack <= 0;
+ end
+ else
+ begin
+ case(wbstate)
+ WBIDLE:
+ begin
+ o_wb_ack <= 1'd0;
+
+ if ( i_wb_stb && i_wb_cyc )
+ begin
+ if ( i_wb_wen )
+ wbstate <= WBWRITE;
+ else
+ wbstate <= WBREAD;
+ end
+ end
+
+ WBWRITE:
+ begin
+ case(i_wb_adr)
+ `DEVEN: // DEVEN
+ begin
+ $display($time, " - %m :: Writing register DEVEN...");
+ if ( i_wb_sel[0] ) DEVEN[7:0] <= i_wb_dat >> 0;
+ if ( i_wb_sel[1] ) DEVEN[15:8] <= i_wb_dat >> 8;
+ if ( i_wb_sel[2] ) DEVEN[23:16] <= i_wb_dat >> 16;
+ if ( i_wb_sel[3] ) DEVEN[31:24] <= i_wb_dat >> 24;
+ end
+
+ `DEVPR: // DEVPR
+ begin
+ $display($time, " - %m :: Writing register DEVPR...");
+ if ( i_wb_sel[0] ) DEVPR[7:0] <= i_wb_dat >> 0;
+ if ( i_wb_sel[1] ) DEVPR[15:8] <= i_wb_dat >> 8;
+ if ( i_wb_sel[2] ) DEVPR[23:16] <= i_wb_dat >> 16;
+ if ( i_wb_sel[3] ) DEVPR[31:24] <= i_wb_dat >> 24;
+
+ end
+
+ `DEVAK: // DEVAK
+ begin
+ $display($time, " - %m :: Writing register DEVAK...");
+ if ( i_wb_sel[0] ) DEVPR[7:0] <= i_wb_dat >> 0;
+ if ( i_wb_sel[1] ) DEVPR[15:8] <= i_wb_dat >> 8;
+ if ( i_wb_sel[2] ) DEVPR[23:16] <= i_wb_dat >> 16;
+ if ( i_wb_sel[3] ) DEVPR[31:24] <= i_wb_dat >> 24;
+ end
+
+ `DEVST: // DEVST
+ begin
+ $display($time, " - %m :: Writing register DEVST...");
+ if ( i_wb_sel[0] ) DEVST[7:0] <= i_wb_dat >> 0;
+ if ( i_wb_sel[1] ) DEVST[15:8] <= i_wb_dat >> 8;
+ if ( i_wb_sel[2] ) DEVST[23:16] <= i_wb_dat >> 16;
+ if ( i_wb_sel[3] ) DEVST[31:24] <= i_wb_dat >> 24;
+ end
+
+ endcase
+
+ wbstate <= WBACK;
+ end
+
+ WBREAD:
+ begin
+ case(i_wb_adr)
+ `DEVEN: o_wb_dat <= DEVEN;
+ `DEVPR: o_wb_dat <= DEVPR;
+ `DEVAK: o_wb_dat <= done;
+ `DEVST: o_wb_dat <= 32'd0;
+ endcase
+
+ wbstate <= WBACK;
+ end
+
+ WBACK:
+ begin
+ o_wb_ack <= 1'd1;
+ wbstate <= WBDONE;
+ end
+
+ WBDONE:
+ begin
+ o_wb_ack <= 1'd0;
+ wbstate <= IDLE;
+ end
+ endcase
+ end
+end
+
+always @ (posedge i_clk)
+begin
+ if ( i_rst || !enable )
+ begin
+ ctr <= 0;
+ done <= 0;
+ state <= IDLE;
+ end
+ else // if enabled
+ begin
+ case(state)
+ IDLE:
+ begin
+ if ( start )
+ begin
+ $display($time," - %m :: Timer started counting...");
+ state <= COUNTING;
+ end
+ end
+
+ COUNTING:
+ begin
+ ctr <= ctr + 1;
+
+ if ( ctr == finalval )
+ begin
+ $display($time, " - %m :: Timer done counting...");
+ state <= DONE;
+ end
+ end
+
+ DONE:
+ begin
+ done <= 1;
+
+ if ( start )
+ begin
+ $display($time, " - %m :: Timer got START from DONE state...");
+ done <= 0;
+ state <= COUNTING;
+ ctr <= 0;
+ end
+ else if ( clr ) // Acknowledge.
+ begin
+ $display($time, " - %m :: Timer got done in ACK state...");
+ done <= 0;
+ state <= IDLE;
+ ctr <= 0;
+ end
+ end
+ endcase
+ end
+end
+
+endmodule
+
+`default_nettype wire
Index: zap/trunk/src/testbench/uart_rx_logger.v
===================================================================
--- zap/trunk/src/testbench/uart_rx_logger.v (nonexistent)
+++ zap/trunk/src/testbench/uart_rx_logger.v (revision 43)
@@ -0,0 +1,90 @@
+// -----------------------------------------------------------------------------
+// -- --
+// -- (C) 2016-2018 Revanth Kamaraj. --
+// -- --
+// -- --------------------------------------------------------------------------
+// -- --
+// -- This program is free software; you can redistribute it and/or --
+// -- modify it under the terms of the GNU General Public License --
+// -- as published by the Free Software Foundation; either version 2 --
+// -- of the License, or (at your option) any later version. --
+// -- --
+// -- This program is distributed in the hope that it will be useful, --
+// -- but WITHOUT ANY WARRANTY; without even the implied warranty of --
+// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
+// -- GNU General Public License for more details. --
+// -- --
+// -- You should have received a copy of the GNU General Public License --
+// -- along with this program; if not, write to the Free Software --
+// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
+// -- 02110-1301, USA. --
+// -- --
+// -----------------------------------------------------------------------------
+
+`default_nettype none
+
+//
+// P = 0 UART0 P = 1 UART1
+//
+// Assumes no parity, 8 bits per character and
+// 1 stop bit.
+//
+// Gets UART characters from file and serializes them.
+//
+// If UART0, output file is `UART0_FILE_PATH_RX
+// If UART1, output file is `UART1_FILE_PATH_RX
+//
+
+module uart_rx_logger #(parameter [0:0] P = 0 ) ( input wire i_clk, output reg o_line = 1'd1 );
+
+integer signed fh;
+reg feof;
+integer signed wchar;
+
+initial
+begin
+ if ( P == 0 )
+ fh = $fopen(`UART0_FILE_PATH_RX, "r+");
+ else
+ fh = $fopen(`UART1_FILE_PATH_RX, "r+");
+
+ if ( fh == 0 )
+ begin
+ $display($time, " - %m :: Error: Failed to open UART input stream. Handle = %d", fh);
+ $finish;
+ end
+
+ while ( 1 )
+ begin
+ wchar = $fgetc(fh);
+
+ if ( wchar != -1 )
+ write_to_uart (wchar);
+ else
+ begin
+ @(posedge i_clk);
+ end
+ end
+end
+
+task write_to_uart ( input integer signed wchar );
+begin
+ repeat(16) @(posedge i_clk) o_line <= 1'd0;
+ repeat(16) @(posedge i_clk) o_line <= wchar[0];
+ repeat(16) @(posedge i_clk) o_line <= wchar[1];
+ repeat(16) @(posedge i_clk) o_line <= wchar[2];
+ repeat(16) @(posedge i_clk) o_line <= wchar[3];
+ repeat(16) @(posedge i_clk) o_line <= wchar[4];
+ repeat(16) @(posedge i_clk) o_line <= wchar[5];
+ repeat(16) @(posedge i_clk) o_line <= wchar[6];
+ repeat(16) @(posedge i_clk) o_line <= wchar[7];
+
+ // Wait 1K clocks between input bytes.
+ repeat(1024) @(posedge i_clk) o_line <= 1'd1;
+end
+endtask
+
+endmodule // uart_rx_logger
+
+`default_nettype wire
+
Index: zap/trunk/src/testbench/uart_tx_dumper.v
===================================================================
--- zap/trunk/src/testbench/uart_tx_dumper.v (nonexistent)
+++ zap/trunk/src/testbench/uart_tx_dumper.v (revision 43)
@@ -0,0 +1,143 @@
+// -----------------------------------------------------------------------------
+// -- --
+// -- (C) 2016-2018 Revanth Kamaraj. --
+// -- --
+// -- --------------------------------------------------------------------------
+// -- --
+// -- This program is free software; you can redistribute it and/or --
+// -- modify it under the terms of the GNU General Public License --
+// -- as published by the Free Software Foundation; either version 2 --
+// -- of the License, or (at your option) any later version. --
+// -- --
+// -- This program is distributed in the hope that it will be useful, --
+// -- but WITHOUT ANY WARRANTY; without even the implied warranty of --
+// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
+// -- GNU General Public License for more details. --
+// -- --
+// -- You should have received a copy of the GNU General Public License --
+// -- along with this program; if not, write to the Free Software --
+// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
+// -- 02110-1301, USA. --
+// -- --
+// -----------------------------------------------------------------------------
+
+`default_nettype none
+
+//
+// P = 0 UART0 P = 1 UART1
+//
+// Assumes no parity, 8 bits per character and
+// 1 stop bit.
+// Writes UART output to a file.
+//
+// If UART0, output file is `UART0_FILE_PATH
+// If UART1, output file is `UART1_FILE_PATH
+//
+
+module uart_tx_dumper #(parameter [0:0] P = 0 ) ( input wire i_clk, input wire i_line );
+
+localparam UART_WAIT_FOR_START = 0;
+localparam UART_RX = 1;
+localparam UART_STOP_BIT = 2;
+
+integer uart_state = UART_WAIT_FOR_START;
+reg uart_sof = 1'd0;
+reg uart_eof = 1'd0;
+integer uart_ctr = 0;
+integer uart_bit_ctr = 1'dx;
+reg [7:0] uart_sr = 0;
+reg [7:0] UART_SR = 0;
+reg UART_SR_DAV = 0;
+wire uart;
+integer signed fh;
+
+assign uart = i_line;
+
+always @ ( posedge i_clk )
+begin
+ UART_SR_DAV = 1'd0;
+ uart_sof = 1'd0;
+ uart_eof = 1'd0;
+
+ case ( uart_state )
+ UART_WAIT_FOR_START:
+ begin
+ if ( !uart )
+ begin
+ uart_ctr = uart_ctr + 1;
+ uart_sof = 1'd1;
+ end
+
+ if ( !uart && uart_ctr == 16 )
+ begin
+ uart_sof = 1'd0;
+ uart_state = UART_RX;
+ uart_ctr = 0;
+ uart_bit_ctr = 0;
+ end
+ end
+
+ UART_RX:
+ begin
+ uart_ctr++;
+
+ if ( uart_ctr == 2 )
+ uart_sr = uart_sr >> 1 | uart << 7;
+
+ if ( uart_ctr == 16 )
+ begin
+ uart_bit_ctr++;
+ uart_ctr = 0;
+
+ if ( uart_bit_ctr == 8 )
+ begin
+ uart_state = UART_STOP_BIT;
+ UART_SR = uart_sr;
+ UART_SR_DAV = 1'd1;
+ uart_ctr = 0;
+ uart_bit_ctr = 0;
+ end
+ end
+ end
+
+ UART_STOP_BIT:
+ begin
+ uart_ctr++;
+
+ if ( uart && uart_ctr == 16 ) // Stop bit.
+ begin
+ uart_state = UART_WAIT_FOR_START;
+ uart_bit_ctr = 0;
+ uart_ctr = 0;
+ end
+ end
+ endcase
+end
+
+initial
+begin
+ if ( P == 0 )
+ fh = $fopen(`UART0_FILE_PATH_TX, "w");
+ else
+ fh = $fopen(`UART1_FILE_PATH_TX, "w");
+
+ if ( fh == -1 )
+ begin
+ $display($time, " - %m :: Error: Failed to open UART output log.");
+ $finish;
+ end
+end
+
+always @ (negedge i_clk)
+begin
+ if ( UART_SR_DAV )
+ begin
+ $display("UART Wrote %c", UART_SR);
+ $fwrite(fh, "%c", UART_SR);
+ $fflush(fh);
+ end
+end
+
+endmodule // uart_tx_dumper
+
+`default_nettype wire
Index: zap/trunk/src/testbench/vic.v
===================================================================
--- zap/trunk/src/testbench/vic.v (nonexistent)
+++ zap/trunk/src/testbench/vic.v (revision 43)
@@ -0,0 +1,188 @@
+// -----------------------------------------------------------------------------
+// -- --
+// -- (C) 2016-2018 Revanth Kamaraj. --
+// -- --
+// -- --------------------------------------------------------------------------
+// -- --
+// -- This program is free software; you can redistribute it and/or --
+// -- modify it under the terms of the GNU General Public License --
+// -- as published by the Free Software Foundation; either version 2 --
+// -- of the License, or (at your option) any later version. --
+// -- --
+// -- This program is distributed in the hope that it will be useful, --
+// -- but WITHOUT ANY WARRANTY; without even the implied warranty of --
+// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
+// -- GNU General Public License for more details. --
+// -- --
+// -- You should have received a copy of the GNU General Public License --
+// -- along with this program; if not, write to the Free Software --
+// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
+// -- 02110-1301, USA. --
+// -- --
+// -----------------------------------------------------------------------------
+// --
+// A simple interrupt controller. --
+// --
+// Registers: --
+// 0x0 - INT_STATUS - Interrupt status as reported by peripherals (sticky). --
+// 0x4 - INT_MASK - Interrupt mask - setting a bit to 1 masks the interrupt --
+// 0x8 - INT_CLEAR - Write 1 to a particular bit to clear the interrupt --
+// status. --
+//------------------------------------------------------------------------------
+
+`default_nettype none
+
+module vic #(
+ parameter [31:0] SOURCES = 32'd4,
+ parameter [31:0] INTERRUPT_PENDING_REGISTER = 32'h0,
+ parameter [31:0] INTERRUPT_MASK_REGISTER = 32'h4,
+ parameter [31:0] INTERRUPT_CLEAR_REGISTER = 32'h8
+) (
+
+// Clock and reset.
+input wire i_clk,
+input wire i_rst,
+
+// Wishbone interface.
+input wire [31:0] i_wb_dat,
+input wire [3:0] i_wb_adr,
+input wire i_wb_stb,
+input wire i_wb_cyc,
+input wire i_wb_wen,
+input wire [3:0] i_wb_sel,
+output reg [31:0] o_wb_dat,
+output reg o_wb_ack,
+
+// Interrupt sources in. Concatenate all
+// sources together.
+input wire [SOURCES-1:0] i_irq,
+
+// Interrupt output. Level interrupt.
+output reg o_irq
+
+
+);
+
+`ifndef ZAP_SOC_VIC
+`define ZAP_SOC_VIC
+ `define INT_STATUS INTERRUPT_PENDING_REGISTER
+ `define INT_MASK INTERRUPT_MASK_REGISTER
+ `define INT_CLEAR INTERRUPT_CLEAR_REGISTER
+`endif
+
+reg [31:0] INT_STATUS;
+reg [31:0] INT_MASK;
+reg [31:0] wbstate;
+
+// Wishbone states.
+localparam WBIDLE = 0;
+localparam WBREAD = 1;
+localparam WBWRITE = 2;
+localparam WBACK = 3;
+localparam WBDONE = 4;
+
+// Send out a global interrupt signal.
+always @ (posedge i_clk)
+begin
+ o_irq <= | ( INT_STATUS & ~INT_MASK );
+end
+
+// Wishbone access FSM
+always @ ( posedge i_clk )
+begin
+ if ( i_rst )
+ begin
+ wbstate <= WBIDLE;
+ o_wb_dat <= 0;
+ o_wb_ack <= 0;
+ INT_MASK <= 32'hffffffff;
+ INT_STATUS <= 32'h0;
+ end
+ else
+ begin:blk1
+ integer i;
+
+ // Normally record interrupts. These are sticky bits.
+ for(i=0;i> 0;
+ if ( i_wb_sel[1] ) INT_MASK[15:8] <= i_wb_dat >> 8;
+ if ( i_wb_sel[2] ) INT_MASK[23:16] <= i_wb_dat >> 16;
+ if ( i_wb_sel[3] ) INT_MASK[31:24] <= i_wb_dat >> 24;
+
+ end
+
+ `INT_CLEAR: // INT_CLEAR
+ begin: blk22
+ integer i;
+
+ $display($time, " - %m :: Writing to INT_CLEAR register...");
+ if ( i_wb_sel[0] ) for(i=0; i <=7;i=i+1) if ( i_wb_dat[i] ) INT_STATUS[i] <= 1'd0;
+ if ( i_wb_sel[1] ) for(i=8; i<=15;i=i+1) if ( i_wb_dat[i] ) INT_STATUS[i] <= 1'd0;
+ if ( i_wb_sel[2] ) for(i=16;i<=23;i=i+1) if ( i_wb_dat[i] ) INT_STATUS[i] <= 1'd0;
+ if ( i_wb_sel[3] ) for(i=24;i<=31;i=i+1) if ( i_wb_dat[i] ) INT_STATUS[i] <= 1'd0;
+ end
+
+ default: $display($time, " - %m :: Warning: Attemting to write to illgal register...");
+
+ endcase
+
+ wbstate <= WBACK;
+ end
+
+ WBREAD:
+ begin
+ case(i_wb_adr)
+ `INT_STATUS: o_wb_dat <= `INT_STATUS;
+ `INT_MASK: o_wb_dat <= `INT_MASK;
+
+ default:
+ begin
+ $display($time, " - %m --> Warning: Attempting to read from illegal register. Will return 0...");
+ o_wb_dat <= 0;
+ end
+ endcase
+
+ wbstate <= WBACK;
+ end
+
+ WBACK:
+ begin
+ o_wb_ack <= 1'd1;
+ wbstate <= WBDONE;
+ end
+
+ WBDONE:
+ begin
+ o_wb_ack <= 1'd0;
+ wbstate <= WBIDLE;
+ end
+ endcase
+ end
+end
+
+endmodule // vic
+
+`default_nettype wire
Index: zap/trunk/src/testbench/zap_tb.v
===================================================================
--- zap/trunk/src/testbench/zap_tb.v (nonexistent)
+++ zap/trunk/src/testbench/zap_tb.v (revision 43)
@@ -0,0 +1,183 @@
+// -----------------------------------------------------------------------------
+// -- --
+// -- (C) 2016-2018 Revanth Kamaraj. --
+// -- --
+// -- --------------------------------------------------------------------------
+// -- --
+// -- This program is free software; you can redistribute it and/or --
+// -- modify it under the terms of the GNU General Public License --
+// -- as published by the Free Software Foundation; either version 2 --
+// -- of the License, or (at your option) any later version. --
+// -- --
+// -- This program is distributed in the hope that it will be useful, --
+// -- but WITHOUT ANY WARRANTY; without even the implied warranty of --
+// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
+// -- GNU General Public License for more details. --
+// -- --
+// -- You should have received a copy of the GNU General Public License --
+// -- along with this program; if not, write to the Free Software --
+// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
+// -- 02110-1301, USA. --
+// -- --
+// -----------------------------------------------------------------------------
+
+
+`default_nettype none
+`include "zap_defines.vh"
+
+module zap_test;
+
+// CPU config.
+parameter RAM_SIZE = 32768;
+parameter DATA_SECTION_TLB_ENTRIES = 4;
+parameter DATA_LPAGE_TLB_ENTRIES = 8;
+parameter DATA_SPAGE_TLB_ENTRIES = 16;
+parameter DATA_CACHE_SIZE = 1024;
+parameter CODE_SECTION_TLB_ENTRIES = 4;
+parameter CODE_LPAGE_TLB_ENTRIES = 8;
+parameter CODE_SPAGE_TLB_ENTRIES = 16;
+parameter CODE_CACHE_SIZE = 1024;
+parameter FIFO_DEPTH = 4;
+parameter BP_ENTRIES = 1024;
+parameter STORE_BUFFER_DEPTH = 32;
+
+// TB related.
+parameter START = 1992;
+parameter COUNT = 120;
+
+// Variables
+reg i_clk = 1'd0;
+reg i_reset = 1'd0;
+wire [1:0] uart_in;
+wire [1:0] uart_out;
+integer i;
+reg [3:0] clk_ctr = 4'd0;
+integer seed = `SEED;
+integer seed_new = `SEED + 1;
+
+// Clock generator.
+always #10 i_clk = !i_clk;
+
+wire w_wb_stb;
+wire w_wb_cyc;
+wire [31:0] w_wb_dat_to_ram;
+wire [31:0] w_wb_adr;
+wire [3:0] w_wb_sel;
+wire w_wb_we;
+wire w_wb_ack;
+wire [31:0] w_wb_dat_from_ram;
+
+// DUT
+chip_top #(
+ .FIFO_DEPTH(FIFO_DEPTH),
+ .BP_ENTRIES(BP_ENTRIES),
+ .STORE_BUFFER_DEPTH(STORE_BUFFER_DEPTH),
+ .DATA_SECTION_TLB_ENTRIES(DATA_SECTION_TLB_ENTRIES),
+ .DATA_LPAGE_TLB_ENTRIES(DATA_LPAGE_TLB_ENTRIES),
+ .DATA_SPAGE_TLB_ENTRIES(DATA_SPAGE_TLB_ENTRIES),
+ .DATA_CACHE_SIZE(DATA_CACHE_SIZE),
+ .CODE_SECTION_TLB_ENTRIES(CODE_SECTION_TLB_ENTRIES),
+ .CODE_LPAGE_TLB_ENTRIES(CODE_LPAGE_TLB_ENTRIES),
+ .CODE_SPAGE_TLB_ENTRIES(CODE_SPAGE_TLB_ENTRIES),
+ .CODE_CACHE_SIZE(CODE_CACHE_SIZE)
+
+) u_chip_top (
+ .SYS_CLK (i_clk),
+ .SYS_RST (i_reset),
+ .UART0_RXD(uart_in[0]),
+ .UART0_TXD(uart_out[0]),
+ .UART1_RXD(uart_in[1]),
+ .UART1_TXD(uart_out[1]),
+ .I_IRQ (28'd0),
+ .I_FIQ (1'd0),
+ .O_WB_STB (w_wb_stb),
+ .O_WB_CYC (w_wb_cyc),
+ .O_WB_DAT (w_wb_dat_to_ram),
+ .O_WB_ADR (w_wb_adr),
+ .O_WB_SEL (w_wb_sel),
+ .O_WB_WE (w_wb_we),
+ .I_WB_ACK (w_wb_ack),
+ .I_WB_DAT (w_wb_dat_from_ram)
+);
+
+// RAM
+ram #(.SIZE_IN_BYTES(RAM_SIZE)) u_ram (
+ .i_clk(i_clk),
+ .i_wb_stb (w_wb_stb),
+ .i_wb_cyc (w_wb_cyc),
+ .i_wb_dat (w_wb_dat_to_ram),
+ .i_wb_adr (w_wb_adr),
+ .i_wb_sel (w_wb_sel),
+ .i_wb_we (w_wb_we),
+ .o_wb_ack (w_wb_ack),
+ .o_wb_dat (w_wb_dat_from_ram)
+);
+
+// UART 0 dumper.
+uart_tx_dumper #(.P(0)) UARTTX0 (
+ .i_clk (i_clk),
+ .i_line (uart_out[0])
+);
+
+// UART 1 dumper.
+uart_tx_dumper #(.P(1)) UARTTX1 (
+ .i_clk (i_clk),
+ .i_line (uart_out[1])
+);
+
+// UART 0 logger.
+uart_rx_logger #(.P(0)) UARTRX0 (
+ .i_clk (i_clk),
+ .o_line (uart_in[0])
+);
+
+// UART 1 logger.
+uart_rx_logger #(.P(1)) UARTRX1 (
+ .i_clk (i_clk),
+ .o_line (uart_in[1])
+);
+
+// Run for MAX_CLOCK_CYCLES
+initial
+begin
+ $display("SEED in decimal = %d", `SEED );
+ $display("parameter RAM_SIZE = %d", RAM_SIZE );
+ $display("parameter START = %d", START );
+ $display("parameter COUNT = %d", COUNT );
+ $display("parameter FIFO_DEPTH = %d", u_chip_top.FIFO_DEPTH );
+ $display("parameter DATA_SECTION_TLB_ENTRIES = %d", DATA_SECTION_TLB_ENTRIES ) ;
+ $display("parameter DATA_LPAGE_TLB_ENTRIES = %d", DATA_LPAGE_TLB_ENTRIES ) ;
+ $display("parameter DATA_SPAGE_TLB_ENTRIES = %d", DATA_SPAGE_TLB_ENTRIES ) ;
+ $display("parameter DATA_CACHE_SIZE = %d", DATA_CACHE_SIZE ) ;
+ $display("parameter CODE_SECTION_TLB_ENTRIES = %d", CODE_SECTION_TLB_ENTRIES ) ;
+ $display("parameter CODE_LPAGE_TLB_ENTRIES = %d", CODE_LPAGE_TLB_ENTRIES ) ;
+ $display("parameter CODE_SPAGE_TLB_ENTRIES = %d", CODE_SPAGE_TLB_ENTRIES ) ;
+ $display("parameter CODE_CACHE_SIZE = %d", CODE_CACHE_SIZE ) ;
+ $display("parameter STORE_BUFFER_DEPTH = %d", STORE_BUFFER_DEPTH ) ;
+
+ `ifdef WAVES
+ $dumpfile(`VCD_FILE_PATH);
+ $dumpvars;
+ `endif
+
+ @(posedge i_clk);
+ i_reset <= 1;
+ @(posedge i_clk);
+ i_reset <= 0;
+
+ if (`MAX_CLOCK_CYCLES == 0 )
+ begin
+ forever @(negedge i_clk);
+ end
+ else
+ begin
+ repeat(`MAX_CLOCK_CYCLES)
+ @(negedge i_clk);
+ end
+
+ `include "zap_check.vh"
+end
+
+endmodule // zap_tb
+
+`default_nettype wire
Index: zap/trunk/src/ts/uart_tx/uart.c
===================================================================
--- zap/trunk/src/ts/uart_tx/uart.c (revision 42)
+++ zap/trunk/src/ts/uart_tx/uart.c (nonexistent)
@@ -1,38 +0,0 @@
-#include "uart.h"
-
-void UARTInit()
-{
- *UART_LCR = (*UART_LCR) | (1 << 7);
- *UART_DLAB1 = 1;
- *UART_DLAB2 = 0;
- *UART_LCR = (*UART_LCR) & ~(1 << 7);
- return 0;
-}
-
-void UARTWrite(char* s)
-{
- int len;
-
- len = strlen(s);
-
- for(int i=0;i 4096, # Data cache size in bytes
- CODE_CACHE_SIZE => 4096, # Instruction cache size in bytes
- CODE_SECTION_TLB_ENTRIES => 8, # Instruction section TLB entries.
- CODE_SPAGE_TLB_ENTRIES => 32, # Instruction small page TLB entries.
- CODE_LPAGE_TLB_ENTRIES => 16, # Instruction large page TLB entries.
- DATA_SECTION_TLB_ENTRIES => 8, # Data section TLB entries.
- DATA_SPAGE_TLB_ENTRIES => 32, # Data small page TLB entries.
- DATA_LPAGE_TLB_ENTRIES => 16, # Data large page TLB entries.
- BP_DEPTH => 1024, # Branch predictor depth.
- INSTR_FIFO_DEPTH => 4, # Instruction buffer depth.
- STORE_BUFFER_DEPTH => 16, # Store buffer depth.
- SYNTHESIS => 0, # 0 allows debug messages.
-
- # Testbench configuration.
- IRQ_EN => 0,
- UART_TX_TERMINAL => 1, # Show TX terminal.
- EXT_RAM_SIZE => 32768, # External RAM size.
- SEED => -1, # Seed. Use -1 to use random seed.
- DUMP_START => 2000, # Starting memory address from which to dump.
- DUMP_SIZE => 200, # Length of dump in bytes.
- IRQ_EN => 0, # Make this 1 to enable IRQ signal from TB.
- FIQ_EN => 0, # Make this 1 to enable FIQ signal from TB.
- MAX_CLOCK_CYCLES => 150000, # Clock cycles to run the simulation for.
- ALLOW_STALLS => 1, # Make this 1 to allow external RAM to signal a stall.
- DEFINE_TLB_DEBUG => 0, # Make this 1 to define TLB_DEBUG. Useful for debugging the TLB.
- REG_CHECK => {},
- FINAL_CHECK => {}
-);
-
Index: zap/trunk/src/ts/uart_tx/main.c
===================================================================
--- zap/trunk/src/ts/uart_tx/main.c (revision 42)
+++ zap/trunk/src/ts/uart_tx/main.c (nonexistent)
@@ -1,15 +0,0 @@
-#include "uart.h"
-
-char* str = "Hello\n";
-
-int main(void)
-{
- int i;
-
- UARTInit();
- UARTWrite(str);
- UARTWrite("World");
- return 0;
-}
-
-
Index: zap/trunk/src/ts/uart_tx/uart.ld
===================================================================
--- zap/trunk/src/ts/uart_tx/uart.ld (revision 42)
+++ zap/trunk/src/ts/uart_tx/uart.ld (nonexistent)
@@ -1,16 +0,0 @@
-
-/* Linker Script */
-
-ENTRY(_Reset) /* _Reset is the entry point. This is the entry point in the bootstrap assembler */
-
-/* Define how sections of the program are organized. */
-SECTIONS
-{
- . = 0x00000; /* Location Counter. */
- .text : { *(.text) } /* Text section is expected to be starting at 0x0.*/
- .data : { *(.data) } /* Immediately followed by data section */
- .bss : { *(.bss) *(COMMON) } /* Immediately followed by BSS section. Common sections are also included in BSS. */
- . = ALIGN(8); /* Align the location counter. */
- . = . + 0x1000; /* 4kB of descending stack memory */
- stack_top = .; /* Make stack_top same as location counter. */
-}
Index: zap/trunk/src/ts/arm_test/Config.cfg
===================================================================
--- zap/trunk/src/ts/arm_test/Config.cfg (revision 42)
+++ zap/trunk/src/ts/arm_test/Config.cfg (revision 43)
@@ -16,14 +16,12 @@
SYNTHESIS => 0, # 0 allows debug messages.
# Testbench configuration.
- IRQ_EN => 0,
- UART_TX_TERMINAL => 0, # Disable UART TX terminal.
+ WAVES => 0, # Log VCD
EXT_RAM_SIZE => 32768, # External RAM size.
SEED => -1, # Seed. Use -1 to use random seed.
DUMP_START => 2000, # Starting memory address from which to dump.
DUMP_SIZE => 200, # Length of dump in bytes.
- MAX_CLOCK_CYCLES => 100000, # Clock cycles to run the simulation for.
- ALLOW_STALLS => 1, # Make this 1 to allow external RAM to signal a stall.
+ MAX_CLOCK_CYCLES => 40000, # Clock cycles to run the simulation for.
DEFINE_TLB_DEBUG => 0, # Make this 1 to define TLB_DEBUG. Useful for debugging the TLB.
REG_CHECK => {
# Value of registers(Post Translate) at the end of the test.
/zap/trunk/src/ts/factorial/Config.cfg
16,14 → 16,12
SYNTHESIS => 0, # 0 allows debug messages. |
|
# Testbench configuration. |
IRQ_EN => 1, # Enable IRQs. |
UART_TX_TERMINAL => 0, # No UART terminal. |
WAVES => 1, |
EXT_RAM_SIZE => 32768, # External RAM size. |
SEED => -1, # Seed. Use -1 to use random seed. |
DUMP_START => 2000, # Starting memory address from which to dump. |
DUMP_SIZE => 200, # Length of dump in bytes. |
MAX_CLOCK_CYCLES => 100000, # Clock cycles to run the simulation for. |
ALLOW_STALLS => 0, # Make this 1 to allow external RAM to signal a stall. |
MAX_CLOCK_CYCLES => 6500, # Clock cycles to run the simulation for. |
DEFINE_TLB_DEBUG => 0, # Make this 1 to define TLB_DEBUG. Useful for debugging the TLB. |
REG_CHECK => {}, # Registers to examine. |
FINAL_CHECK => { |
/zap/trunk/src/ts/factorial/Description.txt
2,5 → 2,6
the value 3.14 to a memory location. This setup uses the MMU but is set up for |
identity mapping using sections. IRQs are generated using the timer in the |
testbench. At the end an SWI is called which performs a bunch of multiplications |
and serial load/store. |
and serial load/store. FIQs are enabled in testbench to be periodically generated |
every 256 clock cycles. |
|
/zap/trunk/src/ts/factorial/factorial.s
59,37 → 59,40
mov r12, #14 |
mov r14, #15 |
|
.set TIMER_BASE_ADDRESS, 0xFFFFFFC0 |
|
# Restart timer |
ldr r0 ,=#0xFFFFFFC0 // Timer base address. |
ldr r0,=TIMER_BASE_ADDRESS // Timer base address. |
add r0, r0, #12 |
ldr r1, =#0x1 |
str r1, [r0] // Restart the timer. |
mov r1, #1 |
str r1, [r0] // Restart the timer. |
|
.set VIC_BASE_ADDRESS, 0xFFFFFFA0 |
.set CLEAR_ALL_PENDING, 0xFFFFFFFF |
|
# Clear interrupt in VIC. |
ldr r0, =#0xFFFFFFA0 // VIC base address |
ldr r0, =VIC_BASE_ADDRESS // VIC base address |
add r0, r0, #8 |
ldr r1, =#0xFFFFFFFF |
str r1, [r0] // Clear all interrupt pending status |
ldr r1, =CLEAR_ALL_PENDING |
str r1, [r0] // Clear all interrupt pending status |
|
# Restore |
ldmfd sp!, {r0-r12, pc}^ |
|
FIQ: |
# Return from FIQ after writing to FIQ registers. |
# Return from FIQ after writing to FIQ registers - shouldn't affect other things. |
mov r8, #9 |
mov r9, #10 |
mov r10, #12 |
mov r11, #13 |
mov r12, #14 |
mov r8, #0 |
mov r9, #0 |
mov r10, #0 |
mov r11, #10 |
mov r12, #0 |
subs pc, r14, #4 |
|
SWI: |
ldr sp,=#2500 |
ldr r11, =#2004 |
.set SWI_SP_VALUE, 2500 |
.set SWI_R11_VALUE, 2004 |
ldr sp,=SWI_SP_VALUE |
ldr r11,=SWI_R11_VALUE |
mov r0, #12 |
mov r1, #0 |
mov r2, r0, lsr #32 |
122,8 → 125,10
bic r2, r2, #31 |
orr r2, r2, #18 |
msr cpsr_c, r2 |
ldr sp, =#3000 |
|
.set IRQ_SP_VALUE, 3000 |
ldr sp,=IRQ_SP_VALUE |
|
// Switch to UND mode. |
mrs r3, cpsr |
bic r3, r3, #31 |
130,8 → 135,10
orr r3, r3, #27 |
msr cpsr_c, r3 |
mov r4, #1 |
ldr sp, =#3500 |
|
.set UND_SP_VALUE, 3500 |
ldr sp, =UND_SP_VALUE |
|
// Enable interrupts (FIQ and IRQ). |
mrs r1, cpsr |
bic r1, r1, #0xC0 |
138,7 → 145,8
msr cpsr_c, r1 |
|
// Enable cache (Uses a single bit to enable both caches). |
ldr r1, =#4100 |
.set ENABLE_CACHE_CP_WORD, 4100 |
ldr r1, =ENABLE_CACHE_CP_WORD |
mcr p15, 0, r1, c1, c1, 0 |
|
// Write out identitiy section mapping. Write 16KB to register 2. |
162,17 → 170,22
// This is identity mapping. Uncacheable. |
mov r1, #1 |
mov r1, r1, lsl #14 // 16KB. This is descriptor 0. |
|
// Go to descriptor 4095. This is the address BASE + (#DESC * 4). |
ldr r2,=#16380 |
.set DESCRIPTOR_IO_SECTION_OFFSET, 16380 // 4095 x 4 |
ldr r2,=DESCRIPTOR_IO_SECTION_OFFSET |
add r1, r1, r2 |
|
// Prepare a descriptor. Descriptor = 0xFFF00002 (Uncacheable section descriptor). |
ldr r2 ,=#0xFFF00002 |
.set DESCRIPTOR_IO_SECTION, 0xFFF00002 |
ldr r2 ,=DESCRIPTOR_IO_SECTION |
str r2, [r1] |
ldr r6, [r1] |
mov r7, r1 |
|
// ENABLE MMU |
ldr r1, =#4101 |
.set ENABLE_MMU_CP_WORD, 4101 |
ldr r1, =ENABLE_MMU_CP_WORD |
mcr p15, 0, r1, c1, c1, 0 |
|
// Switch mode. |
180,29 → 193,35
bic r2, r2, #31 |
orr r2, r2, #16 |
msr cpsr_c, r2 |
ldr sp,=#3500 |
|
.set USR_SP_VALUE, 4000 |
ldr sp,=USR_SP_VALUE |
|
// Run main loop. |
|
// Program VIC to allow timer interrupts. |
ldr r0, =#0xFFFFFFA0 // VIC base address. |
add r0, r0, #4 // Move to INT_MASK |
ldr r1, =#0x0 // Prepare mask value |
str r1, [r0] // Unmask all interrupt sources. |
ldr r0, =VIC_BASE_ADDRESS // VIC base address. |
add r0, r0, #4 // Move to INT_MASK |
mov r1, #0 // Prepare mask value |
str r1, [r0] // Unmask all interrupt sources. |
|
// Program timer peripheral to tick every 32 clock cycles. |
ldr r0 ,=#0xFFFFFFC0 // Timer base address. |
ldr r1 ,=#1 |
str r1, [r0] // Enable timer |
ldr r0 ,=TIMER_BASE_ADDRESS // Timer base address. |
mov r1 , #1 |
str r1, [r0] // Enable timer |
add r0, r0, #4 |
ldr r1, =#32 |
str r1, [r0] // Program to 255 clocks. |
mov r1, #32 |
str r1, [r0] // Program to 255 clocks. |
add r0, r0, #8 |
ldr r1, =#0x1 |
str r1, [r0] // Start the timer. |
mov r1, #0x1 |
str r1, [r0] // Start the timer. |
|
// Call C code |
bl main |
|
bl main |
// Do SWI 0x0 |
swi #0x00 |
|
// Loop forever |
here: b here |
|
/zap/trunk/src/ts/thumb_test/Config.cfg
16,17 → 16,11
SYNTHESIS => 0, # 0 allows debug messages. |
|
# Testbench configuration. |
IRQ_EN => 0, |
UART_TX_TERMINAL => 0, # 1 will open a UART TX terminal. |
EXT_RAM_SIZE => 32768, # External RAM size. |
SEED => -1, # Seed. Use -1 to use random seed. |
DUMP_START => 2000, # Starting memory address from which to dump. |
DUMP_SIZE => 200, # Length of dump in bytes. |
IRQ_EN => 0, # Make this 1 to enable IRQ signal from TB. |
FIQ_EN => 0, # Make this 1 to enable FIQ signal from TB. |
MAX_CLOCK_CYCLES => 1000, # Clock cycles to run the simulation for. |
ALLOW_STALLS => 1, # Make this 1 to allow external RAM to signal a stall. |
DEFINE_TLB_DEBUG => 0, # Make this 1 to define TLB_DEBUG. Useful for debugging the TLB. |
REG_CHECK => { |
"r0" => "32'hFFFFFFFF", |
"r1" => "32'd10", |
/zap/trunk/src/ts/thumb_test/thumb.s
1,12 → 1,14
.text |
.global _Reset |
.set SP_INIT, 4000 |
.set R0_FINAL_VALUE, 0xFFFFFFFF |
|
_Reset: |
ldr sp, =#4000 |
ldr sp, =SP_INIT |
ldr r0, =myThumbFunction+1 |
mov lr, pc |
bx r0 |
ldr r0, =#0xFFFFFFFF |
bx r0 // Jump to Thumb code |
ldr r0, =R0_FINAL_VALUE |
here: b here |
|
.thumb_func |
/zap/trunk/src/ts/uart/Config.cfg
0,0 → 1,30
# TC config. |
|
%Config = ( |
# CPU configuration. |
DATA_CACHE_SIZE => 4096, # Data cache size in bytes |
CODE_CACHE_SIZE => 4096, # Instruction cache size in bytes |
CODE_SECTION_TLB_ENTRIES => 8, # Instruction section TLB entries. |
CODE_SPAGE_TLB_ENTRIES => 32, # Instruction small page TLB entries. |
CODE_LPAGE_TLB_ENTRIES => 16, # Instruction large page TLB entries. |
DATA_SECTION_TLB_ENTRIES => 8, # Data section TLB entries. |
DATA_SPAGE_TLB_ENTRIES => 32, # Data small page TLB entries. |
DATA_LPAGE_TLB_ENTRIES => 16, # Data large page TLB entries. |
BP_DEPTH => 1024, # Branch predictor depth. |
INSTR_FIFO_DEPTH => 4, # Instruction buffer depth. |
STORE_BUFFER_DEPTH => 16, # Store buffer depth. |
SYNTHESIS => 0, # 0 allows debug messages. |
|
# Testbench configuration. |
WAVES => 1, # Generate waveform. |
UART0_TX_TERMINAL => 1, # Show TX terminal. |
UART0_RX_TERMINAL => 1, # Show RX terminal. |
EXT_RAM_SIZE => 32768, # External RAM size. |
SEED => -1, # Seed. Use -1 to use random seed. |
DUMP_START => 2000, # Starting memory address from which to dump. |
DUMP_SIZE => 200, # Length of dump in bytes. |
MAX_CLOCK_CYCLES => 0, # Clock cycles to run the simulation for. 0 is forever. |
REG_CHECK => {}, # No registers to check. |
FINAL_CHECK => {} # No memory locations to check. |
); |
|
/zap/trunk/src/ts/uart/Description.txt
0,0 → 1,2
This test enables RX and TX and echoes RX to the TX console. All this on UART0. |
TC runs forever. Use Ctrl+C to halt the TC. |
/zap/trunk/src/ts/uart/irq_handler.c
0,0 → 1,14
#include "uart.h" |
|
void irq_handler () |
{ |
// Wait for space to be available. |
while ( !UARTTransmitEmpty() ); |
|
// Write character |
UARTWriteByte ( UARTGetChar() ); |
|
// Clear interrupt pending register in VIC. |
*VIC_INT_CLEAR = 0xffffffff; |
} |
|
/zap/trunk/src/ts/uart/main.c
0,0 → 1,12
#include "uart.h" |
|
int main(void) |
{ |
// Just bringup the UART TX and RX - enable interrupts and exit. |
UARTInit(); |
UARTWrite("TX testing..."); |
UARTEnableRXInterrupt(); |
return 0; |
} |
|
|
/zap/trunk/src/ts/uart/makefile
0,0 → 1,2
# Execute the main Makefile. |
include ../../scripts/makefile |
/zap/trunk/src/ts/uart/uart.c
0,0 → 1,76
#include "uart.h" |
|
/* Sets up rate as 1 baud = 16 CPU clocks. Also resets TX and RX logic */ |
void UARTInit() |
{ |
// Set up frequency of operation. 1 bit time = 16 CPU clocks. |
*UART0_LCR = (*UART0_LCR) | (1 << 7); |
*UART0_DLAB1 = 1; |
*UART0_DLAB2 = 0; |
*UART0_LCR = (*UART0_LCR) & ~(1 << 7); |
|
// Enable TX and RX. |
UARTEnableTX(); |
UARTEnableRX(); |
} |
|
/* Write a string to the UART device. This is an open loop function. */ |
void UARTWrite(char* s) |
{ |
int len; |
int i; |
|
len = strlen(s); |
|
for(i=0;i<len;i++) { |
UARTWriteByte(s[i]); |
} |
} |
|
/* Write a byte to the UART. This is an open loop function. */ |
void UARTWriteByte(char c) |
{ |
*UART0_THR = c; |
} |
|
/* Length of a string */ |
int strlen(char* s) |
{ |
int i; |
i = 0; |
|
while(s[i] != '\0') |
i++; |
|
return i; |
} |
|
/* UART Enable RX interrupt */ |
void UARTEnableRXInterrupt (void) { |
*UART0_IER = *UART0_IER | 1; |
} |
|
/* Enable TX */ |
void UARTEnableTX (void) { |
*UART0_FCR = *UART0_FCR | 4; |
} |
|
/* Enablt RX */ |
void UARTEnableRX (void) { |
*UART0_FCR = *UART0_FCR | 1; |
} |
|
/* Check if transmit is empty */ |
int UARTTransmitEmpty (void) { |
char x = *UART0_LSR; |
|
if ( x & (1 << 6) ) |
return 1; |
else |
return 0; |
} |
|
/* Get a character from uart */ |
char UARTGetChar (void) { |
return *UART0_RBR; |
} |
/zap/trunk/src/ts/uart/uart.h
0,0 → 1,37
#ifndef UART_H |
#define UART_H |
|
// Non virtualized addresses for UART0 |
#define UART0_DLAB1 ((char*)0xFFFFFFE0) |
#define UART0_DLAB2 ((char*)0xFFFFFFE1) |
#define UART0_THR ((char*)0xFFFFFFE0) |
#define UART0_RBR ((char*)0xFFFFFFE0) |
#define UART0_IER ((char*)0xFFFFFFE1) |
#define UART0_FCR ((char*)0xFFFFFFE2) |
#define UART0_LCR ((char*)0xFFFFFFE3) |
#define UART0_LSR ((char*)0xFFFFFFE5) |
#define VIC_INT_CLEAR ( (int*)0xFFFFFFA8) |
|
// Initialization functions. |
void UARTInit(void); |
void UARTEnableTX(void); |
void UARTEnableRX(void); |
|
// Open loop functions. |
void UARTWrite(char*); |
void UARTWriteByte(char x); |
|
// UART interrupt related functions. |
void UARTEnableTXInterrupt(void); |
void UARTEnableRXInterrupt(void); |
|
// Check THRE |
int UARTTransmitEmpty(void); |
|
// Get a character from the UART. |
char UARTGetChar (void ); |
|
// String processing functions. |
int strlen(char*); |
|
#endif |
/zap/trunk/src/ts/uart/uart.ld
0,0 → 1,16
|
/* Linker Script */ |
|
ENTRY(_Reset) /* _Reset is the entry point. This is the entry point in the bootstrap assembler */ |
|
/* Define how sections of the program are organized. */ |
SECTIONS |
{ |
. = 0x00000; /* Location Counter. */ |
.text : { *(.text) } /* Text section is expected to be starting at 0x0.*/ |
.data : { *(.data) } /* Immediately followed by data section */ |
.bss : { *(.bss) *(COMMON) } /* Immediately followed by BSS section. Common sections are also included in BSS. */ |
. = ALIGN(8); /* Align the location counter. */ |
. = . + 0x1000; /* 4kB of descending stack memory */ |
stack_top = .; /* Make stack_top same as location counter. */ |
} |
/zap/trunk/src/ts/uart/uart.s
0,0 → 1,64
.set USER_STACK_POINTER, 0x00002000 |
.set IRQ_STACK_POINTER, 0x00003000 |
.set VIC_BASE_ADDRESS, 0xFFFFFFA0 |
|
.text |
.global _Reset |
_Reset: |
|
_Reset : b there |
_Undef : b _Undef |
_Swi : b _Swi |
_Pabt : b _Pabt |
_Dabt : b _Dabt |
reserved : b reserved |
irq : b IRQ |
fiq : b fiq |
|
/* |
* This handler simply revectors IRQs to |
* a dedicated irq_handler function. |
*/ |
IRQ: |
sub r14, r14, #4 |
stmfd sp!, {r0-r12, r14} |
bl irq_handler |
ldmfd sp!, {r0-r12, pc}^ |
|
there: |
/* |
* Switch to IRQ mode. |
* Set up stack pointer. |
*/ |
mrs r2, cpsr |
bic r2, r2, #31 |
orr r2, r2, #18 |
msr cpsr_c, r2 |
ldr sp, =IRQ_STACK_POINTER |
|
/* |
* Switch to user mode with interrupts enabled. |
* Set up stack pointer. |
*/ |
mrs r2, cpsr |
bic r1, r1, #31 |
orr r1, r1, #16 |
bic r1, r1, #0xC0 |
msr cpsr_c, r1 |
|
/* |
* Unmask all interrupts in the VIC. |
*/ |
ldr r0, =VIC_BASE_ADDRESS // VIC base address. |
add r0, r0, #4 // Move to INT_MASK |
mov r1, #0 // Prepare mask value |
str r1, [r0] // Unmask all interrupt sources. |
|
/* |
* Then call the main function. The main function |
* will initiallize UART0 in TX and RX. |
*/ |
ldr sp, =USER_STACK_POINTER |
bl main |
here: b here |
|
/zap/trunk/LICENSE
0,0 → 1,339
GNU GENERAL PUBLIC LICENSE |
Version 2, June 1991 |
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc., |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
Everyone is permitted to copy and distribute verbatim copies |
of this license document, but changing it is not allowed. |
|
Preamble |
|
The licenses for most software are designed to take away your |
freedom to share and change it. By contrast, the GNU General Public |
License is intended to guarantee your freedom to share and change free |
software--to make sure the software is free for all its users. This |
General Public License applies to most of the Free Software |
Foundation's software and to any other program whose authors commit to |
using it. (Some other Free Software Foundation software is covered by |
the GNU Lesser General Public License instead.) You can apply it to |
your programs, too. |
|
When we speak of free software, we are referring to freedom, not |
price. Our General Public Licenses are designed to make sure that you |
have the freedom to distribute copies of free software (and charge for |
this service if you wish), that you receive source code or can get it |
if you want it, that you can change the software or use pieces of it |
in new free programs; and that you know you can do these things. |
|
To protect your rights, we need to make restrictions that forbid |
anyone to deny you these rights or to ask you to surrender the rights. |
These restrictions translate to certain responsibilities for you if you |
distribute copies of the software, or if you modify it. |
|
For example, if you distribute copies of such a program, whether |
gratis or for a fee, you must give the recipients all the rights that |
you have. You must make sure that they, too, receive or can get the |
source code. And you must show them these terms so they know their |
rights. |
|
We protect your rights with two steps: (1) copyright the software, and |
(2) offer you this license which gives you legal permission to copy, |
distribute and/or modify the software. |
|
Also, for each author's protection and ours, we want to make certain |
that everyone understands that there is no warranty for this free |
software. If the software is modified by someone else and passed on, we |
want its recipients to know that what they have is not the original, so |
that any problems introduced by others will not reflect on the original |
authors' reputations. |
|
Finally, any free program is threatened constantly by software |
patents. We wish to avoid the danger that redistributors of a free |
program will individually obtain patent licenses, in effect making the |
program proprietary. To prevent this, we have made it clear that any |
patent must be licensed for everyone's free use or not licensed at all. |
|
The precise terms and conditions for copying, distribution and |
modification follow. |
|
GNU GENERAL PUBLIC LICENSE |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
|
0. This License applies to any program or other work which contains |
a notice placed by the copyright holder saying it may be distributed |
under the terms of this General Public License. The "Program", below, |
refers to any such program or work, and a "work based on the Program" |
means either the Program or any derivative work under copyright law: |
that is to say, a work containing the Program or a portion of it, |
either verbatim or with modifications and/or translated into another |
language. (Hereinafter, translation is included without limitation in |
the term "modification".) Each licensee is addressed as "you". |
|
Activities other than copying, distribution and modification are not |
covered by this License; they are outside its scope. The act of |
running the Program is not restricted, and the output from the Program |
is covered only if its contents constitute a work based on the |
Program (independent of having been made by running the Program). |
Whether that is true depends on what the Program does. |
|
1. You may copy and distribute verbatim copies of the Program's |
source code as you receive it, in any medium, provided that you |
conspicuously and appropriately publish on each copy an appropriate |
copyright notice and disclaimer of warranty; keep intact all the |
notices that refer to this License and to the absence of any warranty; |
and give any other recipients of the Program a copy of this License |
along with the Program. |
|
You may charge a fee for the physical act of transferring a copy, and |
you may at your option offer warranty protection in exchange for a fee. |
|
2. You may modify your copy or copies of the Program or any portion |
of it, thus forming a work based on the Program, and copy and |
distribute such modifications or work under the terms of Section 1 |
above, provided that you also meet all of these conditions: |
|
a) You must cause the modified files to carry prominent notices |
stating that you changed the files and the date of any change. |
|
b) You must cause any work that you distribute or publish, that in |
whole or in part contains or is derived from the Program or any |
part thereof, to be licensed as a whole at no charge to all third |
parties under the terms of this License. |
|
c) If the modified program normally reads commands interactively |
when run, you must cause it, when started running for such |
interactive use in the most ordinary way, to print or display an |
announcement including an appropriate copyright notice and a |
notice that there is no warranty (or else, saying that you provide |
a warranty) and that users may redistribute the program under |
these conditions, and telling the user how to view a copy of this |
License. (Exception: if the Program itself is interactive but |
does not normally print such an announcement, your work based on |
the Program is not required to print an announcement.) |
|
These requirements apply to the modified work as a whole. If |
identifiable sections of that work are not derived from the Program, |
and can be reasonably considered independent and separate works in |
themselves, then this License, and its terms, do not apply to those |
sections when you distribute them as separate works. But when you |
distribute the same sections as part of a whole which is a work based |
on the Program, the distribution of the whole must be on the terms of |
this License, whose permissions for other licensees extend to the |
entire whole, and thus to each and every part regardless of who wrote it. |
|
Thus, it is not the intent of this section to claim rights or contest |
your rights to work written entirely by you; rather, the intent is to |
exercise the right to control the distribution of derivative or |
collective works based on the Program. |
|
In addition, mere aggregation of another work not based on the Program |
with the Program (or with a work based on the Program) on a volume of |
a storage or distribution medium does not bring the other work under |
the scope of this License. |
|
3. You may copy and distribute the Program (or a work based on it, |
under Section 2) in object code or executable form under the terms of |
Sections 1 and 2 above provided that you also do one of the following: |
|
a) Accompany it with the complete corresponding machine-readable |
source code, which must be distributed under the terms of Sections |
1 and 2 above on a medium customarily used for software interchange; or, |
|
b) Accompany it with a written offer, valid for at least three |
years, to give any third party, for a charge no more than your |
cost of physically performing source distribution, a complete |
machine-readable copy of the corresponding source code, to be |
distributed under the terms of Sections 1 and 2 above on a medium |
customarily used for software interchange; or, |
|
c) Accompany it with the information you received as to the offer |
to distribute corresponding source code. (This alternative is |
allowed only for noncommercial distribution and only if you |
received the program in object code or executable form with such |
an offer, in accord with Subsection b above.) |
|
The source code for a work means the preferred form of the work for |
making modifications to it. For an executable work, complete source |
code means all the source code for all modules it contains, plus any |
associated interface definition files, plus the scripts used to |
control compilation and installation of the executable. However, as a |
special exception, the source code distributed need not include |
anything that is normally distributed (in either source or binary |
form) with the major components (compiler, kernel, and so on) of the |
operating system on which the executable runs, unless that component |
itself accompanies the executable. |
|
If distribution of executable or object code is made by offering |
access to copy from a designated place, then offering equivalent |
access to copy the source code from the same place counts as |
distribution of the source code, even though third parties are not |
compelled to copy the source along with the object code. |
|
4. You may not copy, modify, sublicense, or distribute the Program |
except as expressly provided under this License. Any attempt |
otherwise to copy, modify, sublicense or distribute the Program is |
void, and will automatically terminate your rights under this License. |
However, parties who have received copies, or rights, from you under |
this License will not have their licenses terminated so long as such |
parties remain in full compliance. |
|
5. You are not required to accept this License, since you have not |
signed it. However, nothing else grants you permission to modify or |
distribute the Program or its derivative works. These actions are |
prohibited by law if you do not accept this License. Therefore, by |
modifying or distributing the Program (or any work based on the |
Program), you indicate your acceptance of this License to do so, and |
all its terms and conditions for copying, distributing or modifying |
the Program or works based on it. |
|
6. Each time you redistribute the Program (or any work based on the |
Program), the recipient automatically receives a license from the |
original licensor to copy, distribute or modify the Program subject to |
these terms and conditions. You may not impose any further |
restrictions on the recipients' exercise of the rights granted herein. |
You are not responsible for enforcing compliance by third parties to |
this License. |
|
7. If, as a consequence of a court judgment or allegation of patent |
infringement or for any other reason (not limited to patent issues), |
conditions are imposed on you (whether by court order, agreement or |
otherwise) that contradict the conditions of this License, they do not |
excuse you from the conditions of this License. If you cannot |
distribute so as to satisfy simultaneously your obligations under this |
License and any other pertinent obligations, then as a consequence you |
may not distribute the Program at all. For example, if a patent |
license would not permit royalty-free redistribution of the Program by |
all those who receive copies directly or indirectly through you, then |
the only way you could satisfy both it and this License would be to |
refrain entirely from distribution of the Program. |
|
If any portion of this section is held invalid or unenforceable under |
any particular circumstance, the balance of the section is intended to |
apply and the section as a whole is intended to apply in other |
circumstances. |
|
It is not the purpose of this section to induce you to infringe any |
patents or other property right claims or to contest validity of any |
such claims; this section has the sole purpose of protecting the |
integrity of the free software distribution system, which is |
implemented by public license practices. Many people have made |
generous contributions to the wide range of software distributed |
through that system in reliance on consistent application of that |
system; it is up to the author/donor to decide if he or she is willing |
to distribute software through any other system and a licensee cannot |
impose that choice. |
|
This section is intended to make thoroughly clear what is believed to |
be a consequence of the rest of this License. |
|
8. If the distribution and/or use of the Program is restricted in |
certain countries either by patents or by copyrighted interfaces, the |
original copyright holder who places the Program under this License |
may add an explicit geographical distribution limitation excluding |
those countries, so that distribution is permitted only in or among |
countries not thus excluded. In such case, this License incorporates |
the limitation as if written in the body of this License. |
|
9. The Free Software Foundation may publish revised and/or new versions |
of the General Public License from time to time. Such new versions will |
be similar in spirit to the present version, but may differ in detail to |
address new problems or concerns. |
|
Each version is given a distinguishing version number. If the Program |
specifies a version number of this License which applies to it and "any |
later version", you have the option of following the terms and conditions |
either of that version or of any later version published by the Free |
Software Foundation. If the Program does not specify a version number of |
this License, you may choose any version ever published by the Free Software |
Foundation. |
|
10. If you wish to incorporate parts of the Program into other free |
programs whose distribution conditions are different, write to the author |
to ask for permission. For software which is copyrighted by the Free |
Software Foundation, write to the Free Software Foundation; we sometimes |
make exceptions for this. Our decision will be guided by the two goals |
of preserving the free status of all derivatives of our free software and |
of promoting the sharing and reuse of software generally. |
|
NO WARRANTY |
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
REPAIR OR CORRECTION. |
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGES. |
|
END OF TERMS AND CONDITIONS |
|
How to Apply These Terms to Your New Programs |
|
If you develop a new program, and you want it to be of the greatest |
possible use to the public, the best way to achieve this is to make it |
free software which everyone can redistribute and change under these terms. |
|
To do so, attach the following notices to the program. It is safest |
to attach them to the start of each source file to most effectively |
convey the exclusion of warranty; and each file should have at least |
the "copyright" line and a pointer to where the full notice is found. |
|
<one line to give the program's name and a brief idea of what it does.> |
Copyright (C) <year> <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., |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
|
Also add information on how to contact you by electronic and paper mail. |
|
If the program is interactive, make it output a short notice like this |
when it starts in an interactive mode: |
|
Gnomovision version 69, Copyright (C) year name of author |
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
This is free software, and you are welcome to redistribute it |
under certain conditions; type `show c' for details. |
|
The hypothetical commands `show w' and `show c' should show the appropriate |
parts of the General Public License. Of course, the commands you use may |
be called something other than `show w' and `show c'; they could even be |
mouse-clicks or menu items--whatever suits your program. |
|
You should also get your employer (if you work as a programmer) or your |
school, if any, to sign a "copyright disclaimer" for the program, if |
necessary. Here is a sample; alter the names: |
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
|
<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 Lesser General |
Public License instead of this License. |
/zap/trunk/README.md
1,64 → 1,194
## *ZAP* : An ARM compatible core with cache and MMU (ARMv4T ISA compatible) |
## The ZAP Soft Processor (ARMv5T Compatible) |
|
#### Author : Revanth Kamaraj (revanth91kamaraj@gmail.com) |
#### License : GPL v2 |
|
### Description |
### Introduction |
|
ZAP is a pipelined ARM processor core that can execute the ARMv4T instruction |
set. It is equipped with ARMv4 compatible split writeback caches and memory |
management capabilities. The processor core uses a 10 stage pipeline. |
The ZAP processor is a 10 stage pipelined processor for FPGA with support for cache and MMU (ARMv5T compliant). |
|
Note that ARM GCC is included in the repository in the *sw* directory. The |
makefile will extract the GCC compiler into the object folder. |
#### Features |
|
### Current Status |
##### ZAP Processor (zap_top.v) |
|
Experimental. |
The ZAP core is a pipelined ATMv5T processor for FPGA. |
|
### Bugs and Known Issues |
| Property | Description | |
|-----------------------|-------------------------| |
|HDL | Verilog-2001 | |
|Author | Revanth Kamaraj | |
|ARM v5T ISA Support | Fully compatible | |
|Branch Predictor | Direct mapped bimodal | |
|Write Buffer | Yes | |
|Abort Model | Base Restored | |
|Integrated v5T CP15 | Yes | |
|External Coproc. Bus | No | |
|Cache Interface | 128-Bit custom interface| |
|26-Bit Support | No | |
|L1 Code Cache | Direct mapped virtual | |
|L1 Data Cache | Direct mapped virtual | |
|Cache Write Policy | Writeback | |
|L1 Code TLB | Direct mapped | |
|L1 Data TLB | Direct mapped | |
|Bus Interface | 32-bit Wishbone B3 Linear incrementing burst | |
|Cache/TLB Lock Support | No | |
|CP15 Compliance | v5T (No fine pages) | |
|FCSE Support | Yes | |
|
- Issues with the Thumb ISA. |
- SWAP does not bypass cache. |
* 10-stage pipeline design. Pipeline has bypass network to resolve dependencies. Most operations execute at a rate of 1 operation per clock. |
* 2 write ports for the register file to allow LDR/STR with writeback to execute as a single instruction. |
|
### Bus Interface |
#### CPU Configuration (zap_top.v) |
|
| Parameter | Default| Description | |
|--------------------------|--------|-------------| |
| BP_ENTRIES | 1024 | Branch Predictor Settings. Predictor RAM depth. Must be 2^n and > 2 | |
| FIFO_DEPTH | 4 | Branch Predictor Settings. Command FIFO depth. Must be 2^n and > 2 | |
| STORE_BUFFER_DEPTH | 16 | Branch Predictor Settings. Depth of the store buffer. Must be 2^n and > 2 | |
| DATA_SECTION_TLB_ENTRIES | 4 | Data Cache/MMU Configuration. Section TLB entries. Must be 2^n (n > 0) | |
| DATA_LPAGE_TLB_ENTRIES | 8 | Data Cache/MMU Configuration. Large page TLB entries. Must be 2^n (n > 0) | |
| DATA_SPAGE_TLB_ENTRIES | 16 | Data Cache/MMU Configuration. Small page TLB entries. Must be 2^n (n > 0) | |
| DATA_CACHE_SIZE | 1024 | Data Cache/MMU Configuration. Cache size in bytes. Must be at least 256B and 2^n | |
| CODE_SECTION_TLB_ENTRIES | 4 | Instruction Cache/MMU Configuration. Section TLB entries. Must be 2^n (n > 0) | |
| CODE_LPAGE_TLB_ENTRIES | 8 | Instruction Cache/MMU Configuration. Large page TLB entries. Must be 2^n (n > 0) | |
| CODE_SPAGE_TLB_ENTRIES | 16 | Instruction Cache/MMU Configuration. Small page TLB entries. Must be 2^n (n > 0) | |
| CODE_CACHE_SIZE | 1024 | Instruction Cache/MMU Configuration. Cache size in bytes. Must be at least 256B and 2^n | |
|
#### CPU IO Interface (zap_top.v) |
|
Wishbone B3 compatible 32-bit bus. |
|
### Documentation |
| Dir | Size | Port | Description | |
|---------------|----------|--------------------|----------------------------------| |
| input | | i_clk | Clock | |
| input | | i_reset | Reset | |
| input | | i_irq | Interrupt. Level Sensitive. | |
| input | | i_fiq | Fast Interrupt. Level Sensitive.| |
| output | | o_wb_cyc | Wishbone B3 Signal | |
| output | | o_wb_stb | WIshbone B3 signal | |
| output | [31:0] | o_wb_adr | Wishbone B3 signal. | |
| output | | o_wb_we | Wishbone B3 signal. | |
| output | [31:0] | o_wb_dat | Wishbone B3 signal. | |
| output | [3:0] | o_wb_sel | Wishbone B3 signal. | |
| output | [2:0] | o_wb_cti | Wishbone B3 signal. Cycle Type Indicator (Supported modes: Incrementing Burst, End of Burst)| |
| output | [1:0] | o_wb_bte | Wishbone B3 signal. Burst Type Indicator (Supported modes: Linear) | |
| input | | i_wb_ack | Wishbone B3 signal. | |
| input | [31:0] | i_wb_dat | Wishbone B3 signal. | |
| output | | o_wb_stb_nxt | IGNORE THIS PORT. LEAVE OPEN. | |
| output | | o_wb_cyc_nxt | IGNORE THIS PORT. LEAVE OPEN. | |
| output | [31:0] | o_wb_adr_nxt | IGNORE THIS PORT. LEAVE OPEN. | |
|
Please see the PDF file at *doc/ZAP_PROCESSOR_CORE_DATASHEET.pdf* |
|
### Features |
### Getting Started |
*Tested on Ubuntu 16.04 LTS/18.04 LTS* |
|
- Fully synthesizable Verilog-2001 core. |
- Store buffer for improved performance. |
- Can execute ARMv4T code. Note that compressed instruction support is EXPERIMENTAL. |
- Wishbone B3 compatible interface. Cache unit supports burst access. |
- 10-stage pipeline design. Pipeline has bypass network to resolve dependencies. |
- 2 write ports for the register file to allow LDR/STR with writeback to execute as a single instruction. |
- Branch prediction supported. |
- Split I and D writeback cache (Size can be configured using parameters). |
- Split I and D MMUs (TLB size can be configured using parameters). |
- Base restored abort model to simplify data abort handling. |
#### Run Sample Tests |
|
### License |
Let the variable $test_name hold the name of the test. See the src/ts directory for some basic tests pre-installed. Available test names are: factorial, arm_test, thumb_test, uart. New tests can be added using these as starting templates. Please note that these will be run on the SOC platform (chip_top) that consist of the ZAP processor, 2 x UARTs, a VIC and a timer. |
|
(C) 2016-2018 Revanth Kamaraj. |
|
This program is free software; you can redistribute it and/or |
modify it under the terms of the GNU General Public License |
as published by the Free Software Foundation; either version 2 |
of the License, or (at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
02110-1301, USA. |
|
```bash |
sudo apt-get install sudo apt-get install gcc-arm-none-eabi binutils-arm-none-eabi gdb openocd iverilog gtkwave make perl xterm |
cd $PROJ_ROOT/src/ts/$test_name # $PROJ_ROOT is the project directory. |
make # Runs the test using IVerilog. |
cd $PROJ_ROOT/obj/ts/$test_name # Switch to object folder. |
gvim zap.log.gz # View the log file |
gtkwave zap.vcd.gz # Exists if selected by Config.cfg. See PDF document for more information. |
``` |
To use this processor in your SOC, instantiate this top level CPU module in your project: [CPU top file](/src/rtl/cpu/zap_top.v) |
|
### Implementation Specific Details |
|
#### FPGA Timing Performance (Vivado, Retime Enabled) |
|
| FPGA Part | Speed | Critical Path | |
|--------------------|-------|----------------| |
| xc7a35tiftg256-1L | 80MHz | Cache access | |
|
#### Coprocessor #15 Control Registers |
|
##### Register 0 : ID Register |
|
|Bits | Name | Description | |
|-----|---------|------------------------------------------| |
|31:0 | Various | Processor ID info. | |
|
##### Register 1 : Control |
|
|Bits | Name | Description | |
|-----|-----------|------------------------------------------| |
|0 | M | MMU Enable. Active high | |
|1 | A | Always 0. Alignment check off | |
|2 | D | Data Cache Enable. Active high | |
|3 | W | Always 1. Write Buffer always on. | |
|4 | P | Always 1. RESERVED | |
|5 | D | Always 1. RESERVED | |
|6 | L | Always 1. RESERVED | |
|7 | B | Always 0. Little Endian | |
|8 | S | The S bit | |
|9 | R | The R bit | |
|11 | Z | Always 1. Branch prediction enabled | |
|12 | I | Instruction Cache Enable. Active high | |
|13 | V | Normal Exception Vectors. Always 0 | |
|14 | RR | Always 1. Direct mapped cache. | |
|15 | L4 | Always 0. Normal behavior. | |
|
##### Register 2 : Translation Base Address |
|
|Bits | Name | Description | |
|-----|-----------|------------------------------------------| |
|13:0 | M | Preserve value. | |
|31:14| TTB | Upper 18-bits of translation address | |
|
##### Register 3 : Domain Access Control (X=0 to X=15) |
|
|Bits | Name | Description | |
|---------|-----------|------------------------------------------| |
|2X+1:2X | DX | DX access permission. | |
|
##### Register 5 : Fault Status Register |
|
|Bits | Name | Description | |
|-----|-----------|------------------------------------------| |
|3:0 | Status | Status. | |
|1:0 | Domain | Domain. | |
|11:8 | SBZ | Always 0. RESERVED | |
|
##### Register 6 : Fault Address Register |
|
|Bits | Name | Description | |
|-----|-----------|------------------------------------------| |
|31:0 | Addr | Fault Address. | |
|
##### Register 7 : Cache Functions |
|
| Opcode2 | CRm | Description | |
|-------------|-----------------|-------------------------------------| |
| 000 | 0111 | Flush all caches. | |
| 000 | 0101 | Flush I cache. | |
| 000 | 0110 | Flush D cache. | |
| 000 | 1011 | Clean all caches. | |
| 000 | 1010 | Clean D cache. | |
| 000 | 1111 | Clean and flush all caches. | |
| 000 | 1110 | Clean and flush D cache. | |
| Other | Other | Clean and flush ALL caches | |
|
|
##### Register 8 : TLB Functions |
|
|Opcode2 | CRm | Description | |
|--------|---------------|-------------------------| |
| 000 | 0111 | Flush all TLBs | |
| 000 | 0101 | Flush I TLB | |
| 000 | 0110 | Flush D TLB | |
| Other| Other | Flush all TLBs | |
|
##### Register 13 : FCSE Extentions |
|
| Field | Description | |
|-------|-------------| |
| 31:25 | PID | |
|
##### Lockdown Support |
* CPU memory system does not support lockdown. |
|
##### Tiny Pages |
* No support for tiny pages (1KB). |
/zap/trunk/makefile
0,0 → 1,9
.PHONY: clean |
.PHONY: error |
|
error: |
@echo "To run a TC, go to src/ts and do a make there. Only target supported here is 'clean'." |
|
clean: |
@echo "Removing object folder." |
rm -rf obj/ |