OpenCores
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 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/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/

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.