├── _config.yml ├── docs ├── apb_checker.pdf ├── tex │ ├── apb_checker │ │ ├── interfaces.tex │ │ ├── appendices.tex │ │ ├── references.tex │ │ ├── history.tex │ │ ├── preface.tex │ │ ├── specification.tex │ │ ├── introduction.tex │ │ ├── extending.tex │ │ ├── configuration.tex │ │ ├── interface-apb.tex │ │ └── rules.tex │ ├── setup.tex │ ├── preamble_appendix.tex │ └── preamble.tex ├── apb_checker.tex └── pkg │ └── roalogictitle.sty ├── README.md └── rtl └── verilog ├── apb4_bfm.sv ├── ahb3lite_bfm.sv ├── ahb3lite_pkg.sv ├── ahb_protocol_checker.sv └── apb_checker.sv /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-dinky -------------------------------------------------------------------------------- /docs/apb_checker.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoaLogic/ahb3lite_pkg/HEAD/docs/apb_checker.pdf -------------------------------------------------------------------------------- /docs/tex/apb_checker/interfaces.tex: -------------------------------------------------------------------------------- 1 | \chapter{Interfaces}\label{interfaces} 2 | 3 | \input{tex/apb_checker/interface-apb.tex} 4 | -------------------------------------------------------------------------------- /docs/tex/apb_checker/appendices.tex: -------------------------------------------------------------------------------- 1 | % 2 | % Appendices go here 3 | % 4 | % Remember: Appendices are 'section', not 'chapter' 5 | 6 | 7 | \appendix 8 | \doappendixstuff 9 | \newpage 10 | 11 | \input{tex/apb_checker/rules.tex} 12 | 13 | \input{tex/apb_checker/references.tex} 14 | 15 | \input{tex/apb_checker/history.tex} -------------------------------------------------------------------------------- /docs/tex/apb_checker/references.tex: -------------------------------------------------------------------------------- 1 | \begin{thebibliography}{100} % 100 is a random guess of the total number of references 2 | 3 | \setlength{\parskip}{0pt} 4 | \setlength{\itemsep}{0pt plus 0.3ex} 5 | 6 | %references 7 | \bibitem{ArmAPB} Arm Ltd., ``AMBA APB Protocol Specifications," 8 | \emph{\href{https://developer.arm.com/documentation/ihi0024/latest}{https://developer.arm.com/documentation/ihi0024/latest/}}, 2021. 9 | 10 | \end{thebibliography} -------------------------------------------------------------------------------- /docs/tex/apb_checker/history.tex: -------------------------------------------------------------------------------- 1 | \chapter{Revision History} 2 | 3 | \setlength\LTleft{0pt} 4 | \setlength\LTright{0pt} 5 | 6 | \begin{longtable}{@{\extracolsep{\fill}}ccp{8cm}@{}} 7 | \toprule 8 | \textbf{Date} & \textbf{Rev.} & \textbf{Comments}\\ 9 | \midrule 10 | \endhead 11 | 17-Apr-2024 & 1.0 & Initial Release\\ 12 | 26-Apr-2024 & 1.0.1 & Added Preface \newline 13 | Added Extending section\\ 14 | & & \\ 15 | \bottomrule 16 | \caption{Revision History} 17 | \label{tab:REVS} 18 | \end{longtable} 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Collection of support modules and packages for AMBA AHB and APB 2 | 3 | Included: 4 | - ahb3lite package. Contains definitions and functions to support AHB protocol. Used by most RoaLogic IP 5 | - ahb3lite bus functional model (BFM) 6 | - apb4 bus functional model (BFM) 7 | - AHB Protocol Checker. Analyses/snoops AHB bus and reports protocol violations 8 | - APB Protocol Checker. Analysys/snoops APB bus and reports protocol violations 9 | 10 | All simulation files, i.e. the BFMs and Protocol Checkers, are released under GPL license. 11 | The AHB package is released under BSD license. 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/tex/setup.tex: -------------------------------------------------------------------------------- 1 | % Load Roalogic Title Page Generator 2 | \usepackage{pkg/roalogictitle} 3 | 4 | \graphicspath{ {./assets/img/} } 5 | 6 | % Document Variables 7 | 8 | \title{AMBA APB Checker VIP} 9 | \heading{APB Checker Verification IP} 10 | \date{26-Apr-2024} 11 | \version{1.0.1} 12 | \doctype{Datasheet} 13 | \project{\url{https://roalogic.github.io/amba_pkg}} 14 | \author{Richard Herveille} 15 | 16 | % Set page headers/footer 17 | \pagestyle{fancy} 18 | \fancyhf{} 19 | % \fancyhead[LE,RO]{\thepage} 20 | % \fancyhead[RE,LO]{APB Checker VIP} 21 | % \fancyfoot[CE,CO]{\textcircled{c} Roa Logic} 22 | \fancyhead[L]{\theheading\space(v\theversion)} 23 | \fancyhead[R]{\includegraphics[width=50px,trim=0 25px 0 0]{assets/img/RoaLogicHeader}} 24 | \fancyfoot[C]{\thepage} 25 | -------------------------------------------------------------------------------- /docs/apb_checker.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,oneside,11pt,openany]{book} 2 | % \usepackage{showframe} 3 | 4 | % Document Setup 5 | \input{tex/preamble.tex} 6 | \input{tex/setup.tex} 7 | 8 | \begin{document} 9 | 10 | %\layout{} 11 | 12 | \frontmatter 13 | \maketitle 14 | \tableofcontents 15 | \listoffigures 16 | \listoftables 17 | % \listoftodos 18 | 19 | \mainmatter 20 | 21 | \input{tex/apb_checker/preface.tex} 22 | 23 | \input{tex/apb_checker/introduction.tex} 24 | 25 | \input{tex/apb_checker/specification.tex} 26 | 27 | \input{tex/apb_checker/configuration.tex} 28 | 29 | \input{tex/apb_checker/interfaces.tex} 30 | 31 | \input{tex/apb_checker/rules.tex} 32 | 33 | \input{tex/apb_checker/extending.tex} 34 | 35 | \input{tex/apb_checker/references.tex} 36 | 37 | \input{tex/apb_checker/history.tex} 38 | 39 | \end{document} 40 | -------------------------------------------------------------------------------- /docs/tex/apb_checker/preface.tex: -------------------------------------------------------------------------------- 1 | \chapter{Preface}\label{preface} 2 | 3 | \section{Roa Logic Open Source Commitment} 4 | Roa Logic is commited to open source software and the open source community. 5 | We believe that contributing (to) open source software is a way to teach and learn, to share experience and build experience, and to come together as developers, users, and as humans. 6 | We hope that this software will be valuable to someone and enables and motivates new contributors and contributions to the open source community. 7 | 8 | \noindent\textbf{Links:}\newline 9 | \url{https://www.roalogic.com}\newline 10 | \url{https://www.github.com/roalogic} 11 | 12 | 13 | \section{Copyright} 14 | 15 | Copyright \textcopyright 2024, Roa Logic B.V.\newline 16 | Copyright \textcopyright 2024, Richard Herveille 17 | 18 | 19 | \section{License} 20 | 21 | This work is released under the Creative Commons Attribution-ShareAlike 4.0 International (``CC BY-SA 4.0") License. 22 | The full license text can be found here:\newline \url{https://creativecommons.org/licenses/by-sa/4.0/legalcode.en} 23 | 24 | 25 | \section{Disclaimer} 26 | 27 | THIS WORK IS PROVIDED ``AS IS" WITHOUT WARRANTIES OF ANY KIND, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHER. 28 | 29 | 30 | \section{Third-Party} 31 | 32 | Arm and AMBA are registered trademarks of Arm Limited. 33 | 34 | -------------------------------------------------------------------------------- /docs/pkg/roalogictitle.sty: -------------------------------------------------------------------------------- 1 | % Title Page generator 2 | 3 | %Logo 4 | %Title 5 | %DocType 6 | %Project 7 | %Date 8 | 9 | % Define Package 10 | \ProvidesPackage{pkg/roalogictitle}[2017/10/01 v1] 11 | \RequirePackage{graphicx} 12 | 13 | % Define new variables 14 | \newcommand*{\project}[1]{\gdef\@project{#1}% 15 | } 16 | 17 | \newcommand*{\doctype}[1]{\gdef\@doctype{#1}% 18 | } 19 | 20 | \newcommand*{\header}[1]{\gdef\@header{#1}% 21 | } 22 | 23 | \newcommand*{\version}[1]{\gdef\@version{#1}% 24 | } 25 | 26 | \newcommand*{\heading}[1]{\gdef\@heading{#1}% 27 | } 28 | 29 | \appendiargdef{\version}{% 30 | \begingroup 31 | \renewcommand{\thanks}[1]{} 32 | \protected@xdef\theversion{#1} 33 | \endgroup} 34 | 35 | \appendiargdef{\heading}{% 36 | \begingroup 37 | \renewcommand{\thanks}[1]{} 38 | \protected@xdef\theheading{#1} 39 | \endgroup} 40 | 41 | % Overload \maketitle with new layout 42 | \renewcommand*{\maketitle}{% 43 | \hypersetup{pageanchor=false} 44 | \begin{titlepage} 45 | \par 46 | \vspace{3cm} 47 | {\raggedleft% 48 | \includegraphics[width=12cm]{assets/img/Tagged_Logo.eps}\par 49 | }\vspace{1cm} 50 | \centering 51 | {\huge\bfseries\@title\unskip\strut\par} 52 | \vspace{1cm} 53 | {\LARGE\itshape\@doctype\space(v\@version)\unskip\strut\par} 54 | \vspace{1cm} 55 | {\scshape\Large\@project\unskip\strut\par} 56 | \vspace{1cm} 57 | {\large \@date\par} 58 | \vspace{7cm} 59 | {\scshape\large \copyright\space Roa Logic B.V. \par} 60 | 61 | \vfill 62 | 63 | \end{titlepage} 64 | \hypersetup{pageanchor=true} 65 | } 66 | \endinput 67 | -------------------------------------------------------------------------------- /docs/tex/apb_checker/specification.tex: -------------------------------------------------------------------------------- 1 | \chapter{Specifications} \label{specifications} 2 | 3 | \section{Functional Description}\label{functional-description} 4 | 5 | The Roa Logic APB Checker VIP is a configurable, fully parameterized Verification IP (VIP) 6 | that continuously and autonomosly observes and verifies all APB transactions. 7 | The APB Checker VIP is fully compliant with the AMBA APB2, APB3, APB4, and APB5 protocols. 8 | 9 | 10 | \section{Operating Modes}\label{operating-modes} 11 | 12 | The APB Checker VIP supports the APB2, APB3, APB4, and APB5 bus protocols. The protocol to verify is selected using a define statement; 13 | 14 | \texttt{`define APB\_VERSION\_APB5} 15 | 16 | \texttt{`define APB\_VERSION\_APB4} 17 | 18 | \texttt{`define APB\_VERSION\_APB3} 19 | 20 | The default APB2 protocol is used when no define is set. When APB\_VERSION\_APB5 is defined, then APB\_VERSION\_APB4 is automatically defined. When APB\_VERSION\_APB4 is defined, then APB\_VERSION\_APB3 is automatically defined. 21 | The module ports and executed rules reflect the selected protocol. 22 | 23 | 24 | \subsection{PCLK}\label{PCLK} 25 | APB is a synchronous protocol. All transactions take place on the rising edge of \texttt{PCLK}. 26 | Most of the rules are triggered on the rising edge of \texttt{PCLK}. This has the advantage of simple rule design and fast execution. The protocol checker has a minimal simulation performance effect. The disadvantage is that the checker does not look at values inbetween clock edges. It is assumed that all APB signals, except for \texttt{PRESETn} and \texttt{PCLK}, are driven by registers or at least behave like being driven by registers. 27 | -------------------------------------------------------------------------------- /docs/tex/apb_checker/introduction.tex: -------------------------------------------------------------------------------- 1 | \chapter{Introduction} \label{introduction} 2 | 3 | The Roa Logic APB Checker Verification IP helps designers use the ARM\textsuperscript{\textregistered} AMBA\textsuperscript{\textregistered} APB\textsuperscript{\cite{ArmAPB}} bus in their designs. Throughout this document ARM\textsuperscript{\textregistered} AMBA\textsuperscript{\textregistered} APB will be simply refered to as APB. 4 | The Roa Logic APB Checker VIP continuously snoops the APB bus and reports any protocol issues it detects. 5 | In addition to rules checking, the ABP Checker VIP contains an optional watchdog that fires when the APB bus becomes unresponsive. 6 | The APB Bus Checker VIP supports the following APB versions: 7 | \begin{itemize} 8 | \item 9 | AMBA 2 APB Specification (Issue A), commonly known as APB2 10 | \item 11 | AMBA 3 APB Specification (Issue B), commonly known as APB3 12 | \item 13 | AMBA APB Specification (Issue C), commonly known as APB4 14 | \item 15 | AMBA APB Specification (Issue D), commonly known as APB5 16 | \end{itemize} 17 | 18 | The Roa Logic APB Bus Checker VIP is released under the permissive GPLv3 license. 19 | 20 | 21 | \section{Features}\label{features} 22 | 23 | \begin{itemize} 24 | \item 25 | Plug 'n Play APB Checker 26 | \item 27 | Compliant with APB2, APB3, APB4, and APB5 Bus protocols 28 | \item 29 | Supports configurable APB address, data, user signal, and response widths 30 | \item 31 | Autonomously checks APB transactions and signals 32 | \item 33 | User configurable severity per rule 34 | \item 35 | Easily extensible with custom rules 36 | \item 37 | Configurable watchdog fires when the APB bus is unresponsive 38 | \item 39 | Delivered in plain text SystemVerilog format 40 | \end{itemize} 41 | 42 | 43 | \section{Benefits}\label{Benefits} 44 | 45 | \begin{itemize} 46 | \item 47 | Faster debug due to customised reports 48 | \item 49 | Integrates into existing Verilog and SystemVerilog testbenches 50 | \item 51 | Works with existing OVM and UVM test environments 52 | \item 53 | Open Source, therefore code can be reviewed and extended 54 | \item 55 | Permissive license 56 | \end{itemize} -------------------------------------------------------------------------------- /docs/tex/apb_checker/extending.tex: -------------------------------------------------------------------------------- 1 | \chapter{Extending the VIP}\label{extending} 2 | 3 | \section{Introduction} 4 | 5 | The Roa Logic APB Checker VIP can be easiliy extended with custom rules. This chapter explains the structure of the VIP and how to modify it. 6 | 7 | \section{Structure} 8 | 9 | The VIP consits of 3 sections; the message structure, the checks and rules, and the module body. 10 | 11 | 12 | \subsection{The Message Structure} 13 | 14 | When a rule triggers, a message and severity is reported. 15 | The reporting is done by the \texttt{message} task which only takes a message number as input. 16 | 17 | \lstset{language=verilog, 18 | basicstyle=\small\ttfamily, 19 | showstringspaces=false, 20 | frame=single} 21 | 22 | \begin{lstlisting} 23 | task automatic message (input int msg_no); 24 | ... 25 | endtask : message 26 | \end{lstlisting} 27 | 28 | \noindent 29 | The message and its severity level are stored in a struct. 30 | 31 | \begin{lstlisting} 32 | typedef struct { 33 | severity_t severity; 34 | string message; 35 | } message_t; 36 | \end{lstlisting} 37 | 38 | \noindent 39 | The message is stored as a SystemVerilog string, whereas the severity level is a user defined integer type. 40 | 41 | \begin{lstlisting} 42 | typedef enum int {OFF =0, 43 | INFO =1, 44 | WARNING=2, 45 | ERROR =3, 46 | FATAL =4} severity_t; 47 | \end{lstlisting} 48 | 49 | \noindent 50 | Extend the enum to add a new severity level, like this: 51 | 52 | \begin{lstlisting} 53 | typedef enum int {OFF =0, 54 | INFO =1, 55 | WARNING=2, 56 | ERROR =3, 57 | FATAL =4, 58 | MY_LVL =5} severity_t; 59 | \end{lstlisting} 60 | 61 | \pagebreak 62 | \noindent 63 | All messages are stored in the unpacked array \texttt{\_msg} of type \texttt{message\_t}. 64 | The messages are loaded into the array using an initial block. This approach makes adding new messages straighforward. First increase \texttt{MESSAGE\_COUNT}, then add the message with its default severity level. 65 | 66 | \begin{lstlisting} 67 | initial 68 | begin 69 | ... 70 | _msg[MESSAGE_COUNT-1] = '{MY_LVL, "My message"}; 71 | ... 72 | end 73 | \end{lstlisting} 74 | 75 | 76 | 77 | \subsection{Creating new checks/rules} 78 | 79 | All rules and checks are written as verilog tasks. Each task has the following structure; 80 | 81 | \begin{lstlisting} 82 | task check_myrules 83 | //rule 1 84 | if (condition) 85 | message(messageNumber); 86 | 87 | //rule 2 88 | if (condition2) 89 | message(messageNumber2); 90 | endtask : check_myrules 91 | \end{lstlisting} 92 | 93 | \noindent 94 | If a check or rule is only applicable to a specific APB version, then the rule/check must be enwrapped as shown below for the \texttt{check\_pbuser} task. 95 | 96 | \begin{lstlisting} 97 | /* 98 | * Check PBUSER 99 | */ 100 | `ifdef APB_VERSION_APB5 101 | task check_pbuser; 102 | //PBUSER undefined when transfer completes? 103 | if (PENABLE && PREADY) 104 | if (PBUSER === 1'bx || PBUSER === 1'bz) 105 | message(35); 106 | endtask : check_pbuser 107 | `endif 108 | \end{lstlisting} 109 | 110 | 111 | 112 | \subsection{Adding the check in the main body} 113 | 114 | The final step is adding the new check to the main body. Because APB is a synchronous protocol, almost all checks are triggered by \texttt{PCLK}. 115 | 116 | \begin{lstlisting} 117 | /* 118 | * Check MyRules 119 | */ 120 | always @(posedge PCLK) check_myrules(); 121 | \end{lstlisting} 122 | 123 | -------------------------------------------------------------------------------- /docs/tex/preamble_appendix.tex: -------------------------------------------------------------------------------- 1 | 2 | %Show appendices as 'Appendix A' 3 | %Appendices are 'section's, not 'chapter's 4 | 5 | \makeatletter 6 | \@ifundefined{texorpdfstring}{\let\texorpdfstring\@firstoftwo}{} 7 | \@ifundefined{hyper@makecurrent}{}{% 8 | \usepackage{xpatch}% 9 | \newcommand*\Hy@subsectionstring{subsection}% 10 | \newcommand*\Hy@subsubsectionstring{subsubsection}% 11 | \newcommand*\Hy@subsecapp{subsection}% 12 | \newcommand*\Hy@subsubsecapp{subsubsection}% 13 | \xpatchcmd{\hyper@makecurrent}{% 14 | \ifx\Hy@param\Hy@chapterstring\let\Hy@param\Hy@chapapp\fi 15 | }{% 16 | \ifx\Hy@param\Hy@chapterstring\let\Hy@param\Hy@chapapp\fi 17 | \ifx\Hy@param\Hy@subsectionstring\let\Hy@param\Hy@subsecapp\fi 18 | \ifx\Hy@param\Hy@subsubsectionstring\let\Hy@param\Hy@subsubsecapp\fi 19 | % \show\Hy@param 20 | }{% 21 | \@latex@info{Command \string\hyper@makecurrent patched successfully}% 22 | \message{Command \string\hyper@makecurrent patched successfully\on@line}% 23 | }{% 24 | \@latex@error{Command \string\hyper@makecurrent not patched successfully}% 25 | {You're in trouble here.}% 26 | }% 27 | }% 28 | \newcommand\labelfork[2]{% 29 | \ifx\thepage\relax\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi{#1}{#2}% 30 | }% 31 | \newcommand\appendix@l@section[2]{% 32 | \ifnum\c@tocdepth >\z@ 33 | \addpenalty\@secpenalty 34 | \addvspace{1.0em \@plus\p@}% 35 | \setlength\@tempdima{\appendixtocwidth}% 36 | \begingroup 37 | \parindent\z@ 38 | \rightskip\@pnumwidth 39 | \parfillskip-\@pnumwidth 40 | \leavevmode 41 | \bfseries 42 | \advance\leftskip\@tempdima 43 | \hskip-\leftskip 44 | #1% 45 | \nobreak\hfil 46 | \nobreak\hb@xt@\@pnumwidth{\hss#2\kern-\p@\kern\p@}\par 47 | \endgroup 48 | \fi 49 | }% 50 | \newcommand\appendix@l@subsection{% 51 | %\@dottedtocline {2}{1.5em}{2.3em} 52 | \@dottedtocline{2}{1.5em}{\dimexpr0.8em+\appendixtocwidth\relax}% 53 | }% 54 | \newcommand\appendix@l@subsubsection{% 55 | %\@dottedtocline {3}{3.8em}{3.2em} 56 | \@dottedtocline{3}{3.8em}{\dimexpr1.7em+\appendixtocwidth\relax}% 57 | }% 58 | \newcommand\appendixlatsections{% 59 | \let\l@chapter=\appendix@l@chapter 60 | \let\l@section=\appendix@l@section 61 | \let\l@subsection=\appendix@l@subsection 62 | \let\l@subsubsection=\appendix@l@subsubsection 63 | }% 64 | \newcommand\doappendixstuff{% 65 | \renewcommand\thechapter{% 66 | \texorpdfstring{\noexpand\labelfork{}{\appendixname\protect~}}{\appendixname\space}% 67 | \@Alph\c@chapter 68 | \texorpdfstring{\noexpand\labelfork{}{:}}{:}% 69 | }% 70 | \renewcommand\thesection{% 71 | \texorpdfstring{\noexpand\labelfork{}{\appendixname\protect~}}{\appendixname\space}% 72 | \@Alph\c@section.\number\value{section} 73 | \texorpdfstring{\noexpand\labelfork{}{:}}{:}% 74 | }% 75 | \renewcommand\thesubsection{% 76 | \texorpdfstring{\noexpand\labelfork{}{\appendixname\protect~}}{\appendixname\space}% 77 | \@Alph\c@section.\number\value{section}.\number\value{subsection}% 78 | \texorpdfstring{\noexpand\labelfork{}{:}}{:}% 79 | }% 80 | \renewcommand\thesubsubsection{% 81 | \texorpdfstring{\noexpand\labelfork{}{\appendixname\protect~}}{\appendixname\space}% 82 | \@Alph\c@section.\number\value{section}.\number\value{subsection}.\number\value{subsubsection}% 83 | \texorpdfstring{\noexpand\labelfork{}{:}}{:}% 84 | }% 85 | \let\Hy@subsecapp\Hy@appendixstring 86 | \let\Hy@subsubsecapp\Hy@appendixstring 87 | \begingroup 88 | \bfseries 89 | \settowidth\@tempdima{\appendixname~A:~}% 90 | \addtocontents{toc}{\string\def\string\appendixtocwidth{\the\@tempdima}}% 91 | \addtocontents{toc}{\string\appendixlatsections}% 92 | \endgroup 93 | % \addtocontents{toc}{\protect\savedcontentsline{section}{{\large Appendices}}{}\protected@file@percent}% 94 | }% 95 | \makeatother 96 | -------------------------------------------------------------------------------- /rtl/verilog/apb4_bfm.sv: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // ,------. ,--. ,--. // 3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. // 4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' // 5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. // 6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' // 7 | // `---' // 8 | // APB4 Bus Functional Model // 9 | // // 10 | ///////////////////////////////////////////////////////////////////// 11 | // // 12 | // Copyright (C) 2023 ROA Logic BV // 13 | // www.roalogic.com // 14 | // // 15 | // This source file may be used and distributed without // 16 | // restriction provided that this copyright statement is not // 17 | // removed from the file and that any derivative work contains // 18 | // the original copyright notice and the associated disclaimer. // 19 | // // 20 | // This soure file is free software; you can redistribute it // 21 | // and/or modify it under the terms of the GNU General Public // 22 | // License as published by the Free Software Foundation, // 23 | // either version 3 of the License, or (at your option) any later // 24 | // versions. The current text of the License can be found at: // 25 | // http://www.gnu.org/licenses/gpl.html // 26 | // // 27 | // This source file is distributed in the hope that it will be // 28 | // useful, but WITHOUT ANY WARRANTY; without even the implied // 29 | // warranty of MERCHANTABILITY or FITTNESS FOR A PARTICULAR // 30 | // PURPOSE. See the GNU General Public License for more details. // 31 | // // 32 | ///////////////////////////////////////////////////////////////////// 33 | 34 | 35 | /* 36 | * Limitations: 37 | * Does not support Error response/transactions (PSLVERR is ignored) 38 | */ 39 | 40 | module apb4_master_bfm 41 | #( 42 | parameter PADDR_SIZE = 16, 43 | parameter PDATA_SIZE = 32 44 | ) 45 | ( 46 | input PRESETn, 47 | PCLK, 48 | output reg PSEL, 49 | output reg PENABLE, 50 | output reg PWRITE, 51 | output reg [PDATA_SIZE/8-1:0] PSTRB, 52 | output reg [PADDR_SIZE -1:0] PADDR, 53 | output reg [ 2:0] PPROT, 54 | output reg [PDATA_SIZE -1:0] PWDATA, 55 | input [PDATA_SIZE -1:0] PRDATA, 56 | input PREADY, 57 | input PSLVERR 58 | ); 59 | 60 | always @(negedge PRESETn) reset(); 61 | 62 | 63 | ///////////////////////////////////////////////////////// 64 | // 65 | // Tasks 66 | // 67 | task reset(); 68 | //Reset AHB Bus 69 | PSEL = 1'b0; 70 | PENABLE = 1'bx; 71 | PWRITE = 1'bx; 72 | PSTRB = 'hx; 73 | PADDR = 'hx; 74 | PPROT = 'hx; 75 | PWDATA = 'hx; 76 | 77 | @(posedge PRESETn); 78 | endtask 79 | 80 | 81 | task idle (); 82 | //Put AHP Bus in IDLE state 83 | //Call after write or read sequence 84 | PSEL <= 1'b0; 85 | endtask 86 | 87 | 88 | /* APB Write 89 | * 90 | */ 91 | task automatic write ( 92 | input [PADDR_SIZE -1:0] address, 93 | input [PDATA_SIZE -1:0] data, 94 | input [PDATA_SIZE/8-1:0] be 95 | ); 96 | //Setup phase 97 | PSEL <= 1'b1; 98 | PENABLE <= 1'b0; 99 | PWRITE <= 1'b1; 100 | PSTRB <= be; 101 | PADDR <= address; 102 | PPROT <= 'hx; 103 | PWDATA <= data; 104 | @(posedge PCLK); 105 | 106 | //Access phase 107 | PENABLE <= 1'b1; 108 | 109 | do 110 | @(posedge PCLK); 111 | while (!PREADY); 112 | 113 | //Transfer done 114 | PSEL <= 1'b0; 115 | endtask 116 | 117 | 118 | /* APB Read 119 | * 120 | */ 121 | task automatic read ( 122 | input [PADDR_SIZE-1:0] address, 123 | output [PDATA_SIZE-1:0] data 124 | ); 125 | //Setup phase 126 | PSEL <= 1'b1; 127 | PENABLE <= 1'b0; 128 | PWRITE <= 1'b0; 129 | PSTRB <= 'hx; 130 | PADDR <= address; 131 | PPROT <= 'hx; 132 | PWDATA <= 'hx; 133 | @(posedge PCLK); 134 | 135 | //Access phase 136 | PENABLE <= 1'b1; 137 | 138 | do @(posedge PCLK); 139 | while (!PREADY); 140 | 141 | data = PRDATA; 142 | 143 | //Transfer done 144 | PSEL <= 1'b0; 145 | endtask 146 | 147 | endmodule : apb4_master_bfm 148 | -------------------------------------------------------------------------------- /docs/tex/apb_checker/configuration.tex: -------------------------------------------------------------------------------- 1 | \chapter{Configurations}\label{configurations} 2 | 3 | \section{Introduction}\label{introduction-1} 4 | 5 | The Roa Logic APB Checker VIP is a configurable Verification IP for the APB Bus. 6 | The core parameters, static configuration options, and functions for dynamic configuration are described in this section. 7 | 8 | \section{Core Configuration}\label{core-configuration} 9 | The APB Checker VIP supports APB2, APB3, APB4, and APB5. The APB version is selected by setting either of these defines: 10 | 11 | \texttt{`define APB\_VERSION\_APB5} 12 | 13 | \texttt{`define APB\_VERSION\_APB4} 14 | 15 | \texttt{`define APB\_VERSION\_APB3} 16 | 17 | If no define is set, then the default is APB2. 18 | 19 | \section{Core Parameters}\label{core-parameters} 20 | 21 | The parameter names used by the core are as specified by the APB Specification documents, which are owned and governed by ARM Ltd. 22 | 23 | \begin{longtable}[]{@{}lccl@{}} 24 | \toprule 25 | Parameter & Type & Default & Description\tabularnewline 26 | \midrule 27 | \endhead 28 | \texttt{ADDR\_WIDTH} & Integer & 32 & Address bus width\tabularnewline 29 | \texttt{DATA\_WIDTH} & Integer & 32 & Data bus widths\tabularnewline 30 | \texttt{USER\_REQ\_WIDTH} & Integer & 0 & User address bus width\tabularnewline 31 | \texttt{USER\_DATA\_WDITH} & Integer & 0 & User data bus widths\tabularnewline 32 | \texttt{USER\_RESP\_WIDTH} & Integer & 0 & User response bus width\tabularnewline 33 | \texttt{CHECK\_PSTRB} & Integer & 1 & Enable PSTRB checking\tabularnewline 34 | \texttt{CHECK\_PPROT} & Integer & 1 & Enable PPROT checking\tabularnewline 35 | \texttt{CHECK\_PSLVERR} & Integer & 1 & Enable PSLVERR checking\tabularnewline 36 | \texttt{WATCHDOG\_TIMEOUT} & Integer & 128 & Watchdog counter timeout value\tabularnewline 37 | \bottomrule 38 | \caption{Core Parameters} 39 | \end{longtable} 40 | 41 | \subsection{ADDR\_WIDTH}\label{addr_width} 42 | 43 | The \texttt{ADDR\_WIDTH} parameter specifies the width of the APB2 and above PADDR signal. The default value of the \texttt{ADDR\_WIDTH} parameter is 32. 44 | 45 | \subsection{DATA\_WIDTH}\label{data_width} 46 | 47 | The \texttt{DATA\_WIDTH} parameter specifies the width of the APB2 and above PRDATA and PWDATA signals. The default value of the \texttt{DATA\_WIDTH} parameter is 32. 48 | 49 | \subsection{USER\_REQ\_WIDTH}\label{user_req_width} 50 | 51 | The \texttt{USER\_REQ\_WIDTH} parameter specifies the width of the APB5 PAUSER signal. A value of zero (`0') indicates the signal is not present in the APB bus and checking is disabled. The default value of the \texttt{USER\_REQ\_WIDTH} parameter is 0; i.e. disabled. 52 | 53 | \subsection{USER\_DATA\_WIDTH}\label{user_data_width} 54 | 55 | The \texttt{USER\_DATA\_WIDTH} parameter specifies the width of the APB5 PRUSER and PWUSER signals. A value of zero (`0') indicates the signals are not present in the APB bus and checking is disabled. The default value of the \texttt{USER\_DATA\_WIDTH} parameter is 0; i.e. disabled. 56 | 57 | \subsection{USER\_RESP\_WIDTH}\label{user_resp_width} 58 | 59 | The \texttt{USER\_RESP\_WIDTH} parameter specifies the width of the APB5 PBUSER bus. A value of zero (`0') indicates the signal is not present in the APB bus and checking is disabled. The default value of the \texttt{USER\_RESP\_WIDTH} parameter is 0; i.e. disabled. 60 | 61 | \subsection{CHECK\_PSTRB}\label{check_pstrb} 62 | 63 | The \texttt{CHECK\_PSTRB} parameter enables or disables checking of the optional APB4 and above PSTRB signal. If \texttt{CHECK\_PSTRB} has a value of zero (0), then checking the PSTRB signal is disabled. Any other value enables checking the PSTRB signal. The default value of the \texttt{CHECK\_PSTRB} parameter is 1; i.e. enabled. 64 | 65 | \subsection{CHECK\_PPROT}\label{check_pprot} 66 | 67 | The \texttt{CHECK\_PPROT} parameter enables or disables checking of the optional APB4 and above PPROT signal. If \texttt{CHECK\_PPROT} has a value of zero (0), then checking the PPROT signal is disabled. Any other value enables checking the PPROT signal. The default value of the \texttt{CHECK\_PPROT} parameter is 1; i.e. enabled. 68 | 69 | \subsection{CHECK\_PSLVERR}\label{check_pslverr} 70 | 71 | The \texttt{CHECK\_PSLVERR} parameter enables or disables checking of the optional APB3 and above PSLVERR signal. If \texttt{CHECK\_PSLVERR} has a value of zero (0), then checking the PSLVERR signal is disabled. Any other value enables checking the PSLVERR signal. The default value of the \texttt{CHECK\_PSLVERR} parameter is 1; i.e. enabled. 72 | 73 | \subsection{WATCHDOG\_TIMEOUT}\label{watchdog_timeout} 74 | 75 | The \texttt{WATCHDOG\_TIMEOUT} parameter sets the expiration counter value for the optional watchdog. A value of zero (`0') indicates the watchdog is disabled. The default value of the \texttt{WATCHDOG\_TIMEOUT} parameter is 128. 76 | 77 | 78 | \section{Functions for Dynamic Configuration}\label{dynamic_configuration} 79 | 80 | The APB Checker VIP allows the user to dynamically change the severity level of each rule. Changing the severity level allows the user to stop the simulation when hitting a certain rule, or completely ignoring a rule, for example. 81 | See the \hyperref[extending]{extending} section for more details. 82 | 83 | \subsection{get\_severity}\label{get_severity} 84 | 85 | Synopsis: \texttt{function automatic severity\_t get\_severity (input int msg\_no)} 86 | 87 | The \texttt{get\_severity} function returns the severity level of message \texttt{msg\_no}. 88 | Note that the rule number is one higher than the message number; \texttt{msg\_no}=0 means rule \#1. 89 | 90 | \subsection{set\_severity}\label{set_severity} 91 | 92 | Synopsis: \texttt{task automatic set\_severity (input int msg\_no, severity\_t severity)} 93 | 94 | The \texttt{set\_severity} function set the severity level of message \texttt{msg\_no} to \texttt{severity}. 95 | Note that the rule number is one higher than the message number; \texttt{msg\_no}=0 means rule \#1. -------------------------------------------------------------------------------- /docs/tex/apb_checker/interface-apb.tex: -------------------------------------------------------------------------------- 1 | \section{APB Interface}\label{apb-interface} 2 | 3 | The APB Interface is a configurable APB Interface. All signals 4 | defined in the protocol are supported as described below. See the 5 | \emph{AMBA APB Protocol Specifications} for a complete description 6 | of the signals. 7 | 8 | \begin{longtable}[]{@{}lccll@{}} 9 | \toprule 10 | \textbf{Port} & \textbf{Size} & \textbf{Direction} & \textbf{Version} & \textbf{Description}\tabularnewline 11 | \midrule 12 | \endhead 13 | \texttt{PRESETn} & 1 & Input & APB2 & Reset\tabularnewline 14 | \texttt{PCLK} & 1 & Input & APB2 & Clock\tabularnewline 15 | \texttt{PSEL} & 1 & Input & APB2 & Select\tabularnewline 16 | \texttt{PENABLE} & 1 & Input & APB2 & Enable\tabularnewline 17 | \texttt{PADDR} & \texttt{ADDR\_WIDTH} & Input & APB2 & Address\tabularnewline 18 | \texttt{PWRITE} & 1 & Input & APB2 & Direction\tabularnewline 19 | \texttt{PSTRB} & \texttt{DATA\_WIDTH/8} & Input & APB4 & Write Strobe\tabularnewline 20 | \texttt{PPROT} & 3 & Input & APB4 & Protection Type\tabularnewline 21 | \texttt{PWDATA} & \texttt{DATA\_WIDTH} & Input & APB2 & Write Data\tabularnewline 22 | \texttt{PRDATA} & \texttt{DATA\_WIDTH} & Input & APB2 & Read Data\tabularnewline 23 | \texttt{PREADY} & 1 & Input & APB3 & Ready\tabularnewline 24 | \texttt{PSLVERR} & 1 & Input & APB3 & Transfer Error\tabularnewline 25 | \texttt{PWAKEUP} & 1 & Input & APB5 & Wake-up\tabularnewline 26 | \texttt{PAUSER} & \texttt{USER\_REQ\_WIDTH} & Input & APB5 & User request attribute\tabularnewline 27 | \texttt{PWUSER} & \texttt{USER\_DATA\_WIDTH} & Input & APB5 & User write data attribute\tabularnewline 28 | \texttt{PRUSER} & \texttt{USER\_DATA\_WIDTH} & Input & APB5 & User read data attribute\tabularnewline 29 | \texttt{PBUSER} & \texttt{USER\_RESP\_WIDTH} & Input & APB5 & User response attribute\tabularnewline 30 | \bottomrule 31 | \caption{APB Interface Ports} 32 | \end{longtable} 33 | 34 | Signals for an APB version higher than selected are not present on the interface. See the \hyperref[core-configuration]{Core Configuration} section. 35 | 36 | 37 | \subsection{PRESETn}\label{presetn} 38 | 39 | When the active low asynchronous \texttt{PRESETn} input is asserted (`0'), the 40 | APB interface is put into its initial reset state. 41 | 42 | \subsection{PCLK}\label{pclk} 43 | 44 | \texttt{PCLK} is the APB interface clock. All APB signals are timed against the rising edge of \texttt{PCLK}. 45 | 46 | The APB Bus Checker VIP requires a valid \texttt{PCLK}. All checks and rules trigger on the rising edge of \texttt{PCLK}. 47 | 48 | \subsection{PSEL}\label{psel} 49 | 50 | The APB \emph{Requester} generates \texttt{PSEL}, signaling to a \emph{Completer} that it is selected and that a data transfer is required. 51 | 52 | \subsection{PENABLE}\label{penable} 53 | 54 | \texttt{PENABLE} indicates the second and subsequent cycles of a transfer. The cycles when \texttt{PENABLE} is asserted (`1') are called the \emph{Access Phase}. It is driven by the \emph{Requester}. 55 | 56 | \subsection{PADDR}\label{paddr} 57 | 58 | \texttt{PADDR} is the APB address bus. The bus width is defined by the \texttt{ADDR\_WIDTH} parameter. 59 | 60 | \subsection{PWRITE}\label{pwrite} 61 | 62 | \texttt{PWRITE} indicates the direction of the transfer. When \texttt{PWRITE} is asserted (`1') it indicates a write access and a read data access when de-asserted (`0'). It is driven by the \emph{Requester}. 63 | 64 | \subsection{PSTRB}\label{pstrb} 65 | 66 | \texttt{PSTRB} is an optional APB4 signal driven by the \emph{Requester}.. It indicates which byte lane to update during a 67 | write transfer. There is one \texttt{PSTRB} signal per byte lane of the APB write data bus 68 | (\texttt{PWDATA}), such that \texttt{PSTRB[n]} corresponds to \texttt{PWDATA[(8n+7):8n]}. 69 | 70 | \subsection{PPROT}\label{pprot} 71 | 72 | \texttt{PPROT} is an optional APB4 signal driven by the \emph{Requester}. It indicates the normal, privileged, or secure protection level of the transaction and whether the transaction is a data or an instruction access. \texttt{PPROT} has a width of 3 bits. 73 | 74 | \subsection{PWDATA}\label{pwdata} 75 | 76 | \texttt{PWDATA} is the APB write data bus and is driven by the \emph{Requester} during write cycles, when \texttt{PWRITE} is asserted (`1'). The bus width is defined by the \texttt{DATA\_WIDTH} parameter. 77 | 78 | \subsection{PRDATA}\label{prdata} 79 | 80 | \texttt{PRDATA} is the APB read data bus and is driven by the \emph{Completer} during read cycles, when \texttt{PWRITE} is de-asserted (`0'). The bus width is defined by the \texttt{DATA\_WIDTH} parameter. 81 | 82 | \subsection{PREADY}\label{pready} 83 | 84 | \texttt{PREADY} is an APB3 signal driven by the \emph{Completer}. It is used to extend an APB transfer. 85 | 86 | \subsection{PSLVERR}\label{pslverr} 87 | 88 | \texttt{PSLVERR} is an optional APB3 signal driven by the \emph{Completer}. It indicates an error condition on the APB bus when asserted (`1'). 89 | 90 | \subsection{PWAKEUP}\label{pwakeup} 91 | 92 | \texttt{PWAKEUP} is an optional APB5 signal driven by the \emph{Requester}. It indicates any activity associated with an APB interface. 93 | 94 | \subsection{PAUSER}\label{pauser} 95 | 96 | \texttt{PAUSER} is an optional APB5 signal driven by the \emph{Requester}. The bus width is defined by the \texttt{USER\_REQ\_WIDTH} parameter. 97 | 98 | \subsection{PWUSER}\label{pwuser} 99 | 100 | \texttt{PWUSER} is an optional APB5 signal driven by the \emph{Requester}. The bus width is defined by the \texttt{USER\_DATA\_WIDTH} parameter. 101 | 102 | \subsection{PRUSER}\label{pruser} 103 | 104 | \texttt{PRUSER} is an optional APB5 signal driven by the \emph{Requester}. The bus width is defined by the \texttt{USER\_DATA\_WIDTH} parameter. 105 | 106 | \subsection{PBUSER}\label{pbuser} 107 | 108 | \texttt{PBUSER} is an optional APB5 signal driven by the \emph{Requester}. The bus width is defined by the \texttt{USER\_RESP\_WIDTH} parameter. -------------------------------------------------------------------------------- /docs/tex/preamble.tex: -------------------------------------------------------------------------------- 1 | %define new document type 2 | \usepackage[utf8]{inputenc} 3 | \usepackage[english]{babel} 4 | 5 | % Define Roa Logic Colour Scheme 6 | \usepackage[table]{xcolor} 7 | \newcommand{\headlinecolor}{\normalcolor} 8 | \definecolor{rlchapter}{HTML}{3D5986} 9 | \definecolor{rlsection}{HTML}{5B80B8} 10 | \definecolor{rltable}{HTML}{D5DFED} 11 | 12 | % Load packages 13 | \usepackage{graphicx,grffile} % Graphics support 14 | \usepackage{geometry} 15 | \usepackage{array} 16 | \usepackage{xcolor} 17 | \usepackage{placeins} 18 | \usepackage{multirow} 19 | \usepackage{float} 20 | \usepackage[shadow]{todonotes} 21 | \usepackage{lmodern} % Font Library 22 | \usepackage{amssymb,amsmath} % Math Fonts 23 | \usepackage{ifxetex,ifluatex} 24 | \usepackage{longtable} % Long table supprot 25 | \usepackage{vmargin} % Margin control 26 | \usepackage{tabularx} % Table support 27 | \usepackage{booktabs} % For \toprule, \midrule and \bottomrule 28 | \usepackage{csvsimple} % Import CSV files 29 | \usepackage{layout} % Show summary of page layout 30 | \usepackage{hyperref} % Hyperlink support 31 | \usepackage{titlesec} %Headings Styliser 32 | \usepackage{fancyhdr} % Header & Footer control 33 | \usepackage{comment} 34 | \usepackage[olditem,oldenum]{paralist} 35 | \usepackage{titling} 36 | \usepackage{tikz-timing} % Draw digital timing diagrams 37 | \usepackage{etoolbox} %to patch thebibliography 38 | \usepackage{listings} 39 | 40 | 41 | % Setup margins & page style 42 | 43 | %\setlength{\topmargin}{-0.5in} 44 | %\setlength{\textheight}{9in} 45 | %\setlength{\oddsidemargin}{0in} 46 | %\setlength{\evensidemargin}{0in} 47 | %\setlength{\textwidth}{6.5in} 48 | 49 | % Page Layout Control 50 | 51 | % Hyperlink formatting 52 | \hypersetup{ 53 | colorlinks=true, 54 | linkcolor=blue, 55 | filecolor=magenta, 56 | urlcolor=blue, 57 | } 58 | 59 | \urlstyle{same} 60 | 61 | % Font & Colour control 62 | \renewcommand{\familydefault}{\rmdefault} 63 | \renewcommand{\headlinecolor}{\color{rlcolor}} 64 | 65 | 66 | % For timing diagrams 67 | % 68 | % Reference a bus. 69 | % Usage: 70 | % \busref[3::0]{C/BE} -> C/BE[3::0] 71 | % \busref*{AD} -> AD# 72 | % \busref*[3::0]{C/BE} -> C/BE[3::0]# 73 | \NewDocumentCommand{\busref}{som}{\texttt{% 74 | #3% 75 | \IfValueTF{#2}{[#2]}{}% 76 | \IfBooleanTF{#1}{\#}{}% 77 | }} 78 | 79 | 80 | 81 | % Heading Formats 82 | \titleformat{\chapter} 83 | {\normalfont\Huge\bfseries\color{rlchapter}\sffamily}{\thechapter.}{1em}{}[{\titlerule[0.8pt]}] 84 | 85 | \titleformat{\section} 86 | {\color{rlsection}\sffamily\LARGE\bfseries}{\thesection}{1em}{} 87 | 88 | \titleformat{\subsection} 89 | {\color{rlsection}\sffamily\large\bfseries}{\thesubsection}{1em}{} 90 | 91 | \titleformat{\subsubsection} 92 | {\color{rlsection}\sffamily\large\bfseries}{\thesubsubsection}{1em}{} 93 | 94 | %add section number to bibliography 95 | \patchcmd{\thebibliography}{*}{}{}{} 96 | 97 | 98 | %\titlespacing*{\chapter} {0pt}{1.5ex plus 1ex minus .2ex}{2.3ex plus .2ex} 99 | \titlespacing*{\chapter} {0pt}{-50pt}{20pt} 100 | \titlespacing*{\section} {0pt}{1.5ex plus 1ex minus .2ex}{2.3ex plus .2ex} 101 | \titlespacing*{\subsection} {0pt}{1.25ex plus 1ex minus .2ex}{1.5ex plus .2ex} 102 | \titlespacing*{\subsubsection}{0pt}{1.25ex plus 1ex minus .2ex}{1.5ex plus .2ex} 103 | \titlespacing*{\paragraph} {0pt}{1.25ex plus 1ex minus .2ex}{0.5em} 104 | \titlespacing*{\subparagraph} {\parindent}{3.25ex plus 1ex minus .2ex}{0.5em} 105 | 106 | \setlength{\headheight}{13.6pt} % Fix spurious build warnings 107 | 108 | % Paragraph formatting 109 | %\setlength{\parindent}{1em} 110 | \setlength{\parskip}{0.5em} 111 | 112 | % Long table formatting 113 | % \newcolumntype{L}[1]{>{\raggedright\arraybackslash}p{#1}} 114 | % \newcolumntype{C}[1]{>{\centering\arraybackslash}p{#1}} 115 | % \newcolumntype{R}[1]{>{\raggedleft\arraybackslash}p{#1}} 116 | \usepackage{subfig} 117 | \captionsetup{belowskip=0pt,aboveskip=7pt} 118 | 119 | % Pad All Table Rows 120 | % \renewcommand{\arraystretch}{1.2} 121 | 122 | 123 | % Center all Floats (Figs & Tables) 124 | \makeatletter 125 | \g@addto@macro\@floatboxreset\centering 126 | \makeatother 127 | 128 | % Load appendix rules 129 | %\input{tex/preamble_appendix.tex} 130 | 131 | 132 | % 133 | % Custom Commands 134 | % 135 | 136 | % Define ToDo Colours 137 | \presetkeys{todonotes}{color=blue!30, backgroundcolor=white, bordercolor=black, figcolor=white}{} 138 | 139 | % Commands for register format figures. 140 | 141 | % New column types to use in tabular environment for instruction formats. 142 | % Allocate 0.18in per bit. 143 | \newcolumntype{I}{>{\centering\arraybackslash}p{0.18in}} 144 | % Two-bit centered column. 145 | \newcolumntype{W}{>{\centering\arraybackslash}p{0.36in}} 146 | % Three-bit centered column. 147 | \newcolumntype{F}{>{\centering\arraybackslash}p{0.54in}} 148 | % Four-bit centered column. 149 | \newcolumntype{Y}{>{\centering\arraybackslash}p{0.72in}} 150 | % Five-bit centered column. 151 | \newcolumntype{R}{>{\centering\arraybackslash}p{0.9in}} 152 | % Six-bit centered column. 153 | \newcolumntype{S}{>{\centering\arraybackslash}p{1.08in}} 154 | % Seven-bit centered column. 155 | \newcolumntype{O}{>{\centering\arraybackslash}p{1.26in}} 156 | % Eight-bit centered column. 157 | \newcolumntype{E}{>{\centering\arraybackslash}p{1.44in}} 158 | % Ten-bit centered column. 159 | \newcolumntype{T}{>{\centering\arraybackslash}p{1.8in}} 160 | % Twelve-bit centered column. 161 | \newcolumntype{M}{>{\centering\arraybackslash}p{2.2in}} 162 | % Sixteen-bit centered column. 163 | \newcolumntype{K}{>{\centering\arraybackslash}p{2.88in}} 164 | % Twenty-bit centered column. 165 | \newcolumntype{U}{>{\centering\arraybackslash}p{3.6in}} 166 | % Twenty-bit centered column. 167 | \newcolumntype{L}{>{\centering\arraybackslash}p{3.6in}} 168 | % Twenty-five-bit centered column. 169 | \newcolumntype{J}{>{\centering\arraybackslash}p{4in}} % RL Change 170 | 171 | \newcommand{\instbit}[1]{\mbox{\scriptsize #1}} 172 | \newcommand{\instbitrange}[2]{~\instbit{#1} \hfill \instbit{#2}~} 173 | \newcommand{\reglabel}[1]{\hfill \texttt{#1}\hfill\ } 174 | 175 | \newcommand{\wiri}{\textbf{WIRI}} 176 | \newcommand{\wpri}{\textbf{WPRI}} 177 | \newcommand{\wlrl}{\textbf{WLRL}} 178 | \newcommand{\warl}{\textbf{WARL}} 179 | -------------------------------------------------------------------------------- /rtl/verilog/ahb3lite_bfm.sv: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // ,------. ,--. ,--. // 3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. // 4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' // 5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. // 6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' // 7 | // `---' // 8 | // AHB3Lite Bus Functional Model // 9 | // // 10 | ///////////////////////////////////////////////////////////////////// 11 | // // 12 | // Copyright (C) 2017-2023 ROA Logic BV // 13 | // www.roalogic.com // 14 | // // 15 | // This source file may be used and distributed without // 16 | // restriction provided that this copyright statement is not // 17 | // removed from the file and that any derivative work contains // 18 | // the original copyright notice and the associated disclaimer. // 19 | // // 20 | // This soure file is free software; you can redistribute it // 21 | // and/or modify it under the terms of the GNU General Public // 22 | // License as published by the Free Software Foundation, // 23 | // either version 3 of the License, or (at your option) any later // 24 | // versions. The current text of the License can be found at: // 25 | // http://www.gnu.org/licenses/gpl.html // 26 | // // 27 | // This source file is distributed in the hope that it will be // 28 | // useful, but WITHOUT ANY WARRANTY; without even the implied // 29 | // warranty of MERCHANTABILITY or FITTNESS FOR A PARTICULAR // 30 | // PURPOSE. See the GNU General Public License for more details. // 31 | // // 32 | ///////////////////////////////////////////////////////////////////// 33 | 34 | 35 | /* 36 | * Limitations: 37 | * Does not support Error response/transactions (HRESP is ignored) 38 | */ 39 | 40 | module ahb3lite_master_bfm 41 | import ahb3lite_pkg::*; 42 | #( 43 | parameter HADDR_SIZE = 16, 44 | parameter HDATA_SIZE = 32 45 | ) 46 | ( 47 | input HRESETn, 48 | HCLK, 49 | output reg HSEL, 50 | output reg [HTRANS_SIZE-1:0] HTRANS, 51 | output reg [HBURST_SIZE-1:0] HBURST, 52 | output reg [HSIZE_SIZE-1:0] HSIZE, 53 | output reg HWRITE, 54 | output reg [HPROT_SIZE -1:0] HPROT, 55 | output reg HMASTLOCK, 56 | output reg [HADDR_SIZE -1:0] HADDR, 57 | output reg [HDATA_SIZE -1:0] HWDATA, 58 | input [HDATA_SIZE -1:0] HRDATA, 59 | input HREADY, 60 | input HRESP 61 | ); 62 | 63 | always @(negedge HRESETn) reset(); 64 | 65 | 66 | ///////////////////////////////////////////////////////// 67 | // 68 | // Tasks 69 | // 70 | task reset(); 71 | //Reset AHB Bus 72 | HSEL = 1'b0; 73 | HADDR = 'hx; 74 | HWDATA = 'hx; 75 | HWRITE = 'hx; 76 | HSIZE = 'hx; 77 | HBURST = 'hx; 78 | HPROT = 'hx; 79 | HTRANS = HTRANS_IDLE; 80 | HMASTLOCK = 'h0; 81 | 82 | @(posedge HRESETn); 83 | endtask 84 | 85 | 86 | task idle (); 87 | //Put AHB Bus in IDLE state 88 | //Call after write or read sequence 89 | wait4hready(); 90 | HSEL <= 1'b0; 91 | HTRANS <= HTRANS_IDLE; 92 | endtask 93 | 94 | 95 | task automatic write ( 96 | input [HADDR_SIZE -1:0] address, 97 | ref [HDATA_SIZE -1:0] data[], 98 | input [HSIZE_SIZE -1:0] size, 99 | input [HBURST_SIZE-1:0] burst 100 | ); 101 | int beats; 102 | 103 | beats = get_beats_per_burst(burst); 104 | if (beats < 0) beats = data.size(); 105 | 106 | fork 107 | ahb_cmd (address, size, burst, 1'b0, beats); 108 | ahb_data(address, size, burst, 1'b0, beats, data); 109 | join_any 110 | endtask 111 | 112 | 113 | task automatic read ( 114 | input [HADDR_SIZE -1:0] address, 115 | output [HDATA_SIZE -1:0] data[], 116 | input [HSIZE_SIZE -1:0] size, 117 | input [HBURST_SIZE-1:0] burst 118 | ); 119 | int beats; 120 | 121 | beats = get_beats_per_burst(burst); 122 | if (beats < 0) beats = data.size(); 123 | 124 | data = new[beats]; 125 | 126 | fork 127 | ahb_cmd (address, size, burst, 1'b1, beats); 128 | ahb_data(address, size, burst, 1'b1, beats, data); 129 | join_any 130 | endtask 131 | 132 | 133 | ///////////////////////////////////////////////////////// 134 | // 135 | // Sub-Tasks 136 | // 137 | task wait4hready; 138 | do 139 | @(posedge HCLK); 140 | while (!HREADY); 141 | endtask : wait4hready 142 | 143 | 144 | task automatic ahb_cmd ( 145 | input [HADDR_SIZE -1:0] addr, 146 | input [HSIZE_SIZE -1:0] size, 147 | input [HBURST_SIZE-1:0] burst, 148 | input rw, 149 | input int beats 150 | ); 151 | wait4hready(); 152 | HSEL <= 1'b1; 153 | HADDR <= addr; 154 | HWRITE <=~rw; 155 | HSIZE <= size; 156 | HBURST <= burst; 157 | HPROT <= 'hx; 158 | HTRANS <= HTRANS_NONSEQ; 159 | HMASTLOCK <= 1'b0; 160 | 161 | repeat (beats -1) 162 | begin 163 | wait4hready(); 164 | HADDR <= next_address(size,burst); 165 | HTRANS <= HTRANS_SEQ; 166 | end 167 | endtask : ahb_cmd 168 | 169 | 170 | task automatic ahb_data ( 171 | input [HADDR_SIZE -1:0] address, 172 | input [HSIZE_SIZE -1:0] size, 173 | input [HBURST_SIZE-1:0] burst, 174 | input rw, 175 | input int beats, 176 | ref [HDATA_SIZE -1:0] data[] 177 | ); 178 | logic [(HDATA_SIZE+7)/8 -1:0] byte_offset; 179 | logic [HDATA_SIZE -1:0] data_copy[], 180 | tmp_var; 181 | 182 | //copy data, prevent it being overwritten by caller 183 | data_copy = data; 184 | 185 | //get the address offset. No checks if the offset is legal 186 | byte_offset = address % (HDATA_SIZE/8); 187 | 188 | wait4hready(); 189 | 190 | if (rw) 191 | begin 192 | //extra cycle for reading 193 | //read at the end of the cycle 194 | wait4hready(); 195 | 196 | HWDATA <= 'hx; 197 | end 198 | 199 | //transfer beats 200 | for (int nbeat = 0; nbeat < beats; nbeat++) 201 | begin 202 | wait4hready(); 203 | 204 | if (!rw) 205 | begin 206 | //writing ... transfer from data-buffer to AHB-HWDATA 207 | HWDATA <= 'hx; 208 | 209 | //'byte' is reserved, so use nbyte 210 | for (int nbyte = 0; nbyte < get_bytes_per_beat(size); nbyte++) 211 | HWDATA[(nbyte + byte_offset)*8 +: 8] <= data_copy[nbeat][nbyte*8 +: 8]; 212 | end 213 | else 214 | begin 215 | //reading ... transfer from AHB-HRDATA to data-buffer 216 | 217 | //'byte' is reserved, so use nbyte 218 | //Store in temporary variable. 219 | // Using data[nbeat] directly fails when calling with a multi-dimensional dynamic array. Why???? 220 | for (int nbyte = 0; nbyte < get_bytes_per_beat(size); nbyte++) 221 | tmp_var[nbyte*8 +: 8] = HRDATA[(nbyte+byte_offset)*8 +: 8]; 222 | 223 | //copy read-data 224 | data[nbeat] = tmp_var; 225 | end 226 | 227 | byte_offset = (byte_offset + get_bytes_per_beat(size)) % (HDATA_SIZE/8); 228 | end 229 | endtask : ahb_data 230 | 231 | 232 | 233 | ///////////////////////////////////////////////////////// 234 | // 235 | // Functions 236 | // 237 | function int get_bytes_per_beat(input [HSIZE_SIZE-1:0] hsize); 238 | case (hsize) 239 | HSIZE_B8 : get_bytes_per_beat = 1; 240 | HSIZE_B16 : get_bytes_per_beat = 2; 241 | HSIZE_B32 : get_bytes_per_beat = 4; 242 | HSIZE_B64 : get_bytes_per_beat = 8; 243 | HSIZE_B128 : get_bytes_per_beat = 16; 244 | HSIZE_B256 : get_bytes_per_beat = 32; 245 | HSIZE_B512 : get_bytes_per_beat = 64; 246 | HSIZE_B1024: get_bytes_per_beat = 128; 247 | endcase 248 | endfunction : get_bytes_per_beat 249 | 250 | 251 | function int get_beats_per_burst(input [HBURST_SIZE-1:0] hburst); 252 | case (hburst) 253 | HBURST_SINGLE: get_beats_per_burst = 1; 254 | HBURST_INCR : get_beats_per_burst = -1; 255 | HBURST_INCR4 : get_beats_per_burst = 4; 256 | HBURST_WRAP4 : get_beats_per_burst = 4; 257 | HBURST_INCR8 : get_beats_per_burst = 8; 258 | HBURST_WRAP8 : get_beats_per_burst = 8; 259 | HBURST_INCR16: get_beats_per_burst = 16; 260 | HBURST_WRAP16: get_beats_per_burst = 16; 261 | endcase 262 | endfunction : get_beats_per_burst 263 | 264 | 265 | function [HADDR_SIZE-1:0] next_address(input [HSIZE_SIZE-1:0] hsize, hburst); 266 | //generate address mask 267 | int beats_per_burst; 268 | logic [10:0] addr_mask; 269 | 270 | beats_per_burst = get_beats_per_burst(hburst); 271 | beats_per_burst = beats_per_burst > 0 ? beats_per_burst : 1; 272 | addr_mask = (get_bytes_per_beat(hsize) * beats_per_burst) -1; 273 | 274 | case (hburst) 275 | HBURST_WRAP4 : next_address = (HADDR & ~addr_mask) | ((HADDR + get_bytes_per_beat(hsize)) & addr_mask); 276 | HBURST_WRAP8 : next_address = (HADDR & ~addr_mask) | ((HADDR + get_bytes_per_beat(hsize)) & addr_mask); 277 | HBURST_WRAP16: next_address = (HADDR & ~addr_mask) | ((HADDR + get_bytes_per_beat(hsize)) & addr_mask); 278 | default : next_address = HADDR + get_bytes_per_beat(hsize); 279 | endcase 280 | endfunction : next_address 281 | 282 | endmodule : ahb3lite_master_bfm 283 | -------------------------------------------------------------------------------- /rtl/verilog/ahb3lite_pkg.sv: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // ,------. ,--. ,--. // 3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. // 4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' // 5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. // 6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' // 7 | // `---' // 8 | // AMBA AHB3-Lite Package // 9 | // // 10 | ///////////////////////////////////////////////////////////////////// 11 | // // 12 | // Copyright (C) 2015-2021 Roa Logic BV // 13 | // www.roalogic.com // 14 | // // 15 | // This source file may be used and distributed without // 16 | // restriction provided that this copyright statement is not // 17 | // removed from the file and that any derivative work contains // 18 | // the original copyright notice and the associated disclaimer. // 19 | // // 20 | // THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY // 21 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // 22 | // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS // 23 | // FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR // 24 | // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // 25 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // 26 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE // 27 | // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR // 28 | // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // 29 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // 30 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT // 31 | // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // 32 | // POSSIBILITY OF SUCH DAMAGE. // 33 | // // 34 | ///////////////////////////////////////////////////////////////////// 35 | 36 | 37 | /************************************************ 38 | * AHB3 Lite Package 39 | */ 40 | package ahb3lite_pkg; 41 | localparam HTRANS_SIZE = 2; 42 | localparam HSIZE_SIZE = 3; 43 | localparam HBURST_SIZE = 3; 44 | localparam HPROT_SIZE = 4; 45 | 46 | //HTRANS 47 | localparam [1:0] HTRANS_IDLE = 2'b00, 48 | HTRANS_BUSY = 2'b01, 49 | HTRANS_NONSEQ = 2'b10, 50 | HTRANS_SEQ = 2'b11; 51 | 52 | //HSIZE 53 | localparam [2:0] HSIZE_B8 = 3'b000, 54 | HSIZE_B16 = 3'b001, 55 | HSIZE_B32 = 3'b010, 56 | HSIZE_B64 = 3'b011, 57 | HSIZE_B128 = 3'b100, //4-word line 58 | HSIZE_B256 = 3'b101, //8-word line 59 | HSIZE_B512 = 3'b110, 60 | HSIZE_B1024 = 3'b111, 61 | HSIZE_BYTE = HSIZE_B8, 62 | HSIZE_HWORD = HSIZE_B16, 63 | HSIZE_WORD = HSIZE_B32, 64 | HSIZE_DWORD = HSIZE_B64; 65 | 66 | //HBURST 67 | localparam [2:0] HBURST_SINGLE = 3'b000, 68 | HBURST_INCR = 3'b001, 69 | HBURST_WRAP4 = 3'b010, 70 | HBURST_INCR4 = 3'b011, 71 | HBURST_WRAP8 = 3'b100, 72 | HBURST_INCR8 = 3'b101, 73 | HBURST_WRAP16 = 3'b110, 74 | HBURST_INCR16 = 3'b111; 75 | 76 | //HPROT 77 | localparam [3:0] HPROT_OPCODE = 4'b0000, 78 | HPROT_DATA = 4'b0001, 79 | HPROT_USER = 4'b0000, 80 | HPROT_PRIVILEGED = 4'b0010, 81 | HPROT_NON_BUFFERABLE = 4'b0000, 82 | HPROT_BUFFERABLE = 4'b0100, 83 | HPROT_NON_CACHEABLE = 4'b0000, 84 | HPROT_CACHEABLE = 4'b1000; 85 | 86 | //HRESP 87 | localparam HRESP_OKAY = 1'b0, 88 | HRESP_ERROR = 1'b1; 89 | 90 | 91 | /* 92 | * functions 93 | */ 94 | 95 | //is this a wrap burst? 96 | function automatic logic ahb_is_wrap_burst; 97 | input [HBURST_SIZE-1:0] hburst; 98 | 99 | ahb_is_wrap_burst = |hburst[2:1] & ~hburst[0]; 100 | endfunction : ahb_is_wrap_burst 101 | 102 | 103 | //How many beats in burst 104 | function automatic int ahb_hburst2beats; 105 | input [HBURST_SIZE-1:0] hburst; 106 | 107 | case (hburst) 108 | HBURST_SINGLE: ahb_hburst2beats = 1; 109 | HBURST_INCR : ahb_hburst2beats = 1; //actually unlimited 110 | HBURST_WRAP4 : ahb_hburst2beats = 4; 111 | HBURST_INCR4 : ahb_hburst2beats = 4; 112 | HBURST_WRAP8 : ahb_hburst2beats = 8; 113 | HBURST_INCR8 : ahb_hburst2beats = 8; 114 | HBURST_WRAP16: ahb_hburst2beats = 16; 115 | HBURST_INCR16: ahb_hburst2beats = 16; 116 | endcase 117 | endfunction : ahb_hburst2beats 118 | 119 | 120 | //How many bytes per beat 121 | function automatic int ahb_hsize2bytes; 122 | input [HBURST_SIZE-1:0] hsize; 123 | 124 | ahb_hsize2bytes = 1'h1 << hsize; 125 | endfunction : ahb_hsize2bytes 126 | 127 | 128 | //burst address mask 129 | function automatic logic [6:0] ahb_burst_address_mask; 130 | input int hdata_size; 131 | 132 | //returns a mask for the lesser bits of the address 133 | //meaning bits [ 0] for 16bit data 134 | // [1:0] for 32bit data 135 | // [2:0] for 64bit data 136 | //etc 137 | 138 | //default value, prevent warnings 139 | ahb_burst_address_mask = 0; 140 | 141 | //What are the lesser bits in HADDR? 142 | case (hdata_size) 143 | 1024: ahb_burst_address_mask = 7'b111_1111; 144 | 512: ahb_burst_address_mask = 7'b011_1111; 145 | 256: ahb_burst_address_mask = 7'b001_1111; 146 | 128: ahb_burst_address_mask = 7'b000_1111; 147 | 64: ahb_burst_address_mask = 7'b000_0111; 148 | 32: ahb_burst_address_mask = 7'b000_0011; 149 | 16: ahb_burst_address_mask = 7'b000_0001; 150 | default: ahb_burst_address_mask = 7'b000_0000; 151 | endcase 152 | endfunction : ahb_burst_address_mask 153 | 154 | endpackage 155 | 156 | 157 | 158 | /************************************************ 159 | * AHB3 Lite Interface 160 | */ 161 | `ifndef AHB3_INTERFACES 162 | `define AHB3_INTERFACES 163 | interface ahb3lite_bus #( 164 | parameter HADDR_SIZE = 32, 165 | parameter HDATA_SIZE = 32 166 | ) 167 | ( 168 | input logic HCLK,HRESETn 169 | ); 170 | logic HSEL; 171 | logic [HADDR_SIZE -1:0] HADDR; 172 | logic [HDATA_SIZE -1:0] HWDATA; 173 | logic [HDATA_SIZE -1:0] HRDATA; 174 | logic HWRITE; 175 | logic [ 2:0] HSIZE; 176 | logic [ 2:0] HBURST; 177 | logic [ 3:0] HPROT; 178 | logic [ 1:0] HTRANS; 179 | logic HMASTLOCK; 180 | logic HREADY; 181 | logic HREADYOUT; 182 | logic HRESP; 183 | 184 | `ifdef SIM 185 | // Master CB Interface Definitions 186 | clocking cb_master @(posedge HCLK); 187 | output HSEL; 188 | output HADDR; 189 | output HWDATA; 190 | input HRDATA; 191 | output HWRITE; 192 | output HSIZE; 193 | output HBURST; 194 | output HPROT; 195 | output HTRANS; 196 | output HMASTLOCK; 197 | input HREADY; 198 | input HRESP; 199 | endclocking 200 | 201 | modport master_cb ( 202 | clocking cb_master, 203 | input HRESETn 204 | ); 205 | 206 | // Slave Interface Definitions 207 | clocking cb_slave @(posedge HCLK); 208 | input HSEL; 209 | input HADDR; 210 | input HWDATA; 211 | output HRDATA; 212 | input HWRITE; 213 | input HSIZE; 214 | input HBURST; 215 | input HPROT; 216 | input HTRANS; 217 | input HMASTLOCK; 218 | input HREADY; 219 | output HREADYOUT; 220 | output HRESP; 221 | endclocking 222 | 223 | modport slave_cb ( 224 | clocking cb_slave, 225 | input HRESETn 226 | ); 227 | `endif 228 | 229 | modport master ( 230 | input HRESETn, 231 | input HCLK, 232 | output HSEL, 233 | output HADDR, 234 | output HWDATA, 235 | input HRDATA, 236 | output HWRITE, 237 | output HSIZE, 238 | output HBURST, 239 | output HPROT, 240 | output HTRANS, 241 | output HMASTLOCK, 242 | input HREADY, 243 | input HRESP 244 | ); 245 | 246 | modport slave ( 247 | input HRESETn, 248 | input HCLK, 249 | input HSEL, 250 | input HADDR, 251 | input HWDATA, 252 | output HRDATA, 253 | input HWRITE, 254 | input HSIZE, 255 | input HBURST, 256 | input HPROT, 257 | input HTRANS, 258 | input HMASTLOCK, 259 | input HREADY, 260 | output HREADYOUT, 261 | output HRESP 262 | ); 263 | endinterface 264 | 265 | 266 | /************************************************ 267 | * APB Lite Interface 268 | */ 269 | interface apb_bus #( 270 | parameter PADDR_SIZE = 6, 271 | parameter PDATA_SIZE = 8 272 | ) 273 | ( 274 | input logic PCLK,PRESETn 275 | ); 276 | logic PSEL; 277 | logic PENABLE; 278 | logic [ 2:0] PPROT; 279 | logic PWRITE; 280 | logic [PDATA_SIZE/8-1:0] PSTRB; 281 | logic [PADDR_SIZE -1:0] PADDR; 282 | logic [PDATA_SIZE -1:0] PWDATA; 283 | logic [PDATA_SIZE -1:0] PRDATA; 284 | logic PREADY; 285 | logic PSLVERR; 286 | 287 | modport master ( 288 | input PRESETn, 289 | input PCLK, 290 | output PSEL, 291 | output PENABLE, 292 | output PPROT, 293 | output PADDR, 294 | output PWRITE, 295 | output PSTRB, 296 | output PWDATA, 297 | input PRDATA, 298 | input PREADY, 299 | input PSLVERR 300 | ); 301 | 302 | modport slave ( 303 | import is_read, is_write, 304 | 305 | input PRESETn, 306 | input PCLK, 307 | input PSEL, 308 | input PENABLE, 309 | input PPROT, 310 | input PADDR, 311 | input PWRITE, 312 | input PSTRB, 313 | input PWDATA, 314 | output PRDATA, 315 | output PREADY, 316 | output PSLVERR 317 | ); 318 | 319 | //Is this a valid read access? 320 | function automatic is_read(); 321 | return PSEL & PENABLE & ~PWRITE; 322 | endfunction 323 | 324 | //Is this a valid write access? 325 | function automatic is_write(); 326 | return PSEL & PENABLE & PWRITE; 327 | endfunction 328 | 329 | //Is this a valid write to address 0x...? 330 | //Take 'address' as an argument 331 | function automatic is_write_to_adr(input integer bits, input [PADDR_SIZE-1:0] address); 332 | logic [$bits(PADDR)-1:0] mask; 333 | 334 | mask = -1 >> ($bits(PADDR) -bits); //only 'bits' LSBs should be '1' 335 | return is_write() & ( (PADDR & mask) == (address & mask) ); 336 | endfunction 337 | 338 | //What data is written? 339 | //- Handles PSTRB, takes previous register/data value as an argument 340 | function automatic [PDATA_SIZE-1:0] get_write_value (input [PDATA_SIZE-1:0] orig_val); 341 | for (int n=0; n < PDATA_SIZE/8; n++) 342 | get_write_value[n*8 +: 8] = PSTRB[n] ? PWDATA[n*8 +: 8] : orig_val[n*8 +: 8]; 343 | endfunction 344 | 345 | 346 | //Is this the 'setup' phase of the transfer? 347 | function automatic is_setup_phase(); 348 | return PSEL & ~PENABLE; 349 | endfunction 350 | 351 | 352 | //Negate PREADY, Negate PSLVERR 353 | task set_not_ready(); 354 | PREADY = 1'b0; 355 | PSLVERR = 1'b0; 356 | endtask 357 | 358 | //Assert PREADY, Negate PSLVERR 359 | task set_ready(); 360 | PREADY = 1'b1; 361 | PSLVERR = 1'b0; 362 | endtask 363 | 364 | //Assert PREADY, Assert PSLVERR 365 | task set_error(); 366 | PREADY = 1'b1; 367 | PSLVERR = 1'b1; 368 | endtask 369 | endinterface 370 | `endif 371 | -------------------------------------------------------------------------------- /rtl/verilog/ahb_protocol_checker.sv: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // ,------. ,--. ,--. // 3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. // 4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' // 5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. // 6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' // 7 | // `---' // 8 | // AHB Bus Protocol Checker // 9 | // // 10 | ///////////////////////////////////////////////////////////////////// 11 | // // 12 | // Copyright (C) 2014-2024 ROA Logic BV // 13 | // www.roalogic.com // 14 | // // 15 | // This source file may be used and distributed without // 16 | // restriction provided that this copyright statement is not // 17 | // removed from the file and that any derivative work contains // 18 | // the original copyright notice and the associated disclaimer. // 19 | // // 20 | // This soure file is free software; you can redistribute it // 21 | // and/or modify it under the terms of the GNU General Public // 22 | // License as published by the Free Software Foundation, // 23 | // either version 3 of the License, or (at your option) any later // 24 | // versions. The current text of the License can be found at: // 25 | // http://www.gnu.org/licenses/gpl.html // 26 | // // 27 | // This source file is distributed in the hope that it will be // 28 | // useful, but WITHOUT ANY WARRANTY; without even the implied // 29 | // warranty of MERCHANTABILITY or FITTNESS FOR A PARTICULAR // 30 | // PURPOSE. See the GNU General Public License for more details. // 31 | // // 32 | ///////////////////////////////////////////////////////////////////// 33 | 34 | 35 | module ahb_protocol_checker 36 | import ahb3lite_pkg::*; 37 | #( 38 | parameter HADDR_SIZE = 32, //HADDR bus width 39 | parameter HDATA_SIZE = 32, //HDATA bus width 40 | 41 | parameter CHECK_HPROT = 1, //1: check HPROT signal 42 | //0: do not check HPROT signal 43 | parameter WATCHDOG_TIMEOUT = 128, //number of cycles before watchdog triggers 44 | //WATCHDOG_TIMEOUT==0 disables watchdog 45 | parameter STOP_ON_WATCHDOG = 1 //1: stop simulation if watchdog triggers 46 | //0: do not stop simulation if watchdog triggers 47 | ) 48 | ( 49 | //AHB Interface 50 | input HRESETn, 51 | input HCLK, 52 | 53 | input HSEL, 54 | input [HTRANS_SIZE-1:0] HTRANS, 55 | input [HSIZE_SIZE -1:0] HSIZE, 56 | input [HBURST_SIZE-1:0] HBURST, 57 | input [HPROT_SIZE -1:0] HPROT, 58 | input HWRITE, 59 | input HMASTLOCK, 60 | input [HADDR_SIZE -1:0] HADDR, 61 | input [HDATA_SIZE -1:0] HWDATA, 62 | input [HDATA_SIZE -1:0] HRDATA, 63 | input HREADY, 64 | input HRESP 65 | ); 66 | ////////////////////////////////////////////////////////////////// 67 | // 68 | // Variables 69 | // 70 | logic is_burst, 71 | last_burst_beat; 72 | logic dly_hsel; 73 | logic [HTRANS_SIZE-1:0] curr_htrans, 74 | prev_htrans, 75 | dly_htrans; 76 | logic [HSIZE_SIZE -1:0] prev_hsize, 77 | dly_hsize; 78 | logic [HBURST_SIZE-1:0] prev_hburst, 79 | dly_hburst; 80 | logic [HPROT_SIZE -1:0] dly_hprot; 81 | logic prev_hwrite, 82 | dly_hwrite; 83 | logic dly_hmastlock; 84 | logic [HADDR_SIZE -1:0] prev_haddr, 85 | dly_haddr; 86 | logic [HDATA_SIZE -1:0] dly_hwdata, 87 | dly_hrdata; 88 | logic dly_hready, 89 | dly_hresp; 90 | 91 | integer burst_cnt, 92 | watchdog_cnt; 93 | 94 | integer errors = 0; 95 | integer warnings = 0; 96 | 97 | 98 | ////////////////////////////////////////////////////////////////// 99 | // 100 | // Functions 101 | // 102 | function automatic [HADDR_SIZE-1:0] hsize2adrmask (input [HSIZE_SIZE-1:0] hsize); 103 | case (hsize) 104 | HSIZE_B8 : hsize2adrmask = {HADDR_SIZE{1'b1}}; 105 | HSIZE_B16 : hsize2adrmask = {HADDR_SIZE{1'b1}} << 1; 106 | HSIZE_B32 : hsize2adrmask = {HADDR_SIZE{1'b1}} << 2; 107 | HSIZE_B64 : hsize2adrmask = {HADDR_SIZE{1'b1}} << 3; 108 | HSIZE_B128 : hsize2adrmask = {HADDR_SIZE{1'b1}} << 4; 109 | HSIZE_B256 : hsize2adrmask = {HADDR_SIZE{1'b1}} << 5; 110 | HSIZE_B512 : hsize2adrmask = {HADDR_SIZE{1'b1}} << 6; 111 | HSIZE_B1024: hsize2adrmask = {HADDR_SIZE{1'b1}} << 7; 112 | endcase 113 | endfunction : hsize2adrmask 114 | 115 | 116 | function automatic [HDATA_SIZE-1:0] datamask ( 117 | input [HADDR_SIZE-1:0] haddr, 118 | input [HSIZE_SIZE-1:0] hsize 119 | ); 120 | int offset; 121 | 122 | offset = 8 * haddr[0 +: $clog2(HDATA_SIZE/8)]; 123 | 124 | datamask = {HDATA_SIZE{1'b0}}; 125 | case (hsize) 126 | HSIZE_B8 : datamask |= { 8{1'b1}} << offset; 127 | HSIZE_B16 : datamask |= { 16{1'b1}} << offset; 128 | HSIZE_B32 : datamask |= { 32{1'b1}} << offset; 129 | HSIZE_B64 : datamask |= { 64{1'b1}} << offset; 130 | HSIZE_B128 : datamask |= { 128{1'b1}} << offset; 131 | HSIZE_B256 : datamask |= { 256{1'b1}} << offset; 132 | HSIZE_B512 : datamask |= { 512{1'b1}} << offset; 133 | HSIZE_B1024: datamask |= {1024{1'b1}} << offset; 134 | endcase 135 | endfunction : datamask 136 | 137 | 138 | ////////////////////////////////////////////////////////////////// 139 | // 140 | // Tasks 141 | // 142 | task welcome_msg(); 143 | $display("\n\n"); 144 | $display ("------------------------------------------------------------"); 145 | $display (" ,------. ,--. ,--. "); 146 | $display (" | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. "); 147 | $display (" | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' "); 148 | $display (" | |\\ \\ ' '-' '\\ '-' | | '--.' '-' ' '-' || |\\ `--. "); 149 | $display (" `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' "); 150 | $display ("- AHB Protocol Checker ------------------ `---' ----------"); 151 | $display ("- Instance: %m"); 152 | $display ("------------------------------------------------------------"); 153 | $display ("\n"); 154 | endtask 155 | 156 | 157 | task goodbye_msg(); 158 | $display("\n\n"); 159 | $display ("------------------------------------------------------------"); 160 | $display (" ,------. ,--. ,--. "); 161 | $display (" | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. "); 162 | $display (" | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' "); 163 | $display (" | |\\ \\ ' '-' '\\ '-' | | '--.' '-' ' '-' || |\\ `--. "); 164 | $display (" `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' "); 165 | $display ("- AHB Protocol Checker ------------------ `---' ----------"); 166 | $display ("------------------------------------------------------------"); 167 | $display (" Errors: %0d", errors); 168 | $display ("------------------------------------------------------------"); 169 | endtask 170 | 171 | 172 | task ahb_error; 173 | input string msg; 174 | 175 | $error ("AHB ERROR (%m): %s @%0t", msg, $time); 176 | errors++; 177 | endtask : ahb_error 178 | 179 | task ahb_warning; 180 | input string msg; 181 | 182 | $warning ("AHB WARNING (%m): %s @%0t", msg, $time); 183 | warnings++; 184 | endtask : ahb_warning 185 | 186 | 187 | /* 188 | * Check HTRANS 189 | */ 190 | task check_htrans; 191 | if (curr_htrans == HTRANS_IDLE) 192 | begin 193 | //IDLE after BUSY only during a undefined length burst 194 | if (is_burst && prev_htrans === HTRANS_BUSY && dly_hburst !== HBURST_INCR) 195 | begin 196 | ahb_error("Illegal termination of a fixed length burst"); 197 | end 198 | 199 | //IDLE only when non-incrementing burst terminates 200 | if (is_burst && !last_burst_beat && dly_hburst !== HBURST_INCR) 201 | begin 202 | ahb_error ("Expected HTRANS=SEQ or BUSY, seen IDLE instead"); 203 | end 204 | end 205 | 206 | if (curr_htrans === HTRANS_BUSY) 207 | begin 208 | //BUSY only during a burst 209 | if (!is_burst) 210 | ahb_error ("HTRANS=BUSY, but not a burst transfer"); 211 | end 212 | 213 | if (curr_htrans === HTRANS_NONSEQ) 214 | begin 215 | //NONSEQ after BUSY only during undefined length burst 216 | if (is_burst && prev_htrans === HTRANS_BUSY && dly_hburst !== HBURST_INCR) 217 | begin 218 | ahb_error ("Illegal termination of a fixed length burst"); 219 | end 220 | 221 | //NONSEQ only when burst terminates 222 | if (is_burst && !last_burst_beat && dly_hburst !== HBURST_INCR) 223 | begin 224 | ahb_error ("Expected HTRANS=SEQ or BUSY, seen NONSEQ instead"); 225 | end 226 | end 227 | 228 | if (curr_htrans == HTRANS_SEQ) 229 | begin 230 | //SEQ only during a burst 231 | if (!is_burst || last_burst_beat) 232 | ahb_error ("HTRANS=SEQ, but not a burst transfer"); 233 | end 234 | 235 | 236 | //HTRANS must remain stable when slave not ready 237 | if (!dly_hready && curr_htrans !== dly_htrans) 238 | begin 239 | ahb_error ("HTRANS must remain stable during wait states"); 240 | end 241 | 242 | //HTRANS may not contain 'x' during transactions 243 | if (^curr_htrans === 1'bx) 244 | begin 245 | ahb_error ("HTRANS undefined"); 246 | end 247 | endtask : check_htrans 248 | 249 | 250 | 251 | /* 252 | * Check HSIZE 253 | */ 254 | task check_hsize; 255 | //Check HSIZE versus data bus width 256 | logic out_of_range; 257 | 258 | case (HSIZE) 259 | HSIZE_B1024: out_of_range = HDATA_SIZE < 1024 ? 1'b1 : 1'b0; 260 | HSIZE_B512 : out_of_range = HDATA_SIZE < 512 ? 1'b1 : 1'b0; 261 | HSIZE_B256 : out_of_range = HDATA_SIZE < 256 ? 1'b1 : 1'b0; 262 | HSIZE_B128 : out_of_range = HDATA_SIZE < 128 ? 1'b1 : 1'b0; 263 | HSIZE_DWORD: out_of_range = HDATA_SIZE < 64 ? 1'b1 : 1'b0; 264 | HSIZE_WORD : out_of_range = HDATA_SIZE < 32 ? 1'b1 : 1'b0; 265 | HSIZE_HWORD: out_of_range = HDATA_SIZE < 16 ? 1'b1 : 1'b0; 266 | default : out_of_range = 1'b0; 267 | endcase 268 | 269 | if (HSEL && out_of_range) 270 | begin 271 | $error ("AHB ERROR (%m): Illegal HSIZE (%0b) @%0t", HSIZE, $time); 272 | end 273 | 274 | //HSIZE must remain stable during a burst 275 | if (is_burst && !last_burst_beat && HSIZE !== dly_hsize) 276 | begin 277 | ahb_error ("HSIZE must remain stable during burst"); 278 | end 279 | 280 | //HSIZE must remain stable when slave not ready 281 | if (!dly_hready && HSIZE !== dly_hsize) 282 | begin 283 | ahb_error ("HSIZE must remain stable during wait states"); 284 | end 285 | 286 | //HSIZE may not contain 'x' during transactions 287 | if (HSEL && ^HSIZE === 1'bx) 288 | begin 289 | ahb_error ("HSIZE undefined"); 290 | end 291 | endtask : check_hsize 292 | 293 | 294 | 295 | /* 296 | * Check HBURST 297 | */ 298 | task check_hburst; 299 | //HBURST must remain stable during a burst 300 | //1st line checks fixed length burst 301 | //2nd line checks undefinite (INCR) burst 302 | if ( (is_burst && !last_burst_beat && dly_hburst !== HBURST_INCR && HBURST !== dly_hburst) || 303 | (dly_hburst === HBURST_INCR && HTRANS !== HTRANS_IDLE && HTRANS !== HTRANS_NONSEQ && HBURST !== dly_hburst) ) 304 | begin 305 | ahb_error ("HBURST must remain stable during burst"); 306 | end 307 | 308 | //HBURST must remain stable when slave not ready 309 | if (!dly_hready && HBURST !== dly_hburst) 310 | begin 311 | ahb_error ("HBURST must remain stable during wait states"); 312 | end 313 | 314 | //HBURST may not contain 'x' during transactions 315 | if (curr_htrans !== HTRANS_IDLE && ^HBURST === 1'bx) 316 | begin 317 | ahb_error ("HBURST undefined"); 318 | end 319 | endtask : check_hburst 320 | 321 | 322 | /* 323 | * Check HPROT 324 | */ 325 | task check_hprot; 326 | //HPROT must remain stable during a burst 327 | if (is_burst && !last_burst_beat && HPROT !== dly_hprot) 328 | begin 329 | ahb_error ("HPROT must remain stable during burst"); 330 | end 331 | 332 | //HPROT must remain stable when slave not ready 333 | if (!dly_hready && HPROT !== dly_hprot) 334 | begin 335 | ahb_error ("HPROT must remain stable during wait states"); 336 | end 337 | 338 | //HPROT may not contain 'x' during transactions 339 | if (curr_htrans !== HTRANS_IDLE && ^HPROT === 1'bx) 340 | begin 341 | ahb_error("HPROT undefined"); 342 | end 343 | endtask : check_hprot 344 | 345 | 346 | /* 347 | * Check HWRITE 348 | */ 349 | task check_hwrite; 350 | //HWRITE must remain stable during a burst 351 | if (is_burst && !last_burst_beat && HWRITE !== dly_hwrite) 352 | begin 353 | ahb_error ("HWRITE must remain stable during burst"); 354 | end 355 | 356 | //HWRITE must remain stable when slave not ready 357 | if (!dly_hready && HWRITE !== dly_hwrite) 358 | begin 359 | ahb_error ("HWRITE must remain stable during wait states"); 360 | end 361 | 362 | //HWRITE may not contain 'x' during transactions 363 | if (curr_htrans !== HTRANS_IDLE && (HWRITE === 1'bx || HWRITE === 1'bz)) 364 | begin 365 | ahb_error ("HWRITE undefined"); 366 | end 367 | endtask : check_hwrite 368 | 369 | 370 | 371 | /* 372 | * Check HADDR 373 | */ 374 | task check_haddr; 375 | //HADDR should increase by HSIZE during bursts (wrap for wrapping-bursts) 376 | logic incr_haddr; 377 | logic [HADDR_SIZE-1:0] norm_addr, 378 | nxt_addr; 379 | 380 | //HADDR should be an HSIZE aligned address 381 | if (curr_htrans !== HTRANS_IDLE && |(HADDR & ~hsize2adrmask(HSIZE))) 382 | begin 383 | ahb_error ("HADDR not aligned with HSIZE"); 384 | end 385 | 386 | //normalize address 387 | case (prev_hsize) 388 | HSIZE_B1024: norm_addr = prev_haddr >> 7; 389 | HSIZE_B512 : norm_addr = prev_haddr >> 6; 390 | HSIZE_B256 : norm_addr = prev_haddr >> 5; 391 | HSIZE_B128 : norm_addr = prev_haddr >> 4; 392 | HSIZE_DWORD: norm_addr = prev_haddr >> 3; 393 | HSIZE_WORD : norm_addr = prev_haddr >> 2; 394 | HSIZE_HWORD: norm_addr = prev_haddr >> 1; 395 | default : norm_addr = prev_haddr; 396 | endcase 397 | 398 | //next address 399 | nxt_addr = norm_addr +1; 400 | 401 | //handle normalized wrap 402 | case (prev_hburst) 403 | HBURST_WRAP4 : nxt_addr = {norm_addr[HADDR_SIZE-1:2],nxt_addr[1:0]}; 404 | HBURST_WRAP8 : nxt_addr = {norm_addr[HADDR_SIZE-1:3],nxt_addr[2:0]}; 405 | HBURST_WRAP16: nxt_addr = {norm_addr[HADDR_SIZE-1:4],nxt_addr[3:0]}; 406 | endcase 407 | 408 | //move into correct address range 409 | case (prev_hsize) 410 | HSIZE_B1024: nxt_addr = nxt_addr << 7; 411 | HSIZE_B512 : nxt_addr = nxt_addr << 6; 412 | HSIZE_B256 : nxt_addr = nxt_addr << 5; 413 | HSIZE_B128 : nxt_addr = nxt_addr << 4; 414 | HSIZE_DWORD: nxt_addr = nxt_addr << 3; 415 | HSIZE_WORD : nxt_addr = nxt_addr << 2; 416 | HSIZE_HWORD: nxt_addr = nxt_addr << 1; 417 | default : ; 418 | endcase 419 | 420 | if (is_burst && !last_burst_beat && HREADY && HADDR !== nxt_addr) 421 | begin 422 | $error ("AHB ERROR (%m): Seen HADDR=%0x, but expected %0x @%0t", HADDR, nxt_addr, $time); 423 | end 424 | 425 | //HADDR must remain stable when slave not ready 426 | if (!dly_hready && HADDR !== dly_haddr) 427 | begin 428 | ahb_error ("HADDR must remain stable during wait states"); 429 | end 430 | 431 | //HADDR may not contain 'x' during transactions 432 | if (curr_htrans !== HTRANS_IDLE && ^HADDR === 1'bx) 433 | begin 434 | ahb_error ("HADDR undefined"); 435 | end 436 | endtask : check_haddr 437 | 438 | 439 | 440 | /* 441 | * Check HWDATA 442 | */ 443 | task check_hwdata; 444 | //HWDATA must remain stable when slave not ready 445 | if (!dly_hready && dly_hwrite && HWDATA !== dly_hwdata) 446 | begin 447 | ahb_error ("HWDATA must remain stable during wait states"); 448 | end 449 | 450 | //HWDATA contains 'x'? 451 | if (prev_htrans !== HTRANS_IDLE && prev_hwrite && 452 | ^(HWDATA & datamask(prev_haddr, prev_hsize) === 1'bx)) 453 | begin 454 | ahb_warning ("HWDATA contains 'x'"); 455 | end 456 | 457 | endtask : check_hwdata 458 | 459 | 460 | 461 | /* 462 | * Check slave response 463 | */ 464 | task check_slave_response; 465 | //Always zero-wait-state response to IDLE 466 | if ( (prev_htrans === HTRANS_IDLE) && (!HREADY || (HRESP !== HRESP_OKAY)) ) 467 | begin 468 | $error ("AHB ERROR (%m): Slave must provide a zero wait state response to IDLE transfers (HREADY=%0b, HRESP=%0b) @%0t", HREADY, HRESP, $time); 469 | end 470 | 471 | //HREADY may not contain 'x' 472 | if (HREADY === 1'bx || HREADY === 1'bz) 473 | begin 474 | ahb_error ("HREADY undefined"); 475 | end 476 | 477 | //always zero-wait-state response to BUSY 478 | //unless slave already inserted wait-states 479 | if ( (prev_htrans === HTRANS_BUSY) && dly_hready && (!HREADY || (HRESP !== HRESP_OKAY)) ) 480 | begin 481 | $error ("AHB ERROR (%m): Slave must provide a zero wait state response to BUSY transfers (HREADY=%0b, HRESP=%0b) @%0t", HREADY, HRESP, $time); 482 | end 483 | 484 | //HRESP may not contain 'x' 485 | if (HREADY && (HRESP === 1'bx || HRESP === 1'bz)) 486 | begin 487 | ahb_error ("HRESP undefined"); 488 | end 489 | 490 | 491 | //ERROR is a 2 cycle response 492 | if ( (( HREADY && HRESP ) && !(!dly_hready && dly_hresp)) || 493 | ((!dly_hready && dly_hresp) && !( HREADY && HRESP )) ) 494 | begin 495 | $error ("AHB ERROR (%m): Incorrect ERROR sequence @%0t", $time); 496 | end 497 | endtask : check_slave_response 498 | 499 | 500 | ////////////////////////////////////////////////////////////////// 501 | // 502 | // Module Body 503 | // 504 | 505 | 506 | /* 507 | * Check HTRANS 508 | */ 509 | assign curr_htrans = !HSEL ? HTRANS_IDLE : HTRANS; 510 | 511 | always @(posedge HCLK,negedge HRESETn) 512 | if (!HRESETn) dly_htrans <= HTRANS_IDLE; 513 | else dly_htrans <= curr_htrans; 514 | 515 | 516 | always @(posedge HCLK, negedge HRESETn) 517 | if (!HRESETn) prev_htrans <= HTRANS_IDLE; 518 | else if ( HREADY ) prev_htrans <= curr_htrans; 519 | 520 | 521 | always @(posedge HCLK,negedge HRESETn) 522 | if (!HRESETn) is_burst <= 1'b0; 523 | else if ( HREADY ) 524 | begin 525 | if ( curr_htrans === HTRANS_IDLE ) is_burst <= 1'b0; 526 | else if ( HTRANS === HTRANS_NONSEQ && 527 | HBURST !== HBURST_SINGLE ) is_burst <= 1'b1; 528 | else if ( HBURST === HTRANS_NONSEQ && 529 | HBURST === HBURST_SINGLE ) is_burst <= 1'b0; //terminated INCR burst 530 | else if ( last_burst_beat ) is_burst <= 1'b0; //terminated regular burst 531 | end 532 | 533 | always @(posedge HCLK) check_htrans(); 534 | 535 | 536 | /* 537 | * Check HSIZE 538 | */ 539 | always @(posedge HCLK) 540 | if (HREADY) prev_hsize <= HSIZE; 541 | 542 | always @(posedge HCLK) dly_hsize <= HSIZE; 543 | always @(posedge HCLK) check_hsize(); 544 | 545 | 546 | /* 547 | * Check HBURST 548 | */ 549 | always @(posedge HCLK) 550 | if (HREADY) 551 | begin 552 | if (curr_htrans === HTRANS_NONSEQ) 553 | begin 554 | case (HBURST) 555 | HBURST_WRAP4 : burst_cnt <= 3; // 4 556 | HBURST_INCR4 : burst_cnt <= 3; // 4 557 | HBURST_WRAP8 : burst_cnt <= 7; // 8 558 | HBURST_INCR8 : burst_cnt <= 7; // 8 559 | HBURST_WRAP16: burst_cnt <= 15; //16 560 | HBURST_INCR16: burst_cnt <= 15; //16 561 | default : burst_cnt <= -1; 562 | endcase 563 | end 564 | else if (curr_htrans === HTRANS_SEQ) 565 | begin 566 | burst_cnt <= burst_cnt -1; 567 | end 568 | end 569 | 570 | assign last_burst_beat = ~|burst_cnt; 571 | 572 | 573 | always @(posedge HCLK) 574 | if (HREADY) prev_hburst <= HBURST; 575 | 576 | always @(posedge HCLK) dly_hburst <= HBURST; 577 | always @(posedge HCLK) check_hburst(); 578 | 579 | 580 | /* 581 | * Check HPROT 582 | */ 583 | always @(posedge HCLK) if (CHECK_HPROT) dly_hprot <= HPROT; 584 | always @(posedge HCLK) if (CHECK_HPROT) check_hprot(); 585 | 586 | 587 | /* 588 | * Check HADDR 589 | */ 590 | always @(posedge HCLK) 591 | if (HREADY) prev_haddr <= HADDR; 592 | 593 | always @(posedge HCLK) dly_haddr <= HADDR; 594 | always @(posedge HCLK) check_haddr(); 595 | 596 | 597 | /* 598 | * Check HWDATA 599 | */ 600 | always @(posedge HCLK) dly_hwdata <= HWDATA; 601 | always @(posedge HCLK) check_hwdata(); 602 | 603 | 604 | /* 605 | * Check HWRITE 606 | */ 607 | always @(posedge HCLK) 608 | if (HREADY) prev_hwrite <= HWRITE; 609 | 610 | always @(posedge HCLK) dly_hwrite <= HWRITE; 611 | always @(posedge HCLK) check_hwrite(); 612 | 613 | 614 | /* 615 | * Check Slave response 616 | */ 617 | always @(posedge HCLK) dly_hready <= HREADY; 618 | always @(posedge HCLK) dly_hresp <= HRESP; 619 | always @(posedge HCLK) check_slave_response(); 620 | 621 | 622 | 623 | /* 624 | * Watchdog 625 | */ 626 | always @(posedge HCLK, negedge HRESETn) 627 | if (!HRESETn) watchdog_cnt <= WATCHDOG_TIMEOUT; 628 | else if ( HREADY ) watchdog_cnt <= WATCHDOG_TIMEOUT; 629 | else watchdog_cnt <= watchdog_cnt -1'h1; 630 | 631 | always @(posedge HCLK) 632 | if (WATCHDOG_TIMEOUT) 633 | if (~|watchdog_cnt) 634 | begin 635 | ahb_error ("Watchdog expired"); 636 | 637 | if (STOP_ON_WATCHDOG) $stop(); 638 | end 639 | endmodule : ahb_protocol_checker 640 | 641 | -------------------------------------------------------------------------------- /rtl/verilog/apb_checker.sv: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // ,------. ,--. ,--. // 3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. // 4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' // 5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. // 6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' // 7 | // `---' // 8 | // APB Bus Protocol Checker // 9 | // // 10 | ///////////////////////////////////////////////////////////////////// 11 | // // 12 | // Copyright (C) 2024 ROA Logic BV // 13 | // www.roalogic.com // 14 | // // 15 | // This source file may be used and distributed without // 16 | // restriction provided that this copyright statement is not // 17 | // removed from the file and that any derivative work contains // 18 | // the original copyright notice and the associated disclaimer. // 19 | // // 20 | // This soure file is free software; you can redistribute it // 21 | // and/or modify it under the terms of the GNU General Public // 22 | // License as published by the Free Software Foundation, // 23 | // either version 3 of the License, or (at your option) any later // 24 | // versions. The current text of the License can be found at: // 25 | // http://www.gnu.org/licenses/gpl.html // 26 | // // 27 | // This source file is distributed in the hope that it will be // 28 | // useful, but WITHOUT ANY WARRANTY; without even the implied // 29 | // warranty of MERCHANTABILITY or FITTNESS FOR A PARTICULAR // 30 | // PURPOSE. See the GNU General Public License for more details. // 31 | // // 32 | ///////////////////////////////////////////////////////////////////// 33 | 34 | 35 | /* 36 | * APB Revisions: CommonRef Status Changes 37 | *------------------------------------------------------------- 38 | * APB Specification Rev E APB obsolete 39 | * AMBA 2 APB Specification (Issue A) APB2 active 40 | * AMBA 3 APB Specification (ISSUE B) APB3 active PREADY 41 | * PSLVERR 42 | * AMBA APB Specification (ISSUE C) APB4 active PPROT 43 | * PSTRB 44 | * AMBA APB Specification (ISSUE D) APB5 active PWAKEUP 45 | * PAUSER 46 | * PWUSER 47 | * PRUSER 48 | * PBUSER 49 | * 50 | * The checker use the following defines to specify the ABP version 51 | * APB_VERSION_APB2 52 | * APB_VERSION_APB3 53 | * APB_VERSION_APB4 54 | * APB_VERSION_APB5 55 | */ 56 | 57 | 58 | /* 59 | * Relationship between message number and rule number 60 | * #Rule = message-number +1 61 | * example msgno=0 results in APB-1 62 | * msgno=1 results in APB-2 63 | */ 64 | 65 | //APB5 implies APB4 and below 66 | `ifdef APB_VERSION_APB5 67 | `ifndef APB_VERSION_APB4 68 | `define APB_VERSION_APB4 69 | `endif 70 | `endif 71 | 72 | 73 | //APB4 implies APB3 and below 74 | `ifdef APB_VERSION_APB4 75 | `ifndef APB_VERSION_APB3 76 | `define APB_VERSION_APB3 77 | `endif 78 | `endif 79 | 80 | 81 | module apb_checker 82 | import ahb3lite_pkg::*; 83 | #( 84 | parameter int ADDR_WIDTH = 32, //PADDR bus width 85 | parameter int DATA_WIDTH = 32, //PRDATA/PWDATA bus width 86 | 87 | parameter int USER_REQ_WIDTH = 0, 88 | parameter int USER_DATA_WIDTH = 0, 89 | parameter int USER_RESP_WIDTH = 0, 90 | 91 | parameter int CHECK_PSTRB = 1, //1: check PSTRB signal 92 | //0: do not check PSTRB signal 93 | parameter int CHECK_PPROT = 1, //1: check PPROT signal 94 | //0: do not check PPROT signal 95 | parameter int CHECK_PSLVERR = 1, //1: check PSLVERR signal 96 | //0: do not check PSLVERR signal 97 | parameter int WATCHDOG_TIMEOUT = 128 //number of cycles before watchdog triggers 98 | //WATCHDOG_TIMEOUT==0 disables watchdog 99 | ) 100 | ( 101 | //AHB Interface 102 | input PRESETn, 103 | input PCLK, 104 | 105 | input PSEL, 106 | input PENABLE, 107 | input [ADDR_WIDTH -1:0] PADDR, 108 | input PWRITE, 109 | `ifdef APB_VERSION_APB4 110 | input [(DATA_WIDTH+7)/8-1:0] PSTRB, 111 | input [ 2:0] PPROT, 112 | `endif 113 | input [DATA_WIDTH -1:0] PWDATA, 114 | input [DATA_WIDTH -1:0] PRDATA 115 | 116 | `ifdef APB_VERSION_APB3 117 | , 118 | input PREADY, 119 | input PSLVERR 120 | `endif 121 | 122 | `ifdef APB_VERSION_APB5 123 | , 124 | input PWAKEUP, 125 | input [USER_REQ_WIDTH -1:0] PAUSER, 126 | input [USER_DATA_WIDTH -1:0] PRUSER, 127 | PWUSER, 128 | input [USER_RESP_WIDTH -1:0] PBUSER 129 | `endif 130 | ); 131 | ////////////////////////////////////////////////////////////////// 132 | // 133 | // Variables 134 | // 135 | localparam PSTRB_SIZE = (DATA_WIDTH+7)/8; 136 | 137 | logic setup_phase, 138 | access_phase; 139 | logic dly_psel; 140 | logic dly_penable; 141 | logic [ADDR_WIDTH -1:0] dly_paddr; 142 | logic dly_pwrite; 143 | logic [PSTRB_SIZE -1:0] dly_pstrb; 144 | logic [ 2:0] dly_pprot; 145 | logic [DATA_WIDTH -1:0] dly_pwdata; 146 | logic dly_pready; 147 | logic dly_pwakeup; 148 | logic [USER_REQ_WIDTH -1:0] dly_pauser; 149 | logic [USER_DATA_WIDTH-1:0] dly_pwuser, 150 | dly_pruser; 151 | logic [USER_RESP_WIDTH-1:0] dly_pbuser; 152 | 153 | 154 | int watchdog_cnt = WATCHDOG_TIMEOUT; 155 | int errors = 0; 156 | int warnings = 0; 157 | int infos = 0; 158 | 159 | 160 | ////////////////////////////////////////////////////////////////// 161 | // 162 | // Message Structure 163 | // 164 | localparam int MESSAGE_COUNT = 43; 165 | 166 | typedef enum int {OFF =0, 167 | INFO =1, 168 | WARNING=2, 169 | ERROR =3, 170 | FATAL =4} severity_t; 171 | 172 | typedef struct { 173 | severity_t severity; 174 | string message; 175 | } message_t; 176 | 177 | message_t _msg[MESSAGE_COUNT]; 178 | 179 | 180 | //Default values 181 | initial 182 | begin 183 | _msg[ 0] = '{ERROR , "PSEL must remain high for the entire transfer"}; 184 | _msg[ 1] = '{ERROR , "PSEL undefined"}; 185 | _msg[ 2] = '{ERROR , "PENABLE must be low during Setup phase"}; 186 | _msg[ 3] = '{ERROR , "PENABLE must be high during Access phase"}; 187 | _msg[ 4] = '{ERROR , "PENABLE undefined"}; 188 | _msg[ 5] = '{ERROR , "PADDR must remain stable for the entire transfer"}; 189 | _msg[ 6] = '{ERROR , "PADDR versus PSTRB misaligned"}; 190 | _msg[38] = '{WARNING, "PADDR should be max 32 bits"}; 191 | _msg[ 7] = '{ERROR , "PADDR should be aligned to DATA_WIDTH"}; 192 | _msg[ 8] = '{ERROR , "PADDR undefined"}; 193 | _msg[ 9] = '{ERROR , "PWRITE must remain stable for the entire transfer"}; 194 | _msg[10] = '{ERROR , "PWRITE undefined"}; 195 | _msg[11] = '{WARNING, "PSTRB value non byte/word/dword/..."}; 196 | _msg[12] = '{ERROR , "PSTRB must remain stable for the entire transfer"}; 197 | _msg[13] = '{ERROR , "PSTRB undefined"}; 198 | _msg[37] = '{ERROR , "PSTRB must be low during read transfer"}; 199 | _msg[14] = '{ERROR , "PPROT must remain stable for the entire transfer"}; 200 | _msg[15] = '{ERROR , "PPROT undefined"}; 201 | _msg[16] = '{ERROR , "PWDATA must remain stable for the entire transfer"}; 202 | _msg[17] = '{WARNING, "PWDATA contains 'x'"}; 203 | _msg[18] = '{WARNING, "PWDATA contains 'x'"}; 204 | _msg[39] = '{WARNING, "PWDATA should be 8, 16, or 32 bits wide"}; 205 | _msg[19] = '{WARNING, "PRDATA contains 'x'"}; 206 | _msg[40] = '{WARNING, "PRDATA should be 8, 16, or 32 bits wide"}; 207 | _msg[20] = '{ERROR , "PREADY undefined during Access phase"}; 208 | _msg[21] = '{ERROR , "PSLVERR undefined"}; 209 | _msg[22] = '{FATAL , "Watchdog expired"}; 210 | _msg[23] = '{ERROR , "PWAKEUP must remain high until the end of the transfer"}; 211 | _msg[24] = '{WARNING, "PWAKEUP should be asserted at least one cycle before PSEL"}; 212 | _msg[25] = '{WARNING, "PWAKEUP raised without starting a transfer"}; 213 | _msg[26] = '{ERROR , "PWAKEUP undefined"}; 214 | _msg[27] = '{ERROR , "PAUSER must remain stable for the entire transfer"}; 215 | _msg[28] = '{ERROR , "PAUSER undefined"}; 216 | _msg[29] = '{WARNING, "PAUSER width should be max 128 bits"}; 217 | _msg[30] = '{ERROR , "PWUSER must remain stable for the entire write transfer"}; 218 | _msg[31] = '{ERROR , "PWUSER undefined"}; 219 | _msg[32] = '{WARNING, "PWUSER should be max DATA_WIDTH/2 bits"}; 220 | _msg[33] = '{WARNING, "PRUSER contains 'x'"}; 221 | _msg[34] = '{WARNING, "PRUSER should be max DATA_WIDTH/2 bits"}; 222 | _msg[35] = '{ERROR , "PBUSER undefined"}; 223 | _msg[36] = '{WARNING, "PBUSER should be max 16 bits"}; 224 | //_msg[37] see PSTRB 225 | //_msg[38] see PADDR 226 | //_msg[39] see PWDATA 227 | //_msg[40] see PRDATA 228 | _msg[41] = '{ERROR , "PRESETn undefined"}; 229 | _msg[42] = '{ERROR , "PCLK undefined"}; 230 | 231 | 232 | /* Initial width checks 233 | */ 234 | if ($bits(PADDR) > 32) 235 | message(38); 236 | 237 | if (($bits(PWDATA) != 8) && 238 | ($bits(PWDATA) != 16) && 239 | ($bits(PWDATA) != 32) ) 240 | message(39); 241 | 242 | if (($bits(PRDATA) != 8) && 243 | ($bits(PRDATA) != 16) && 244 | ($bits(PRDATA) != 32) ) 245 | message(40); 246 | 247 | `ifdef APB_VERSION_APB5 248 | if ($bits(PAUSER) > 128) 249 | message(29); 250 | 251 | if ($bits(PWUSER) > DATA_WIDTH/2) 252 | message(32); 253 | 254 | if ($bits(PRUSER) > DATA_WIDTH/2) 255 | message(34); 256 | 257 | if ($bits(PBUSER) > 16) 258 | message(36); 259 | `endif 260 | end 261 | 262 | 263 | //Display message 264 | task automatic message (input int msg_no); 265 | severity_t msg_severity; 266 | string msg; 267 | 268 | msg_severity = _msg[msg_no].severity; 269 | msg = $sformatf ("APB-%0d %s (%m): %s @%0t", msg_no +1, msg_severity.name(), _msg[msg_no].message, $time); 270 | 271 | case (msg_severity) 272 | OFF : ; 273 | INFO : $info (msg); 274 | WARNING: $warning (msg); 275 | ERROR : $error (msg); 276 | FATAL : begin $display("%0d", msg_no); $fatal (msg); end 277 | endcase 278 | 279 | case (msg_severity) 280 | OFF : ; 281 | INFO : infos++; 282 | WARNING: warnings++; 283 | ERROR : errors++; 284 | FATAL : ; 285 | endcase 286 | endtask : message 287 | 288 | 289 | //Set severity level of a message/check 290 | task automatic set_severity(int msg_no, severity_t severity); 291 | if (msg_no < MESSAGE_COUNT && msg_no >= 0) 292 | _msg[msg_no].severity = severity; 293 | endtask : set_severity 294 | 295 | //Get severity level of a message/check 296 | function automatic severity_t get_severity(int msg_no); 297 | if (msg_no < MESSAGE_COUNT && msg_no >= 0) 298 | return _msg[msg_no].severity; 299 | endfunction : get_severity 300 | 301 | 302 | ////////////////////////////////////////////////////////////////// 303 | // 304 | // Functions 305 | // 306 | 307 | //Return selected APB_VERSION string 308 | function string apb_version; 309 | `ifdef APB_VERSION_APB5 310 | return "ABP5"; 311 | `elsif APB_VERSION_APB4 312 | return "APB4"; 313 | `elsif APB_VERSION_APB3 314 | return "APB3"; 315 | `else 316 | return "APB2"; 317 | `endif 318 | endfunction : apb_version 319 | 320 | 321 | //Check if PSTRB has a 'logical' structure. Meaning: 322 | //1 PSTRB for byte access and in the form of 'h8, 'h4, 'h2, 'h1 323 | //2 PSTRB's for hword access and in the form of 'hc0, 'hc0, 'h0c, 'h03 324 | //4 PSTRB's for word access and in the form of 'hf000, 'h0f00, 'h00f0, 'h000f 325 | //etc 326 | function pstrb_valid( 327 | input [PSTRB_SIZE-1:0] pstrb 328 | ); 329 | logic [PSTRB_SIZE-1:0] mask; 330 | 331 | pstrb_valid = 0; 332 | 333 | //create all possible valid/logic PSTRB combinations and check against them 334 | for (int size =0; size <= $clog2(PSTRB_SIZE) ; size++ ) 335 | for (int offset=0; offset < PSTRB_SIZE/(2**size); offset++) 336 | begin 337 | mask = ((PSTRB_SIZE'(1) << (PSTRB_SIZE'(1) << size)) -1'h1) << (offset << size); 338 | pstrb_valid |= (pstrb & mask) == pstrb; 339 | end 340 | endfunction : pstrb_valid 341 | 342 | 343 | //Check if PSTRB is aligned with PADDR (or vice versa) 344 | function pstrb_misaligned( 345 | input [ADDR_WIDTH-1:0] paddr, 346 | input [PSTRB_SIZE-1:0] pstrb 347 | ); 348 | int tr_size; 349 | logic [PSTRB_SIZE-1:0] mask; 350 | logic [ADDR_WIDTH-1:0] addr_mask, 351 | masked_addr; 352 | 353 | tr_size = -1; 354 | 355 | //Determine the size of the transaction based on PSTRB value 356 | //0 = byte ( 8bits) 357 | //1 = hword (16bits) 358 | //2 = word (32bits) 359 | //etc 360 | for (int size =0; size <= $clog2(PSTRB_SIZE) ; size++ ) 361 | for (int offset=0; offset < PSTRB_SIZE/(2**size); offset++) 362 | begin 363 | mask = ((PSTRB_SIZE'(1) << (PSTRB_SIZE'(1) << size)) -1'h1) << (offset << size); 364 | if (pstrb == mask) 365 | begin 366 | tr_size = size; 367 | break; 368 | end 369 | end 370 | 371 | addr_mask = {ADDR_WIDTH{1'b1}} << tr_size; 372 | masked_addr = paddr & ~addr_mask; 373 | 374 | pstrb_misaligned = |masked_addr; 375 | endfunction : pstrb_misaligned 376 | 377 | 378 | 379 | ////////////////////////////////////////////////////////////////// 380 | // 381 | // Welcome/Goodbye Tasks 382 | // 383 | task welcome_msg(); 384 | $display("\n\n"); 385 | $display ("------------------------------------------------------------"); 386 | $display (" ,------. ,--. ,--. "); 387 | $display (" | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. "); 388 | $display (" | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' "); 389 | $display (" | |\\ \\ ' '-' '\\ '-' | | '--.' '-' ' '-' || |\\ `--. "); 390 | $display (" `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' "); 391 | $display ("- APB Protocol Checker ------------------ `---' ----------"); 392 | $display ("- Instance: %m"); 393 | $display ("- APB Version: %s", apb_version); 394 | $display ("------------------------------------------------------------"); 395 | $display ("\n"); 396 | endtask 397 | 398 | 399 | task goodbye_msg(); 400 | $display("\n\n"); 401 | $display ("------------------------------------------------------------"); 402 | $display (" ,------. ,--. ,--. "); 403 | $display (" | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. "); 404 | $display (" | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' "); 405 | $display (" | |\\ \\ ' '-' '\\ '-' | | '--.' '-' ' '-' || |\\ `--. "); 406 | $display (" `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' "); 407 | $display ("- APB Protocol Checker ------------------ `---' ----------"); 408 | $display ("- Instance: %m"); 409 | $display ("------------------------------------------------------------"); 410 | $display ("- Info : %0d", infos); 411 | $display ("- Warnings: %0d", warnings); 412 | $display ("- Errors : %0d", errors); 413 | $display ("------------------------------------------------------------"); 414 | endtask 415 | 416 | initial welcome_msg(); 417 | 418 | 419 | ////////////////////////////////////////////////////////////////// 420 | // 421 | // Tasks / Checks 422 | // 423 | 424 | /* 425 | * Check PRESETn 426 | */ 427 | task check_presetn; 428 | //PRESETn must not be undefined 429 | if (PRESETn === 1'bx || PRESETn === 1'bz) 430 | message(41); 431 | endtask : check_presetn 432 | 433 | 434 | /* 435 | * Check PCLK 436 | */ 437 | task check_pclk; 438 | //PCLK must not be undefined 439 | if (PRESETn) 440 | if (PCLK === 1'bx || PCLK === 1'bz) 441 | message(42); 442 | endtask : check_pclk 443 | 444 | 445 | /* 446 | * Check PSEL 447 | */ 448 | task check_psel; 449 | //PSEL can only go low if the current transfer ended 450 | if (!PSEL && dly_psel) 451 | if (!dly_pready) 452 | message(0); 453 | 454 | //PSEL must not be undefined 455 | if (PSEL === 1'bx || PSEL === 1'bz) 456 | message(1); 457 | endtask : check_psel 458 | 459 | 460 | /* 461 | * Check PENABLE 462 | */ 463 | task check_penable; 464 | //PENABLE must be low during Setup phase 465 | if (setup_phase) 466 | if (PENABLE) 467 | message(2); 468 | 469 | //PENABLE must be high during Access phase 470 | if (access_phase) 471 | if (!PENABLE) 472 | message(3); 473 | 474 | //PENABLE must not be undefined during transfer 475 | if (PSEL && (PENABLE === 1'bx || PENABLE == 1'bz)) 476 | message(4); 477 | endtask : check_penable 478 | 479 | 480 | /* 481 | * Check PADDR 482 | */ 483 | task check_paddr; 484 | logic [ADDR_WIDTH-1:0] addr_mask, masked_addr; 485 | 486 | //PADDR must remain stable during the entire transfer 487 | if (!dly_pready && PADDR !== dly_paddr) 488 | message(5); 489 | 490 | //PADDR must align with PSTRB 491 | `ifdef APB_VERSION_APB4 492 | if (PWRITE) 493 | begin 494 | if (pstrb_misaligned(PADDR, PSTRB)) 495 | message(6); 496 | end 497 | `endif 498 | 499 | //PADDR should be aligned to DATA_WIDTH 500 | addr_mask = {ADDR_WIDTH{1'b1}} << $clog2(PSTRB_SIZE); 501 | masked_addr = PADDR & ~addr_mask; 502 | if (|masked_addr) 503 | message(7); 504 | 505 | //PADDR may not be undefined during transfer 506 | if (^PADDR === 1'bx) 507 | message(8); 508 | endtask : check_paddr 509 | 510 | 511 | /* 512 | * Check PWRITE 513 | */ 514 | task check_pwrite; 515 | //PWRITE must remain stable during the entire transfer 516 | if (!dly_pready && PWRITE !== dly_pwrite) 517 | message(9); 518 | 519 | //PWRITE may not be undefined during transfer 520 | if (PWRITE === 1'bx || PWRITE === 1'bz) 521 | message(10); 522 | endtask : check_pwrite 523 | 524 | 525 | /* 526 | * Check PSTRB 527 | */ 528 | `ifdef APB_VERSION_APB4 529 | task check_pstrb; 530 | //PSTRB valid? 531 | if (|PSTRB) 532 | if (~pstrb_valid(PSTRB)) 533 | message(11); 534 | 535 | //PSTRB must remain stable during entire transfer 536 | if (!dly_pready && PSTRB !== dly_pstrb) 537 | message(12); 538 | 539 | //PSTRB must be low during read transfer 540 | if (!PWRITE && |PSTRB) 541 | message(37); 542 | 543 | //PSTRB may not be undefined during transfer 544 | if (PWRITE && ^PSTRB === 1'bx) 545 | message(13); 546 | endtask : check_pstrb 547 | `endif 548 | 549 | 550 | /* 551 | * Check PPROT 552 | */ 553 | `ifdef APB_VERSION_APB4 554 | task check_pprot; 555 | //PPROT must remain stable during entire transfer 556 | if (!dly_pready && PPROT !== dly_pprot) 557 | message(14); 558 | 559 | //PPROT may not be undefined during transfer 560 | if (^PPROT === 1'bx) 561 | message(15); 562 | endtask : check_pprot 563 | `endif 564 | 565 | 566 | /* 567 | * Check PWDATA 568 | */ 569 | task check_pwdata; 570 | logic is_x; 571 | 572 | //PWDATA must remain stable during entire transfer 573 | if (!dly_pready && PWDATA !== dly_pwdata) 574 | message(16); 575 | 576 | //PWDATA undefined? 577 | `ifdef APB_VERSION_APB4 578 | if (PWRITE) 579 | begin 580 | is_x = 1'b0; 581 | 582 | foreach (PSTRB[i]) 583 | is_x |= (^PWDATA[i*8 +: 8] & PSTRB[i]) === 1'bx; 584 | 585 | if (is_x) 586 | message(17); 587 | end 588 | `else 589 | if (PWRITE && ^PWDATA === 1'bx) 590 | message(18); 591 | `endif 592 | endtask : check_pwdata 593 | 594 | 595 | /* 596 | * Check PRDATA 597 | */ 598 | task check_prdata; 599 | //PRDATA undefined when transfer completes? 600 | `ifdef APB_VERSION_APB3 601 | if (PENABLE && PREADY && !PWRITE) 602 | `else 603 | if (PENABLE && !PWRITE) 604 | `endif 605 | if (^PRDATA === 1'bx) 606 | message(19); 607 | endtask : check_prdata 608 | 609 | 610 | /* 611 | * Check PREADY 612 | */ 613 | `ifdef APB_VERSION_APB3 614 | task check_pready; 615 | //PREADY may not contain 'x' when PENABLE is high 616 | if (PENABLE && (PREADY === 1'bx || PREADY === 1'bz)) 617 | message(20); 618 | endtask : check_pready 619 | `endif 620 | 621 | 622 | /* 623 | * Check PSLVERR 624 | */ 625 | `ifdef APB_VERSION_APB3 626 | task check_pslverr; 627 | //PSLVERR may not be undefined when transfer completes 628 | if (PENABLE && PREADY) 629 | if (PSLVERR === 1'bx || PSLVERR === 1'bz) 630 | message(21); 631 | endtask : check_pslverr 632 | `endif 633 | 634 | 635 | /* 636 | * Check PWAKEUP 637 | */ 638 | `ifdef APB_VERSION_APB5 639 | task check_pwakeup; 640 | //PWAKEUP must remain asserted until PREADY asserted if PSEL 641 | // and PWAKEUP are high in the same cycle 642 | if (!dly_pready && dly_psel && dly_pwakeup && !PWAKEUP) 643 | message(23); 644 | 645 | //Recommendation: assert PWAKEUP 1 cycle before PSEL 646 | if (PSEL && PWAKEUP && !dly_pwakeup) 647 | message(24); 648 | 649 | //It is not recommended to assert, then deassert PWAKEUP without 650 | // starting a transfer 651 | if (!PWAKEUP && dly_pwakeup && !PSEL && !dly_psel) 652 | message(25); 653 | 654 | //PWAKEUP should not be undefined ever 655 | if (PWAKEUP === 1'bx || PWAKEUP === 1'bz) 656 | message(26); 657 | endtask : check_pready 658 | `endif 659 | 660 | 661 | /* 662 | * Check PAUSER 663 | */ 664 | `ifdef APB_VERSION_APB5 665 | task check_pauser; 666 | //PAUSER must remain valid for the entire transfer 667 | if (!dly_pready && PAUSER != dly_pauser) 668 | message(27); 669 | 670 | //PAUSER must be valid when PSEL is asserted 671 | if (PAUSER === 1'bx || PAUSER === 1'bz) 672 | message(28); 673 | endtask : check_pauser 674 | `endif 675 | 676 | 677 | /* 678 | * Check PWUSER 679 | */ 680 | `ifdef APB_VERSION_APB5 681 | task check_pwuser; 682 | //PAUSER must remain valid for the entire transfer 683 | if (!dly_pready && PWUSER != dly_pwuser) 684 | message(30); 685 | 686 | //PAUSER must be valid when PSEL and PWRITE are asserted 687 | if (PWRITE && (PWUSER === 1'bx || PWUSER === 1'bz)) 688 | message(31); 689 | endtask : check_pwuser 690 | `endif 691 | 692 | 693 | /* 694 | * Check PRUSER 695 | */ 696 | `ifdef APB_VERSION_APB5 697 | task check_pruser; 698 | //PRUSER undefined when transfer completes? 699 | if (PENABLE && PREADY && !PWRITE) 700 | if (^PRUSER === 1'bx) 701 | message(33); 702 | endtask : check_pruser 703 | `endif 704 | 705 | 706 | /* 707 | * Check PBUSER 708 | */ 709 | `ifdef APB_VERSION_APB5 710 | task check_pbuser; 711 | //PBUSER undefined when transfer completes? 712 | if (PENABLE && PREADY) 713 | if (PBUSER === 1'bx || PBUSER === 1'bz) 714 | message(35); 715 | endtask : check_pbuser 716 | `endif 717 | 718 | 719 | 720 | ////////////////////////////////////////////////////////////////// 721 | // 722 | // Module Body 723 | // 724 | 725 | /* 726 | * Phase 727 | */ 728 | assign setup_phase = (PSEL & !dly_psel ) | 729 | (PSEL & dly_penable & dly_pready); 730 | 731 | initial access_phase = 1'b0; 732 | 733 | always @(posedge PCLK, negedge PRESETn) 734 | if (!PRESETn ) access_phase <= 1'b0; 735 | else if ( setup_phase) access_phase <= 1'b1; 736 | `ifdef APB_VERSION_APB3 737 | else if ( PREADY ) access_phase <= 1'b0; 738 | `else 739 | else access_phase <= 1'b0; 740 | `endif 741 | 742 | 743 | /* 744 | * Check PRESETn 745 | */ 746 | initial check_presetn(); 747 | always @(PRESETn) check_presetn(); 748 | 749 | 750 | /* 751 | * Check PCLK 752 | */ 753 | initial check_pclk(); 754 | always @(PCLK) check_pclk(); 755 | 756 | 757 | /* 758 | * Check PSEL 759 | */ 760 | initial dly_psel = 0; 761 | 762 | always @(posedge PCLK, negedge PRESETn) 763 | if (!PRESETn) dly_psel <= 1'b0; 764 | else dly_psel <= PSEL; 765 | 766 | always @(posedge PCLK) check_psel(); 767 | 768 | 769 | /* 770 | * Check PENABLE 771 | */ 772 | always @(posedge PCLK) dly_penable <= PENABLE; 773 | always @(posedge PCLK) check_penable(); 774 | 775 | 776 | /* 777 | * Check PADDR 778 | */ 779 | always @(posedge PCLK) dly_paddr <= PADDR; 780 | always @(posedge PCLK) if (PSEL) check_paddr(); 781 | 782 | 783 | /* 784 | * Check PWRITE 785 | */ 786 | always @(posedge PCLK) dly_pwrite <= PWRITE; 787 | always @(posedge PCLK) if (PSEL) check_pwrite(); 788 | 789 | 790 | /* 791 | * Check PSTRB 792 | */ 793 | `ifdef APB_VERSION_APB4 794 | always @(posedge PCLK) if (CHECK_PSTRB) dly_pstrb <= PSTRB; 795 | always @(posedge PCLK) if (CHECK_PSTRB) if (PSEL) check_pstrb(); 796 | `endif 797 | 798 | 799 | /* 800 | * Check PPROT 801 | */ 802 | `ifdef APB_VERSION_APB4 803 | always @(posedge PCLK) if (CHECK_PPROT) dly_pprot <= PPROT; 804 | always @(posedge PCLK) if (CHECK_PPROT) if (PSEL) check_pprot(); 805 | `endif 806 | 807 | 808 | /* 809 | * Check PWDATA 810 | */ 811 | always @(posedge PCLK) dly_pwdata <= PWDATA; 812 | always @(posedge PCLK) if (PSEL) check_pwdata(); 813 | 814 | 815 | /* 816 | * Check PRDATA 817 | */ 818 | always @(posedge PCLK) if (PSEL) check_prdata(); 819 | 820 | 821 | /* 822 | * Check PREADY 823 | */ 824 | `ifdef APB_VERSION_APB3 825 | always @(posedge PCLK) dly_pready <= PREADY; 826 | always @(posedge PCLK) if (PSEL) check_pready(); 827 | `else 828 | assign dly_ready = 1'b1; 829 | `endif 830 | 831 | 832 | /* 833 | * Check PSLVERR 834 | */ 835 | `ifdef APB_VERSION_APB3 836 | always @(posedge PCLK) if (CHECK_PSLVERR) if (PSEL) check_pslverr(); 837 | `endif 838 | 839 | 840 | /* 841 | * Check PWAKEUP 842 | */ 843 | `ifdef APB_VERSION_APB5 844 | always @(posedge PCLK) dly_pwakeup <= PWAKEUP; 845 | always @(posedge PCLK) if (PSEL) check_pwakeup(); 846 | `endif 847 | 848 | 849 | /* 850 | * Check PAUSER 851 | */ 852 | `ifdef APB_VERSION_APB5 853 | always @(posedge PCLK) if (USER_REQ_WIDTH > 0) dly_pauser <= PAUSER; 854 | always @(posedge PCLK) if (USER_REQ_WIDTH > 0) check_pauser(); 855 | `endif 856 | 857 | 858 | /* 859 | * Check PWUSER 860 | */ 861 | `ifdef APB_VERSION_APB5 862 | always @(posedge PCLK) if (USER_DATA_WIDTH > 0) dly_pwuser <= PWUSER; 863 | always @(posedge PCLK) if (USER_DATA_WIDTH > 0) if (PSEL) check_pwuser(); 864 | `endif 865 | 866 | 867 | /* 868 | * Check PRUSER 869 | */ 870 | `ifdef APB_VERSION_APB5 871 | always @(posedge PCLK) if (USER_DATA_WIDTH > 0) dly_pruser <= PRUSER; 872 | always @(posedge PCLK) if (USER_DATA_WIDTH > 0) if (PSEL) check_pruser(); 873 | `endif 874 | 875 | 876 | /* 877 | * Check PBUSER 878 | */ 879 | `ifdef APB_VERSION_APB5 880 | always @(posedge PCLK) if (USER_RESP_WIDTH > 0) dly_pbuser <= PBUSER; 881 | always @(posedge PCLK) if (USER_RESP_WIDTH > 0) if (PSEL) check_pbuser(); 882 | `endif 883 | 884 | 885 | 886 | /* 887 | * Watchdog 888 | */ 889 | always @(posedge PCLK, negedge PRESETn) 890 | if (!PRESETn ) watchdog_cnt <= WATCHDOG_TIMEOUT; 891 | else if (!PSEL ) watchdog_cnt <= WATCHDOG_TIMEOUT; 892 | `ifdef APB_VERSION_APB3 893 | else if ( PENABLE && PREADY ) watchdog_cnt <= WATCHDOG_TIMEOUT; 894 | `else 895 | else if ( PENABLE ) watchdog_cnt <= WATCHDOG_TIMEOUT; 896 | `endif 897 | else watchdog_cnt <= watchdog_cnt -1'h1; 898 | 899 | 900 | always @(posedge PCLK) 901 | if (WATCHDOG_TIMEOUT > 0) 902 | if (~|watchdog_cnt) 903 | message(22); 904 | endmodule : apb_checker 905 | 906 | -------------------------------------------------------------------------------- /docs/tex/apb_checker/rules.tex: -------------------------------------------------------------------------------- 1 | \chapter{Rules} 2 | 3 | \section{Introduction} 4 | 5 | This section describes all the rules in numerical order. Waveform examples showing how a rule is triggered are provided for each rule. Only the relevant signals are shown in each waveform. The failing conditions are shown in \textcolor{red}{red}. Also the rule trigger is shown as a pseudo-signal in the waveform. 6 | 7 | For reference, shown below is a waveform with examples of APB transfers with a 32bit data bus. The waveform shows how the core is brought out of sleep after the initial reset, followed by a read from address A with a single wait state, and a single byte write to address B with no wait states. 8 | The waveform also shows the Idle, Setup, and Access phases of the APB transfer. 9 | 10 | \begin{figure}[h] 11 | \begin{tikztimingtable}[% 12 | timing/dslope=0.1, 13 | timing/.style={x=5ex,y=2ex}, 14 | x=5ex, 15 | timing/rowdist=3ex, 16 | timing/name/.style={font=\sffamily\scriptsize} 17 | ] 18 | \busref{PRESETn} & 1L 1H {[dotted] 0.5H}\\ 19 | \busref{PCLK} & 19{c}\\ 20 | \busref{PSEL} & 0.5U 1U 2L 3H 2H 1L\\ 21 | \busref{PENABLE} & 0.5U 1U 3L 2H 1L 1H 1L\\ 22 | \busref{PADDR} & 0.5U 3U 3D{A} 2D{B} 1U\\ 23 | \busref{PWRITE} & 0.5U 3U 3L 2H 1U\\ 24 | \busref[3:0]{PSTRB} & 0.5U 3U 3D{0x0} 2D{0x1} 1U\\ 25 | \busref[31:0]{PWDATA} & 0.5U 3U 3U 2D{DB} 1U\\ 26 | \busref[31:0]{PRDATA} & 0.5U 5U D{DA} 2U 1U\\ 27 | \busref{PREADY} & 0.5U 4U 1L 1H 1U 1H 1U\\ 28 | \busref{PSLVERR} & 0.5U 4U 2L 2L 1U\\ 29 | \busref{PWAKEUP} & 0.5U 1U 1L 1H {[dotted] 0.5H}\\ 30 | \busref{PAUSER} & 0.5U 3U 3D{} 2D 1U\\ 31 | \busref{PRUSER} & 0.5U 3U 3D{} 2D 1U\\ 32 | \busref{PWUSER} & 0.5U 3U 3D{} 2D 1U\\ 33 | \busref{PBUSER} & 0.5U 3U 3D{} 2D 1U\\ 34 | \busref{ABP Phase} & 3.5D{Idle} 1D{Setup} 2D{Access} 1D{Setup} 1D{Access} 1D{Idle}\\ 35 | \extracode 36 | \begin{pgfonlayer}{background} 37 | \begin{scope}[semitransparent ,semithick] 38 | \vertlines[darkgray,dotted]{0.5,1.5,...,9.0} 39 | \end{scope} 40 | \end{pgfonlayer} 41 | \end{tikztimingtable} 42 | \caption{APB Transfer Examples}\label{fig:APB-Transfer-Example} 43 | \end{figure} 44 | 45 | \pagebreak 46 | 47 | 48 | 49 | \section{Rules} 50 | 51 | \subsection{PSEL Must remain high for the entire transfer}\label{subsec:APB-1} 52 | 53 | \begin{description} 54 | \setlength\itemsep{-0.45em} 55 | \item Message: APB-1 56 | \item Severity: ERROR 57 | \item Description: The PSEL signal must remain asserted (`1') during the entire transfer. 58 | \item APB Version: All 59 | \end{description} 60 | 61 | \begin{figure}[h] 62 | \begin{tikztimingtable}[% 63 | timing/dslope=0.1, 64 | timing/.style={x=5ex,y=2ex}, 65 | x=5ex, 66 | timing/rowdist=3ex, 67 | timing/name/.style={font=\sffamily\scriptsize} 68 | ] 69 | \busref{PCLK} & 7{c}\\ 70 | \busref{PSEL} & 0.5L 1H {[red] 1L} 1L\\ 71 | \busref{PENABLE} & 0.5U 1L 1H 1U\\ 72 | \busref{APB-1} & 1.5L 1H 1L\\ 73 | \extracode 74 | \begin{pgfonlayer}{background} 75 | \begin{scope}[semitransparent ,semithick] 76 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 77 | \end{scope} 78 | \end{pgfonlayer} 79 | \end{tikztimingtable} 80 | \caption{APB-1 Example}\label{fig:APB-1} 81 | \end{figure} 82 | 83 | 84 | 85 | \subsection{PSEL Undefined}\label{subsec:APB-2} 86 | 87 | \begin{description} 88 | \setlength\itemsep{-0.45em} 89 | \item Message: APB-2 90 | \item Severity: ERROR 91 | \item Description: The PSEL signal may never be undefined (`x') or (`z'). 92 | \item APB Version: All 93 | \end{description} 94 | 95 | \begin{figure}[h] 96 | \begin{tikztimingtable}[% 97 | timing/dslope=0.1, 98 | timing/.style={x=5ex,y=2ex}, 99 | x=5ex, 100 | timing/rowdist=3ex, 101 | timing/name/.style={font=\sffamily\scriptsize} 102 | ] 103 | \busref{PRESETn} & 3.5H\\ 104 | \busref{PCLK} & 7{c} \\ 105 | \busref{PSEL} & 0.5L {[red] 1X} {[red] 1U} 1H\\ 106 | \busref{APB-2} & 0.5L 2H 1L\\ 107 | \extracode 108 | \begin{pgfonlayer}{background} 109 | \begin{scope}[semitransparent ,semithick] 110 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 111 | \end{scope} 112 | \end{pgfonlayer} 113 | \end{tikztimingtable} 114 | \caption{APB-2 Example}\label{fig:APB-2} 115 | \end{figure} 116 | 117 | 118 | 119 | \subsection{PENABLE must be low during Setup Phase}\label{subsec:APB-3} 120 | 121 | \begin{description} 122 | \setlength\itemsep{-0.45em} 123 | \item Message: APB-3 124 | \item Severity: ERROR 125 | \item Description: The PENABLE signal must be low (`0') during the first cycle (the setup phase) of a transfer. 126 | \item APB Version: All 127 | \end{description} 128 | 129 | \begin{figure}[h] 130 | \begin{tikztimingtable}[% 131 | timing/dslope=0.1, 132 | timing/.style={x=5ex,y=2ex}, 133 | x=5ex, 134 | timing/rowdist=3ex, 135 | timing/name/.style={font=\sffamily\scriptsize} 136 | ] 137 | \busref{PCLK} & 7{c} \\ 138 | \busref{PSEL} & 0.5L 2H 1L\\ 139 | \busref{PENABLE} & 0.5L {[red] 1H} 1H 1L\\ 140 | \busref{APB-3} & 0.5L 1H 1L 1L\\ 141 | \extracode 142 | \begin{pgfonlayer}{background} 143 | \begin{scope}[semitransparent ,semithick] 144 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 145 | \end{scope} 146 | \end{pgfonlayer} 147 | \end{tikztimingtable} 148 | \caption{APB-3 Example}\label{fig:APB-3} 149 | \end{figure} 150 | 151 | 152 | \subsection{PENABLE must be high during Access Phase}\label{subsec:APB-4} 153 | 154 | \begin{description} 155 | \setlength\itemsep{-0.45em} 156 | \item Message: APB-4 157 | \item Severity: ERROR 158 | \item Description: The PENABLE signal must be high (`1') during the second and consecutive cycles (the access phases) of a transfer. 159 | \item APB Version: All 160 | \end{description} 161 | 162 | \begin{figure}[h] 163 | \begin{tikztimingtable}[% 164 | timing/dslope=0.1, 165 | timing/.style={x=5ex,y=2ex}, 166 | x=5ex, 167 | timing/rowdist=3ex, 168 | timing/name/.style={font=\sffamily\scriptsize} 169 | ] 170 | \busref{PCLK} & 7{c} \\ 171 | \busref{PSEL} & 0.5L 2H 1L\\ 172 | \busref{PENABLE} & 0.5L 1L {[red] 1L} 1L\\ 173 | \busref{APB-4} & 0.5L 1L 1H 1L\\ 174 | \extracode 175 | \begin{pgfonlayer}{background} 176 | \begin{scope}[semitransparent ,semithick] 177 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 178 | \end{scope} 179 | \end{pgfonlayer} 180 | \end{tikztimingtable} 181 | \caption{APB-4 Example}\label{fig:APB-4} 182 | \end{figure} 183 | 184 | 185 | 186 | \subsection{PENABLE undefined}\label{subsec:APB-5} 187 | 188 | \begin{description} 189 | \setlength\itemsep{-0.45em} 190 | \item Message: APB-5 191 | \item Severity: ERROR 192 | \item Description: The PENABLED signal may never be undefined (`x') or (`z') during a transfer. 193 | \item APB Version: All 194 | \end{description} 195 | 196 | \begin{figure}[h] 197 | \begin{tikztimingtable}[% 198 | timing/dslope=0.1, 199 | timing/.style={x=5ex,y=2ex}, 200 | x=5ex, 201 | timing/rowdist=3ex, 202 | timing/name/.style={font=\sffamily\scriptsize} 203 | ] 204 | \busref{PCLK} & 7{c} \\ 205 | \busref{PSEL} & 0.5L 2H 1L\\ 206 | \busref{PENABLE} & 0.5L {[red] 2X} 1L\\ 207 | \busref{APB-5} & 0.5L 2H 1L\\ 208 | \extracode 209 | \begin{pgfonlayer}{background} 210 | \begin{scope}[semitransparent ,semithick] 211 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 212 | \end{scope} 213 | \end{pgfonlayer} 214 | \end{tikztimingtable} 215 | \caption{APB-5 Example}\label{fig:APB-5} 216 | \end{figure} 217 | 218 | 219 | 220 | \subsection{PADDR must remain stable for the entire transfer}\label{subsec:APB-6} 221 | 222 | \begin{description} 223 | \setlength\itemsep{-0.45em} 224 | \item Message: APB-6 225 | \item Severity: ERROR 226 | \item Description: The PADDR signal may not change during a transfer. 227 | \item APB Version: All 228 | \end{description} 229 | 230 | \begin{figure}[h] 231 | \begin{tikztimingtable}[% 232 | timing/dslope=0.1, 233 | timing/.style={x=5ex,y=2ex}, 234 | x=5ex, 235 | timing/rowdist=3ex, 236 | timing/name/.style={font=\sffamily\scriptsize} 237 | ] 238 | \busref{PCLK} & 7{c} \\ 239 | \busref{PSEL} & 0.5L 2H 1L\\ 240 | \busref{PADDR} & 0.5U 1D{A} {[red] 1D{B}} 1U\\ 241 | \busref{APB-6} & 0.5L 1L 1H 1L\\ 242 | \extracode 243 | \begin{pgfonlayer}{background} 244 | \begin{scope}[semitransparent ,semithick] 245 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 246 | \end{scope} 247 | \end{pgfonlayer} 248 | \end{tikztimingtable} 249 | \caption{APB-6 Example}\label{fig:APB-6} 250 | \end{figure} 251 | 252 | 253 | 254 | \subsection{PADDR versus PSTRB misaligned}\label{subsec:APB-7} 255 | 256 | \begin{description} 257 | \setlength\itemsep{-0.45em} 258 | \item Message: APB-7 259 | \item Severity: ERROR 260 | \item Description: The PADDR signal value must be aligned with the transfer size indicated by the PSTRB signal value during a write transfer. 261 | \item APB Version: from APB4 262 | \end{description} 263 | 264 | \begin{figure}[h] 265 | \begin{tikztimingtable}[% 266 | timing/dslope=0.1, 267 | timing/.style={x=5ex,y=2ex}, 268 | x=5ex, 269 | timing/rowdist=3ex, 270 | timing/name/.style={font=\sffamily\scriptsize} 271 | ] 272 | \busref{PCLK} & 11{c} \\ 273 | \busref{PSEL} & 0.5L 2H 2H 1L\\ 274 | \busref[31:0]{PADDR} & 0.5U {[red] 2D{0x02} 2D{0x01}} 1U\\ 275 | \busref{PWRITE} & 0.5U 2H 2H 1L\\ 276 | \busref[3:0]{PSTRB} & 0.5U {[red] 2D{0xf} 2D{0x3}} 1U\\ 277 | \busref{APB-7} & 0.5L 2H 2H 1L\\ 278 | \extracode 279 | \begin{pgfonlayer}{background} 280 | \begin{scope}[semitransparent ,semithick] 281 | \vertlines[darkgray,dotted]{0.5,1.5,...,5.0} 282 | \end{scope} 283 | \end{pgfonlayer} 284 | \end{tikztimingtable} 285 | \caption{APB-7 Example}\label{fig:APB-7} 286 | \end{figure} 287 | 288 | 289 | 290 | \subsection{PADDR should be aligned to DATA\_WIDTH}\label{subsec:APB-8} 291 | 292 | \begin{description} 293 | \setlength\itemsep{-0.45em} 294 | \item Message: APB-8 295 | \item Severity: ERROR 296 | \item Description: The PADDR signal value must be aligned with the DATA\_WIDTH parameter value during a transfer. 297 | \item APB Version: All 298 | \end{description} 299 | 300 | \begin{figure}[h] 301 | \begin{tikztimingtable}[% 302 | timing/dslope=0.1, 303 | timing/.style={x=5ex,y=2ex}, 304 | x=5ex, 305 | timing/rowdist=3ex, 306 | timing/name/.style={font=\sffamily\scriptsize} 307 | ] 308 | \busref{PCLK} & 7{c} \\ 309 | \busref{PSEL} & 0.5L 2H 1L\\ 310 | \busref[31:0]{PADDR} & 0.5U {[red] 2D{0x01}} 1U\\ 311 | \busref[31:0]{PRDATA} & 0.5U 2D{} 1U\\ 312 | \busref{APB-8} & 0.5L 2H 1L\\ 313 | \extracode 314 | \begin{pgfonlayer}{background} 315 | \begin{scope}[semitransparent ,semithick] 316 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 317 | \end{scope} 318 | \end{pgfonlayer} 319 | \end{tikztimingtable} 320 | \caption{APB-8 Example}\label{fig:APB-8} 321 | \end{figure} 322 | 323 | 324 | 325 | \subsection{PADDR undefined}\label{subsec:APB-9} 326 | 327 | \begin{description} 328 | \setlength\itemsep{-0.45em} 329 | \item Message: APB-9 330 | \item Severity: ERROR 331 | \item Description: The PADDR signal may never be undefined (`x') or (`z') during a transfer. 332 | \item APB Version: All 333 | \end{description} 334 | 335 | \begin{figure}[h] 336 | \begin{tikztimingtable}[% 337 | timing/dslope=0.1, 338 | timing/.style={x=5ex,y=2ex}, 339 | x=5ex, 340 | timing/rowdist=3ex, 341 | timing/name/.style={font=\sffamily\scriptsize} 342 | ] 343 | \busref{PCLK} & 7{c} \\ 344 | \busref{PSEL} & 0.5L 2H 1L\\ 345 | \busref{PADDR} & 0.5U {[red] 2X} 1U\\ 346 | \busref{APB-9} & 0.5L 2H 1L\\ 347 | \extracode 348 | \begin{pgfonlayer}{background} 349 | \begin{scope}[semitransparent ,semithick] 350 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 351 | \end{scope} 352 | \end{pgfonlayer} 353 | \end{tikztimingtable} 354 | \caption{APB-9 Example}\label{fig:APB-9} 355 | \end{figure} 356 | 357 | 358 | 359 | \subsection{PWRITE must remain stable for the entire transfer}\label{subsec:APB-10} 360 | 361 | \begin{description} 362 | \setlength\itemsep{-0.45em} 363 | \item Message: APB-10 364 | \item Severity: ERROR 365 | \item Description: The PWRITE signal may not change during a transfer. 366 | \item APB Version: All 367 | \end{description} 368 | 369 | \begin{figure}[h] 370 | \begin{tikztimingtable}[% 371 | timing/dslope=0.1, 372 | timing/.style={x=5ex,y=2ex}, 373 | x=5ex, 374 | timing/rowdist=3ex, 375 | timing/name/.style={font=\sffamily\scriptsize} 376 | ] 377 | \busref{PCLK} & 7{c} \\ 378 | \busref{PSEL} & 0.5L 2H 1L\\ 379 | \busref{PWRITE} & 0.5U 1H {[red] 1L} 1U\\ 380 | \busref{APB-10} & 0.5L 1L 1H 1L\\ 381 | \extracode 382 | \begin{pgfonlayer}{background} 383 | \begin{scope}[semitransparent ,semithick] 384 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 385 | \end{scope} 386 | \end{pgfonlayer} 387 | \end{tikztimingtable} 388 | \caption{APB-10 Example}\label{fig:APB-10} 389 | \end{figure} 390 | 391 | 392 | 393 | \subsection{PWRITE undefined}\label{subsec:APB-11} 394 | 395 | \begin{description} 396 | \setlength\itemsep{-0.45em} 397 | \item Message: APB-11 398 | \item Severity: ERROR 399 | \item Description: The PWRITE signal may never be undefined (`x') or (`z') during a transfer. 400 | \item APB Version: All 401 | \end{description} 402 | 403 | \begin{figure}[h] 404 | \begin{tikztimingtable}[% 405 | timing/dslope=0.1, 406 | timing/.style={x=5ex,y=2ex}, 407 | x=5ex, 408 | timing/rowdist=3ex, 409 | timing/name/.style={font=\sffamily\scriptsize} 410 | ] 411 | \busref{PCLK} & 7{c} \\ 412 | \busref{PSEL} & 0.5L 2H 1L\\ 413 | \busref{PWRITE} & 0.5U {[red] 2X} 1U\\ 414 | \busref{APB-11} & 0.5L 2H 1L\\ 415 | \extracode 416 | \begin{pgfonlayer}{background} 417 | \begin{scope}[semitransparent ,semithick] 418 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 419 | \end{scope} 420 | \end{pgfonlayer} 421 | \end{tikztimingtable} 422 | \caption{APB-11 Example}\label{fig:APB-11} 423 | \end{figure} 424 | 425 | 426 | 427 | \subsection{PSTRB value non byte/word/dword/...}\label{subsec:APB-12} 428 | 429 | \begin{description} 430 | \setlength\itemsep{-0.45em} 431 | \item Message: APB-12 432 | \item Severity: WARNING 433 | \item Description: The PSTRB signal holds a strange value during a write transfer. 434 | \item APB Version: from APB4 435 | \end{description} 436 | 437 | \begin{figure}[h] 438 | \begin{tikztimingtable}[% 439 | timing/dslope=0.1, 440 | timing/.style={x=5ex,y=2ex}, 441 | x=5ex, 442 | timing/rowdist=3ex, 443 | timing/name/.style={font=\sffamily\scriptsize} 444 | ] 445 | \busref{PCLK} & 35{c} \\ 446 | \busref{PSEL} & 0.5L 16H 1L\\ 447 | \busref{PWRITE} & 0.5L 16H 1L\\ 448 | \busref[3:0]{PSTRB} & 0.5U {[red] 2D{0x5} 2D{0x6} 2D{0x7} 2D{0x9} 2D{0xA} 2D{0xB} 2D{0xD} 2D{0xE}} 1U\\ 449 | \busref{APB-12} & 0.5L 16H 1L\\ 450 | \extracode 451 | \begin{pgfonlayer}{background} 452 | \begin{scope}[semitransparent ,semithick] 453 | \vertlines[darkgray,dotted]{0.5,1.5,...,15.0} 454 | \end{scope} 455 | \end{pgfonlayer} 456 | \end{tikztimingtable} 457 | \caption{APB-12 Example}\label{fig:APB-12} 458 | \end{figure} 459 | 460 | \pagebreak 461 | 462 | 463 | 464 | \subsection{PSTRB must remain stable for the entire transfer}\label{subsec:APB-13} 465 | 466 | \begin{description} 467 | \setlength\itemsep{-0.45em} 468 | \item Message: APB-13 469 | \item Severity: ERROR 470 | \item Description: The PSTRB signal may not change during a transfer. 471 | \item APB Version: from APB4 472 | \end{description} 473 | 474 | \begin{figure}[h] 475 | \begin{tikztimingtable}[% 476 | timing/dslope=0.1, 477 | timing/.style={x=5ex,y=2ex}, 478 | x=5ex, 479 | timing/rowdist=3ex, 480 | timing/name/.style={font=\sffamily\scriptsize} 481 | ] 482 | \busref{PCLK} & 7{c} \\ 483 | \busref{PSEL} & 0.5L 2H 1L\\ 484 | \busref{PSTRB} & 0.5U 1D{A} {[red] 1D{B}} 1U\\ 485 | \busref{APB-13} & 0.5L 1L 1H 1L\\ 486 | \extracode 487 | \begin{pgfonlayer}{background} 488 | \begin{scope}[semitransparent ,semithick] 489 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 490 | \end{scope} 491 | \end{pgfonlayer} 492 | \end{tikztimingtable} 493 | \caption{APB-13 Example}\label{fig:APB-13} 494 | \end{figure} 495 | 496 | 497 | 498 | \subsection{PSTRB undefined}\label{subsec:APB-14} 499 | 500 | \begin{description} 501 | \setlength\itemsep{-0.45em} 502 | \item Message: APB-14 503 | \item Severity: ERROR 504 | \item Description: The PSTRB signal may never be undefined (`x') or (`z') during a transfer. 505 | \item APB Version: from APB4 506 | \end{description} 507 | 508 | \begin{figure}[h] 509 | \begin{tikztimingtable}[% 510 | timing/dslope=0.1, 511 | timing/.style={x=5ex,y=2ex}, 512 | x=5ex, 513 | timing/rowdist=3ex, 514 | timing/name/.style={font=\sffamily\scriptsize} 515 | ] 516 | \busref{PCLK} & 7{c} \\ 517 | \busref{PSEL} & 0.5L 2H 1L\\ 518 | \busref{PSTRB} & 0.5U {[red] 2X} 1U\\ 519 | \busref{APB-14} & 0.5L 2H 1L\\ 520 | \extracode 521 | \begin{pgfonlayer}{background} 522 | \begin{scope}[semitransparent ,semithick] 523 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 524 | \end{scope} 525 | \end{pgfonlayer} 526 | \end{tikztimingtable} 527 | \caption{APB-14 Example}\label{fig:APB-14} 528 | \end{figure} 529 | 530 | 531 | 532 | \subsection{PPROT must remain stable for the entire transfer}\label{subsec:APB-15} 533 | 534 | \begin{description} 535 | \setlength\itemsep{-0.45em} 536 | \item Message: APB-15 537 | \item Severity: ERROR 538 | \item Description: The PPROT signal may not change during a transfer. 539 | \item APB Version: from APB4 540 | \end{description} 541 | 542 | \begin{figure}[h] 543 | \begin{tikztimingtable}[% 544 | timing/dslope=0.1, 545 | timing/.style={x=5ex,y=2ex}, 546 | x=5ex, 547 | timing/rowdist=3ex, 548 | timing/name/.style={font=\sffamily\scriptsize} 549 | ] 550 | \busref{PCLK} & 7{c} \\ 551 | \busref{PSEL} & 0.5L 2H 1L\\ 552 | \busref[2:0]{PPROT} & 0.5U 1D{A} {[red] 1D{B}} 1U\\ 553 | \busref{APB-15} & 0.5L 1L 1H 1L\\ 554 | \extracode 555 | \begin{pgfonlayer}{background} 556 | \begin{scope}[semitransparent ,semithick] 557 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 558 | \end{scope} 559 | \end{pgfonlayer} 560 | \end{tikztimingtable} 561 | \caption{APB-15 Example}\label{fig:APB-15} 562 | \end{figure} 563 | 564 | \pagebreak 565 | 566 | 567 | 568 | \subsection{PPROT undefined}\label{subsec:APB-16} 569 | 570 | \begin{description} 571 | \setlength\itemsep{-0.45em} 572 | \item Message: APB-16 573 | \item Severity: ERROR 574 | \item Description: The PPROT signal may never be undefined (`x') or (`z') during a transfer. 575 | \item APB Version: from APB4 576 | \end{description} 577 | 578 | \begin{figure}[h] 579 | \begin{tikztimingtable}[% 580 | timing/dslope=0.1, 581 | timing/.style={x=5ex,y=2ex}, 582 | x=5ex, 583 | timing/rowdist=3ex, 584 | timing/name/.style={font=\sffamily\scriptsize} 585 | ] 586 | \busref{PCLK} & 7{c} \\ 587 | \busref{PSEL} & 0.5L 2H 1L\\ 588 | \busref[2:0]{PPROT} & 0.5U {[red] 2X} 1U\\ 589 | \busref{APB-16} & 0.5L 2H 1L\\ 590 | \extracode 591 | \begin{pgfonlayer}{background} 592 | \begin{scope}[semitransparent ,semithick] 593 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 594 | \end{scope} 595 | \end{pgfonlayer} 596 | \end{tikztimingtable} 597 | \caption{APB-16 Example}\label{fig:APB-16} 598 | \end{figure} 599 | 600 | 601 | 602 | \subsection{PWDATA must remain stable for the entire transfer}\label{subsec:APB-17} 603 | 604 | \begin{description} 605 | \setlength\itemsep{-0.45em} 606 | \item Message: APB-17 607 | \item Severity: ERROR 608 | \item Description: The PWDATA signal may not change during a write transfer. 609 | \item APB Version: All 610 | \end{description} 611 | 612 | \begin{figure}[h] 613 | \begin{tikztimingtable}[% 614 | timing/dslope=0.1, 615 | timing/.style={x=5ex,y=2ex}, 616 | x=5ex, 617 | timing/rowdist=3ex, 618 | timing/name/.style={font=\sffamily\scriptsize} 619 | ] 620 | \busref{PCLK} & 7{c} \\ 621 | \busref{PSEL} & 0.5L 2H 1L\\ 622 | \busref{PWRITE} & 0.5U 2H 1U\\ 623 | \busref{PWDATA} & 0.5U 1D{A} {[red] 1D{B}} 1U\\ 624 | \busref{APB-17} & 0.5L 1L 1H 1L\\ 625 | \extracode 626 | \begin{pgfonlayer}{background} 627 | \begin{scope}[semitransparent ,semithick] 628 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 629 | \end{scope} 630 | \end{pgfonlayer} 631 | \end{tikztimingtable} 632 | \caption{APB-17 Example}\label{fig:APB-17} 633 | \end{figure} 634 | 635 | 636 | 637 | \subsection{PWDATA contains 'x'}\label{subsec:APB-18} 638 | 639 | \begin{description} 640 | \setlength\itemsep{-0.45em} 641 | \item Message: APB-18 642 | \item Severity: WARNING 643 | \item Description: One or more bits of the PWDATA signal are undefined (`x') or (`z') during a write transfer. 644 | \item APB Version: APB2, APB3 645 | \end{description} 646 | 647 | \begin{figure}[h] 648 | \begin{tikztimingtable}[% 649 | timing/dslope=0.1, 650 | timing/.style={x=5ex,y=2ex}, 651 | x=5ex, 652 | timing/rowdist=3ex, 653 | timing/name/.style={font=\sffamily\scriptsize} 654 | ] 655 | \busref{PCLK} & 7{c} \\ 656 | \busref{PSEL} & 0.5L 2H 1L\\ 657 | \busref{PWRITE} & 0.5U 2H 1U\\ 658 | \busref{PWDATA} & 0.5U {[red] 2X} 1U\\ 659 | \busref{APB-18} & 0.5L 2H 1L\\ 660 | \extracode 661 | \begin{pgfonlayer}{background} 662 | \begin{scope}[semitransparent ,semithick] 663 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 664 | \end{scope} 665 | \end{pgfonlayer} 666 | \end{tikztimingtable} 667 | \caption{APB-18 Example}\label{fig:APB-18} 668 | \end{figure} 669 | 670 | 671 | 672 | \subsection{PWDATA contains 'x'}\label{subsec:APB-19} 673 | 674 | \begin{description} 675 | \setlength\itemsep{-0.45em} 676 | \item Message: APB-19 677 | \item Severity: WARNING 678 | \item Description: One or more bits of the PWDATA signal, in a byte not masked by PSTRB, are undefined (`x') or (`z') during a write transfer. 679 | \item APB Version: from APB4 680 | \end{description} 681 | 682 | \begin{figure}[h] 683 | \begin{tikztimingtable}[% 684 | timing/dslope=0.1, 685 | timing/.style={x=5ex,y=2ex}, 686 | x=5ex, 687 | timing/rowdist=3ex, 688 | timing/name/.style={font=\sffamily\scriptsize} 689 | ] 690 | \busref{PCLK} & 11{c} \\ 691 | \busref{PSEL} & 0.5L 2H 2H 1L\\ 692 | \busref{PWRITE} & 0.5U 2H 2H 1U\\ 693 | \busref[1:0]{PSTRB} & 0.5U 2D{0x1} {[red]2D{0x2}} 1U\\ 694 | \busref[15:0]{PWDATA} & 0.5U 2D{0xXXDC} {[red]2D{0xXXDC}} 1U\\ 695 | \busref{APB-19} & 0.5L 2L 2H 1L\\ 696 | \extracode 697 | \begin{pgfonlayer}{background} 698 | \begin{scope}[semitransparent ,semithick] 699 | \vertlines[darkgray,dotted]{0.5,1.5,...,5.0} 700 | \end{scope} 701 | \end{pgfonlayer} 702 | \end{tikztimingtable} 703 | \caption{APB-19 Example}\label{fig:APB-19} 704 | \end{figure} 705 | 706 | 707 | 708 | \subsection{PRDATA contains 'x'}\label{subsec:APB-20} 709 | 710 | \begin{description} 711 | \setlength\itemsep{-0.45em} 712 | \item Message: APB-20 713 | \item Severity: WARNING 714 | \item Description: One or more bits of the PRDATA signal are undefined (`x') or (`z') during a read transfer. 715 | \item APB Version: All 716 | \end{description} 717 | 718 | \begin{figure}[h] 719 | \begin{tikztimingtable}[% 720 | timing/dslope=0.1, 721 | timing/.style={x=5ex,y=2ex}, 722 | x=5ex, 723 | timing/rowdist=3ex, 724 | timing/name/.style={font=\sffamily\scriptsize} 725 | ] 726 | \busref{PCLK} & 7{c} \\ 727 | \busref{PSEL} & 0.5L 2H 1L\\ 728 | \busref{PENABLE} & 0.5U 1L 1H 1U\\ 729 | \busref{PWRITE} & 0.5U 2L 1U\\ 730 | \busref[15:0]{PRDATA} & 0.5U 1U {[red]1D{0xXEDC}} 1U\\ 731 | \busref{APB-20} & 0.5L 1L 1H 1L\\ 732 | \extracode 733 | \begin{pgfonlayer}{background} 734 | \begin{scope}[semitransparent ,semithick] 735 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 736 | \end{scope} 737 | \end{pgfonlayer} 738 | \end{tikztimingtable} 739 | \caption{APB-20 Example}\label{fig:APB-20} 740 | \end{figure} 741 | 742 | \pagebreak 743 | 744 | 745 | 746 | \subsection{PREADY undefined during Access phase}\label{subsec:APB-21} 747 | 748 | \begin{description} 749 | \setlength\itemsep{-0.45em} 750 | \item Message: APB-21 751 | \item Severity: ERROR 752 | \item Description: The PREADY signal is undefined (`x') or (`z') during the access phase of a transfer. 753 | \item APB Version: from APB3 754 | \end{description} 755 | 756 | \begin{figure}[h] 757 | \begin{tikztimingtable}[% 758 | timing/dslope=0.1, 759 | timing/.style={x=5ex,y=2ex}, 760 | x=5ex, 761 | timing/rowdist=3ex, 762 | timing/name/.style={font=\sffamily\scriptsize} 763 | ] 764 | \busref{PCLK} & 7{c} \\ 765 | \busref{PSEL} & 0.5L 2H 1L\\ 766 | \busref{PENABLE} & 0.5U 1L 1H 1U\\ 767 | \busref{PREADY} & 0.5U 1U {[red]1X} 1U\\ 768 | \busref{APB-21} & 0.5L 1L 1H 1L\\ 769 | \extracode 770 | \begin{pgfonlayer}{background} 771 | \begin{scope}[semitransparent ,semithick] 772 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 773 | \end{scope} 774 | \end{pgfonlayer} 775 | \end{tikztimingtable} 776 | \caption{APB-21 Example}\label{fig:APB-21} 777 | \end{figure} 778 | 779 | 780 | 781 | \subsection{PSLVERR undefined}\label{subsec:APB-22} 782 | 783 | \begin{description} 784 | \setlength\itemsep{-0.45em} 785 | \item Message: APB-22 786 | \item Severity: ERROR 787 | \item Description: The PSLVERR signal is undefined (`x') or (`z') during the final cycle of a transfer. 788 | \item APB Version: from APB3 789 | \end{description} 790 | 791 | \begin{figure}[h] 792 | \begin{tikztimingtable}[% 793 | timing/dslope=0.1, 794 | timing/.style={x=5ex,y=2ex}, 795 | x=5ex, 796 | timing/rowdist=3ex, 797 | timing/name/.style={font=\sffamily\scriptsize} 798 | ] 799 | \busref{PCLK} & 7{c} \\ 800 | \busref{PSEL} & 0.5L 2H 1L\\ 801 | \busref{PENABLE} & 0.5U 1L 1H 1U\\ 802 | \busref{PREADY} & 0.5U 1U 1H 1U\\ 803 | \busref{PSLVERR} & 0.5U 1U {[red]1X} 1U\\ 804 | \busref{APB-22} & 0.5L 1L 1H 1L\\ 805 | \extracode 806 | \begin{pgfonlayer}{background} 807 | \begin{scope}[semitransparent ,semithick] 808 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 809 | \end{scope} 810 | \end{pgfonlayer} 811 | \end{tikztimingtable} 812 | \caption{APB-22 Example}\label{fig:APB-22} 813 | \end{figure} 814 | 815 | \pagebreak 816 | 817 | 818 | 819 | \subsection{Watchdog expired}\label{subsec:APB-23} 820 | 821 | \begin{description} 822 | \setlength\itemsep{-0.45em} 823 | \item Message: APB-23 824 | \item Severity: FATAL 825 | \item Description: The optional watchdog counter expired. 826 | \item APB Version: from APB3 827 | \end{description} 828 | 829 | \begin{figure}[h] 830 | \begin{tikztimingtable}[% 831 | timing/dslope=0.1, 832 | timing/.style={x=5ex,y=2ex}, 833 | x=5ex, 834 | timing/rowdist=3ex, 835 | timing/name/.style={font=\sffamily\scriptsize} 836 | ] 837 | \busref{PCLK} & 13{c} \\ 838 | \busref{PSEL} & 0.5L 6H\\ 839 | \busref{PENABLE} & 0.5U 1L 5H\\ 840 | \busref{PREADY} & 0.5U 1U 5L\\ 841 | \busref{watchdog\_cnt} & 0.5U 1U 1D{n} 1D{n-1} {[dotted] 1D{}} 1D{1} 1D{0}\\ 842 | \busref{APB-23} & 0.5L 5L 1H\\ 843 | \extracode 844 | \begin{pgfonlayer}{background} 845 | \begin{scope}[semitransparent ,semithick] 846 | \vertlines[darkgray,dotted]{0.5,1.5,...,6.0} 847 | \end{scope} 848 | \end{pgfonlayer} 849 | \end{tikztimingtable} 850 | \caption{APB-23 Example}\label{fig:APB-23} 851 | \end{figure} 852 | 853 | 854 | 855 | \subsection{PWAKEUP must remain high until the end of the transfer}\label{subsec:APB-24} 856 | 857 | \begin{description} 858 | \setlength\itemsep{-0.45em} 859 | \item Message: APB-24 860 | \item Severity: ERROR 861 | \item Description: PWAKEUP must remain high (`1') until PREADY is high (`1'), if both PSEL and PWAKEUP are high (`1'). 862 | \item APB Version: from APB5 863 | \end{description} 864 | 865 | \begin{figure}[h] 866 | \begin{tikztimingtable}[% 867 | timing/dslope=0.1, 868 | timing/.style={x=5ex,y=2ex}, 869 | x=5ex, 870 | timing/rowdist=3ex, 871 | timing/name/.style={font=\sffamily\scriptsize} 872 | ] 873 | \busref{PCLK} & 11{c} \\ 874 | \busref{PSEL} & 0.5L 1H 3H 1L\\ 875 | \busref{PENABLE} & 0.5U 1L 3H 1L\\ 876 | \busref{PREADY} & 0.5U 1U 2L 1H 1L\\ 877 | \busref{PWAKEUP} & 0.5H 1H 1H {[red]2L} 1L\\ 878 | \busref{APB-24} & 0.5L 2L 2H 1L\\ 879 | \extracode 880 | \begin{pgfonlayer}{background} 881 | \begin{scope}[semitransparent ,semithick] 882 | \vertlines[darkgray,dotted]{0.5,1.5,...,5.0} 883 | \end{scope} 884 | \end{pgfonlayer} 885 | \end{tikztimingtable} 886 | \caption{APB-24 Example}\label{fig:APB-24} 887 | \end{figure} 888 | 889 | \pagebreak 890 | 891 | 892 | 893 | \subsection{PWAKEUP should be asserted at least one cycle before PSEL}\label{subsec:APB-25} 894 | 895 | \begin{description} 896 | \setlength\itemsep{-0.45em} 897 | \item Message: APB-25 898 | \item Severity: WARNING 899 | \item Description: PWAKEUP should be high (`1') at least 1 PCLK cycle before PSEL goes high (`1'). 900 | \item APB Version: from APB5 901 | \end{description} 902 | 903 | \begin{figure}[h] 904 | \begin{tikztimingtable}[% 905 | timing/dslope=0.1, 906 | timing/.style={x=5ex,y=2ex}, 907 | x=5ex, 908 | timing/rowdist=3ex, 909 | timing/name/.style={font=\sffamily\scriptsize} 910 | ] 911 | \busref{PCLK} & 5{c} \\ 912 | \busref{PWAKEUP} & 0.5L {[red]1L} 1H\\ 913 | \busref{PSEL} & 0.5L 1L 1H\\ 914 | \busref{APB-25} & 0.5L 1H 1L\\ 915 | \extracode 916 | \begin{pgfonlayer}{background} 917 | \begin{scope}[semitransparent ,semithick] 918 | \vertlines[darkgray,dotted]{0.5,1.5,...,2.0} 919 | \end{scope} 920 | \end{pgfonlayer} 921 | \end{tikztimingtable} 922 | \caption{APB-25 Example}\label{fig:APB-25} 923 | \end{figure} 924 | 925 | 926 | 927 | \subsection{PWAKEUP raised without starting a transfer}\label{subsec:APB-26} 928 | 929 | \begin{description} 930 | \setlength\itemsep{-0.45em} 931 | \item Message: APB-26 932 | \item Severity: WARNING 933 | \item Description: PWAKEUP should not be raised without starting a transfer. 934 | \item APB Version: from APB5 935 | \end{description} 936 | 937 | \begin{figure}[h] 938 | \begin{tikztimingtable}[% 939 | timing/dslope=0.1, 940 | timing/.style={x=5ex,y=2ex}, 941 | x=5ex, 942 | timing/rowdist=3ex, 943 | timing/name/.style={font=\sffamily\scriptsize} 944 | ] 945 | \busref{PCLK} & 7{c} \\ 946 | \busref{PWAKEUP} & 0.5L 2H {[red]1L} 1L\\ 947 | \busref{PSEL} & 0.5L 2L 2L\\ 948 | \busref{APB-26} & 0.5L 2L 1H 1L\\ 949 | \extracode 950 | \begin{pgfonlayer}{background} 951 | \begin{scope}[semitransparent ,semithick] 952 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 953 | \end{scope} 954 | \end{pgfonlayer} 955 | \end{tikztimingtable} 956 | \caption{APB-26 Example}\label{fig:APB-26} 957 | \end{figure} 958 | 959 | 960 | 961 | \subsection{PWAKEUP undefined}\label{subsec:APB-27} 962 | 963 | \begin{description} 964 | \setlength\itemsep{-0.45em} 965 | \item Message: APB-27 966 | \item Severity: ERROR 967 | \item Description: The PWAKEUP signal may never be undefined (`x') or (`z'). 968 | \item APB Version: from APB5 969 | \end{description} 970 | 971 | \begin{figure}[h] 972 | \begin{tikztimingtable}[% 973 | timing/dslope=0.1, 974 | timing/.style={x=5ex,y=2ex}, 975 | x=5ex, 976 | timing/rowdist=3ex, 977 | timing/name/.style={font=\sffamily\scriptsize} 978 | ] 979 | \busref{PCLK} & 7{c} \\ 980 | \busref{PWAKEUP} & 0.5L 1L {[red]1X} 1H\\ 981 | \busref{APB-27} & 0.5L 1L 1H 1L\\ 982 | \extracode 983 | \begin{pgfonlayer}{background} 984 | \begin{scope}[semitransparent ,semithick] 985 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 986 | \end{scope} 987 | \end{pgfonlayer} 988 | \end{tikztimingtable} 989 | \caption{APB-27 Example}\label{fig:APB-27} 990 | \end{figure} 991 | 992 | \pagebreak 993 | 994 | 995 | 996 | \subsection{PAUSER must remain stable for the entire transfer}\label{subsec:APB-28} 997 | 998 | \begin{description} 999 | \setlength\itemsep{-0.45em} 1000 | \item Message: APB-28 1001 | \item Severity: ERROR 1002 | \item Description: The PAUSER signal may not change during a transfer. 1003 | \item APB Version: from APB5 1004 | \end{description} 1005 | 1006 | \begin{figure}[h] 1007 | \begin{tikztimingtable}[% 1008 | timing/dslope=0.1, 1009 | timing/.style={x=5ex,y=2ex}, 1010 | x=5ex, 1011 | timing/rowdist=3ex, 1012 | timing/name/.style={font=\sffamily\scriptsize} 1013 | ] 1014 | \busref{PCLK} & 7{c} \\ 1015 | \busref{PSEL} & 0.5L 2H 1L\\ 1016 | \busref{PAUSER} & 0.5U 1D{A} {[red] 1D{B}} 1U\\ 1017 | \busref{APB-28} & 0.5L 1L 1H 1L\\ 1018 | \extracode 1019 | \begin{pgfonlayer}{background} 1020 | \begin{scope}[semitransparent ,semithick] 1021 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 1022 | \end{scope} 1023 | \end{pgfonlayer} 1024 | \end{tikztimingtable} 1025 | \caption{APB-28 Example}\label{fig:APB-28} 1026 | \end{figure} 1027 | 1028 | 1029 | 1030 | \subsection{PAUSER undefined}\label{subsec:APB-29} 1031 | 1032 | \begin{description} 1033 | \setlength\itemsep{-0.45em} 1034 | \item Message: APB-29 1035 | \item Severity: ERROR 1036 | \item Description: The PAUSER signal may never be undefined (`x') or (`z') during a transfer. 1037 | \item APB Version: from APB5 1038 | \end{description} 1039 | 1040 | \begin{figure}[h] 1041 | \begin{tikztimingtable}[% 1042 | timing/dslope=0.1, 1043 | timing/.style={x=5ex,y=2ex}, 1044 | x=5ex, 1045 | timing/rowdist=3ex, 1046 | timing/name/.style={font=\sffamily\scriptsize} 1047 | ] 1048 | \busref{PCLK} & 7{c} \\ 1049 | \busref{PSEL} & 0.5L 2H 1L\\ 1050 | \busref{PAUSER} & 0.5U {[red] 2X} 1U\\ 1051 | \busref{APB-29} & 0.5L 2H 1L\\ 1052 | \extracode 1053 | \begin{pgfonlayer}{background} 1054 | \begin{scope}[semitransparent ,semithick] 1055 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 1056 | \end{scope} 1057 | \end{pgfonlayer} 1058 | \end{tikztimingtable} 1059 | \caption{APB-29 Example}\label{fig:APB-29} 1060 | \end{figure} 1061 | 1062 | 1063 | 1064 | \subsection{PAUSER should be max 128 bits}\label{subsec:APB-30} 1065 | 1066 | \begin{description} 1067 | \setlength\itemsep{-0.45em} 1068 | \item Message: APB-30 1069 | \item Severity: WARNING 1070 | \item Description: The PAUSER signal width should be less than 128 bits. 1071 | \item APB Version: from APB5 1072 | \end{description} 1073 | 1074 | \pagebreak 1075 | 1076 | 1077 | 1078 | \subsection{PWUSER must remain stable for the entire transfer}\label{subsec:APB-31} 1079 | 1080 | \begin{description} 1081 | \setlength\itemsep{-0.45em} 1082 | \item Message: APB-31 1083 | \item Severity: ERROR 1084 | \item Description: The PWUSER signal may not change during a transfer. 1085 | \item APB Version: from APB5 1086 | \end{description} 1087 | 1088 | \begin{figure}[h] 1089 | \begin{tikztimingtable}[% 1090 | timing/dslope=0.1, 1091 | timing/.style={x=5ex,y=2ex}, 1092 | x=5ex, 1093 | timing/rowdist=3ex, 1094 | timing/name/.style={font=\sffamily\scriptsize} 1095 | ] 1096 | \busref{PCLK} & 7{c} \\ 1097 | \busref{PSEL} & 0.5L 2H 1L\\ 1098 | \busref{PWUSER} & 0.5U 1D{A} {[red] 1D{B}} 1U\\ 1099 | \busref{APB-31} & 0.5L 1L 1H 1L\\ 1100 | \extracode 1101 | \begin{pgfonlayer}{background} 1102 | \begin{scope}[semitransparent ,semithick] 1103 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 1104 | \end{scope} 1105 | \end{pgfonlayer} 1106 | \end{tikztimingtable} 1107 | \caption{APB-31 Example}\label{fig:APB-31} 1108 | \end{figure} 1109 | 1110 | 1111 | 1112 | \subsection{PWUSER undefined}\label{subsec:APB-32} 1113 | 1114 | \begin{description} 1115 | \setlength\itemsep{-0.45em} 1116 | \item Message: APB-32 1117 | \item Severity: ERROR 1118 | \item Description: The PWUSER signal may never be undefined (`x') or (`z') during a transfer. 1119 | \item APB Version: from APB5 1120 | \end{description} 1121 | 1122 | \begin{figure}[h] 1123 | \begin{tikztimingtable}[% 1124 | timing/dslope=0.1, 1125 | timing/.style={x=5ex,y=2ex}, 1126 | x=5ex, 1127 | timing/rowdist=3ex, 1128 | timing/name/.style={font=\sffamily\scriptsize} 1129 | ] 1130 | \busref{PCLK} & 7{c} \\ 1131 | \busref{PSEL} & 0.5L 2H 1L\\ 1132 | \busref{PWUSER} & 0.5U {[red] 2X} 1U\\ 1133 | \busref{APB-32} & 0.5L 2H 1L\\ 1134 | \extracode 1135 | \begin{pgfonlayer}{background} 1136 | \begin{scope}[semitransparent ,semithick] 1137 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 1138 | \end{scope} 1139 | \end{pgfonlayer} 1140 | \end{tikztimingtable} 1141 | \caption{APB-32 Example}\label{fig:APB-32} 1142 | \end{figure} 1143 | 1144 | 1145 | 1146 | \subsection{PWUSER should be max DATA\_WIDTH/2 bits}\label{subsec:APB-33} 1147 | 1148 | \begin{description} 1149 | \setlength\itemsep{-0.45em} 1150 | \item Message: APB-33 1151 | \item Severity: WARNING 1152 | \item Description: The PWUSER signal width should be less than DATA\_WIDTH/2 bits. 1153 | \item APB Version: from APB5 1154 | \end{description} 1155 | 1156 | \pagebreak 1157 | 1158 | 1159 | 1160 | \subsection{PRUSER contains 'x'}\label{subsec:APB-34} 1161 | 1162 | \begin{description} 1163 | \setlength\itemsep{-0.45em} 1164 | \item Message: APB-34 1165 | \item Severity: WARNING 1166 | \item Description: One or more bits of the PRUSER signal are undefined (`x') or (`z') during a read transfer. 1167 | \item APB Version: from APB5 1168 | \end{description} 1169 | 1170 | \begin{figure}[h] 1171 | \begin{tikztimingtable}[% 1172 | timing/dslope=0.1, 1173 | timing/.style={x=5ex,y=2ex}, 1174 | x=5ex, 1175 | timing/rowdist=3ex, 1176 | timing/name/.style={font=\sffamily\scriptsize} 1177 | ] 1178 | \busref{PCLK} & 7{c} \\ 1179 | \busref{PSEL} & 0.5L 2H 1L\\ 1180 | \busref{PENABLE} & 0.5U 1L 1H 1U\\ 1181 | \busref{PWRITE} & 0.5U 2L 1U\\ 1182 | \busref[15:0]{PRUSER} & 0.5U 1U {[red]1D{0xXEDC}} 1U\\ 1183 | \busref{APB-20} & 0.5L 1L 1H 1L\\ 1184 | \extracode 1185 | \begin{pgfonlayer}{background} 1186 | \begin{scope}[semitransparent ,semithick] 1187 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 1188 | \end{scope} 1189 | \end{pgfonlayer} 1190 | \end{tikztimingtable} 1191 | \caption{APB-34 Example}\label{fig:APB-34} 1192 | \end{figure} 1193 | 1194 | 1195 | 1196 | \subsection{PRUSER should be max DATA\_WIDTH/2 bits}\label{subsec:APB-35} 1197 | 1198 | \begin{description} 1199 | \setlength\itemsep{-0.45em} 1200 | \item Message: APB-35 1201 | \item Severity: WARNING 1202 | \item Description: The PRUSER signal width should be less than DATA\_WIDTH/2 bits. 1203 | \item APB Version: from APB5 1204 | \end{description} 1205 | 1206 | 1207 | 1208 | \subsection{PBUSER contains 'x'}\label{subsec:APB-36} 1209 | 1210 | \begin{description} 1211 | \setlength\itemsep{-0.45em} 1212 | \item Message: APB-36 1213 | \item Severity: WARNING 1214 | \item Description: One or more bits of the PBUSER signal are undefined (`x') or (`z') during the final cycle of a transfer. 1215 | \item APB Version: from APB5 1216 | \end{description} 1217 | 1218 | \begin{figure}[h] 1219 | \begin{tikztimingtable}[% 1220 | timing/dslope=0.1, 1221 | timing/.style={x=5ex,y=2ex}, 1222 | x=5ex, 1223 | timing/rowdist=3ex, 1224 | timing/name/.style={font=\sffamily\scriptsize} 1225 | ] 1226 | \busref{PCLK} & 9{c} \\ 1227 | \busref{PSEL} & 0.5L 2H 1H 1L\\ 1228 | \busref{PENABLE} & 0.5U 1L 1H 1H 1U\\ 1229 | \busref{PREADY} & 0.5U 1U 1L 1H 1U\\ 1230 | \busref[15:0]{PBUSER} & 0.5U 1U 1D{0xXEDC} {[red]1D{0xXEDC}} 1U\\ 1231 | \busref{APB-36} & 0.5L 1L 1L 1H 1L\\ 1232 | \extracode 1233 | \begin{pgfonlayer}{background} 1234 | \begin{scope}[semitransparent ,semithick] 1235 | \vertlines[darkgray,dotted]{0.5,1.5,...,4.0} 1236 | \end{scope} 1237 | \end{pgfonlayer} 1238 | \end{tikztimingtable} 1239 | \caption{APB-36 Example}\label{fig:APB-36} 1240 | \end{figure} 1241 | 1242 | 1243 | 1244 | \subsection{PBUSER should be max 16 bits}\label{subsec:APB-37} 1245 | 1246 | \begin{description} 1247 | \setlength\itemsep{-0.45em} 1248 | \item Message: APB-37 1249 | \item Severity: WARNING 1250 | \item Description: The PBUSER signal width should be less than 16 bits. 1251 | \item APB Version: from APB5 1252 | \end{description} 1253 | 1254 | \pagebreak 1255 | 1256 | 1257 | 1258 | \subsection{PSTRB must be low during read transfer}\label{subsec:APB-38} 1259 | 1260 | \begin{description} 1261 | \setlength\itemsep{-0.45em} 1262 | \item Message: APB-38 1263 | \item Severity: ERROR 1264 | \item Description: The PSTRB signal must be low (all `0') during a read transfer. 1265 | \item APB Version: from APB4 1266 | \end{description} 1267 | 1268 | \begin{figure}[h] 1269 | \begin{tikztimingtable}[% 1270 | timing/dslope=0.1, 1271 | timing/.style={x=5ex,y=2ex}, 1272 | x=5ex, 1273 | timing/rowdist=3ex, 1274 | timing/name/.style={font=\sffamily\scriptsize} 1275 | ] 1276 | \busref{PCLK} & 7{c} \\ 1277 | \busref{PSEL} & 0.5L 2H 1L\\ 1278 | \busref{PWRITE} & 0.5L 2L 1L\\ 1279 | \busref{PSTRB} & 0.5U {[red] 2D{0x01}} 1U\\ 1280 | \busref{APB-38} & 0.5L 2H 1L\\ 1281 | \extracode 1282 | \begin{pgfonlayer}{background} 1283 | \begin{scope}[semitransparent ,semithick] 1284 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 1285 | \end{scope} 1286 | \end{pgfonlayer} 1287 | \end{tikztimingtable} 1288 | \caption{APB-38 Example}\label{fig:APB-38} 1289 | \end{figure} 1290 | 1291 | 1292 | 1293 | \subsection{PADDR should be max 32 bits}\label{subsec:APB-39} 1294 | 1295 | \begin{description} 1296 | \setlength\itemsep{-0.45em} 1297 | \item Message: APB-39 1298 | \item Severity: WARNING 1299 | \item Description: The PADDR signal width should be less than 32 bits. 1300 | \item APB Version: All 1301 | \end{description} 1302 | 1303 | 1304 | 1305 | \subsection{PWDATA should be max 8, 16, or 32 bits wide}\label{subsec:APB-40} 1306 | 1307 | \begin{description} 1308 | \setlength\itemsep{-0.45em} 1309 | \item Message: APB-40 1310 | \item Severity: WARNING 1311 | \item Description: The PWDATA signal width should be either 8, 16, or 32 bits. 1312 | \item APB Version: All 1313 | \end{description} 1314 | 1315 | 1316 | 1317 | \subsection{PRDATA should be max 8, 16, or 32 bits wide}\label{subsec:APB-41} 1318 | 1319 | \begin{description} 1320 | \setlength\itemsep{-0.45em} 1321 | \item Message: APB-41 1322 | \item Severity: WARNING 1323 | \item Description: The PRDATA signal width should be either 8, 16, or 32 bits. 1324 | \item APB Version: All 1325 | \end{description} 1326 | 1327 | 1328 | 1329 | \subsection{PRESETn Undefined}\label{subsec:APB-42} 1330 | 1331 | \begin{description} 1332 | \setlength\itemsep{-0.45em} 1333 | \item Message: APB-42 1334 | \item Severity: ERROR 1335 | \item Description: The PRESETn signal may never be undefined (`x') or (`z'). 1336 | \item APB Version: All 1337 | \end{description} 1338 | 1339 | \begin{figure}[h] 1340 | \begin{tikztimingtable}[% 1341 | timing/dslope=0.1, 1342 | timing/.style={x=5ex,y=2ex}, 1343 | x=5ex, 1344 | timing/rowdist=3ex, 1345 | timing/name/.style={font=\sffamily\scriptsize} 1346 | ] 1347 | \busref{PRESETn} & 0.5L 1L 1X 1H\\ 1348 | \busref{APB-42} & 0.5L 1L 1H 1L\\ 1349 | \extracode 1350 | \begin{pgfonlayer}{background} 1351 | \begin{scope}[semitransparent ,semithick] 1352 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 1353 | \end{scope} 1354 | \end{pgfonlayer} 1355 | \end{tikztimingtable} 1356 | \caption{APB-42 Example}\label{fig:APB-42} 1357 | \end{figure} 1358 | 1359 | 1360 | 1361 | \subsection{PCLK Undefined}\label{subsec:APB-43} 1362 | 1363 | \begin{description} 1364 | \setlength\itemsep{-0.45em} 1365 | \item Message: APB-43 1366 | \item Severity: ERROR 1367 | \item Description: The PCLK signal may never be undefined (`x') or (`z'). 1368 | \item APB Version: All 1369 | \end{description} 1370 | 1371 | \begin{figure}[h] 1372 | \begin{tikztimingtable}[% 1373 | timing/dslope=0.1, 1374 | timing/.style={x=5ex,y=2ex}, 1375 | x=5ex, 1376 | timing/rowdist=3ex, 1377 | timing/name/.style={font=\sffamily\scriptsize} 1378 | ] 1379 | \busref{PRESETn} & 0.5H 3H\\ 1380 | \busref{PCLK} & 3{c} 1x 3{c}\\ 1381 | \busref{APB-43} & 0.5L 1L 1h 1L\\ 1382 | \extracode 1383 | \begin{pgfonlayer}{background} 1384 | \begin{scope}[semitransparent ,semithick] 1385 | \vertlines[darkgray,dotted]{0.5,1.5,...,3.0} 1386 | \end{scope} 1387 | \end{pgfonlayer} 1388 | \end{tikztimingtable} 1389 | \caption{APB-43 Example}\label{fig:APB-43} 1390 | \end{figure} 1391 | 1392 | \pagebreak 1393 | 1394 | 1395 | 1396 | \section{Rules per signal}\label{sec:RulesPerSignal} 1397 | 1398 | \begin{longtable}[]{@{}lrl@{}} 1399 | \toprule 1400 | \textbf{Signal} & \textbf{MsgNo} & \textbf{Message}\tabularnewline 1401 | \midrule 1402 | \endhead 1403 | \texttt{PRESETn} & 42 & \nameref{subsec:APB-42}\tabularnewline 1404 | \texttt{PCLK} & 43 & \nameref{subsec:APB-43}\tabularnewline 1405 | \texttt{PSEL} & 1 & \nameref{subsec:APB-1} \tabularnewline 1406 | \texttt{PSEL} & 2 & \nameref{subsec:APB-2} \tabularnewline 1407 | \texttt{PENABLE} & 3 & \nameref{subsec:APB-3} \tabularnewline 1408 | \texttt{PENABLE} & 4 & \nameref{subsec:APB-4} \tabularnewline 1409 | \texttt{PENABLE} & 5 & \nameref{subsec:APB-5} \tabularnewline 1410 | \texttt{PADDR} & 6 & \nameref{subsec:APB-6} \tabularnewline 1411 | \texttt{PADDR} & 7 & \nameref{subsec:APB-7} \tabularnewline 1412 | \texttt{PADDR} & 8 & \nameref{subsec:APB-8} \tabularnewline 1413 | \texttt{PADDR} & 9 & \nameref{subsec:APB-9} \tabularnewline 1414 | \texttt{PADDR} & 39 & \nameref{subsec:APB-39}\tabularnewline 1415 | \texttt{PWRITE} & 10 & \nameref{subsec:APB-10}\tabularnewline 1416 | \texttt{PWRITE} & 11 & \nameref{subsec:APB-11}\tabularnewline 1417 | \texttt{PSTRB} & 12 & \nameref{subsec:APB-12}\tabularnewline 1418 | \texttt{PSTRB} & 13 & \nameref{subsec:APB-13}\tabularnewline 1419 | \texttt{PSTRB} & 14 & \nameref{subsec:APB-14}\tabularnewline 1420 | \texttt{PSTRB} & 38 & \nameref{subsec:APB-38}\tabularnewline 1421 | \texttt{PPROT} & 15 & \nameref{subsec:APB-15}\tabularnewline 1422 | \texttt{PPROT} & 16 & \nameref{subsec:APB-16}\tabularnewline 1423 | \texttt{PWDATA} & 17 & \nameref{subsec:APB-17}\tabularnewline 1424 | \texttt{PWDATA} & 18 & \nameref{subsec:APB-18}\tabularnewline 1425 | \texttt{PWDATA} & 19 & \nameref{subsec:APB-19}\tabularnewline 1426 | \texttt{PWDATA} & 40 & \nameref{subsec:APB-40}\tabularnewline 1427 | \texttt{PRDATA} & 20 & \nameref{subsec:APB-20}\tabularnewline 1428 | \texttt{PRDATA} & 41 & \nameref{subsec:APB-41}\tabularnewline 1429 | \texttt{PREADY} & 21 & \nameref{subsec:APB-21}\tabularnewline 1430 | \texttt{PSLVERR} & 22 & \nameref{subsec:APB-22}\tabularnewline 1431 | \texttt{PWAKEUP} & 24 & \nameref{subsec:APB-24}\tabularnewline 1432 | \texttt{PWAKEUP} & 25 & \nameref{subsec:APB-25}\tabularnewline 1433 | \texttt{PWAKEUP} & 26 & \nameref{subsec:APB-26}\tabularnewline 1434 | \texttt{PWAKEUP} & 27 & \nameref{subsec:APB-27}\tabularnewline 1435 | \texttt{PAUSER} & 28 & \nameref{subsec:APB-28}\tabularnewline 1436 | \texttt{PAUSER} & 29 & \nameref{subsec:APB-29}\tabularnewline 1437 | \texttt{PAUSER} & 30 & \nameref{subsec:APB-30}\tabularnewline 1438 | \texttt{PWUSER} & 31 & \nameref{subsec:APB-31}\tabularnewline 1439 | \texttt{PWUSER} & 32 & \nameref{subsec:APB-32}\tabularnewline 1440 | \texttt{PWUSER} & 33 & \nameref{subsec:APB-33}\tabularnewline 1441 | \texttt{PRUSER} & 34 & \nameref{subsec:APB-34}\tabularnewline 1442 | \texttt{PRUSER} & 35 & \nameref{subsec:APB-35}\tabularnewline 1443 | \texttt{PBUSER} & 36 & \nameref{subsec:APB-36}\tabularnewline 1444 | \texttt{PBUSER} & 37 & \nameref{subsec:APB-37}\tabularnewline 1445 | \bottomrule 1446 | \caption{Rules per signal} 1447 | \end{longtable} 1448 | --------------------------------------------------------------------------------