├── .gitignore
├── sim
└── ahb3lite
│ ├── run
│ ├── Makefile
│ └── Makefile.include
│ └── bin
│ ├── Makefile.riviera
│ ├── Makefile.include
│ └── Makefile
├── docs
├── tex
│ ├── tableofcontents.tex
│ ├── history.tex
│ ├── references.tex
│ ├── resources.tex
│ ├── setup.tex
│ ├── introduction.tex
│ ├── configuration.tex
│ ├── preamble.tex
│ ├── interfaces-ahblite.tex
│ └── specification.tex
├── assets
│ ├── img
│ │ ├── CONFIG.png
│ │ ├── RoaLogicHeader.eps
│ │ ├── AHB-Lite_PLIC_Worksheet.png
│ │ ├── plic-if-eps-converted-to.pdf
│ │ ├── plic-ports-eps-converted-to.pdf
│ │ ├── Tagged_Logo-eps-converted-to.pdf
│ │ ├── plic-system-eps-converted-to.pdf
│ │ ├── RoaLogicHeader-eps-converted-to.pdf
│ │ ├── plic-handshake-eps-converted-to.pdf
│ │ └── PLIC-block-diagram-eps-converted-to.pdf
│ └── csv
│ │ ├── configreg.xlsx
│ │ └── RegisterMapping.xlsx
├── AHB-Lite_PLIC_Datasheet.pdf
├── markdown
│ ├── frontmatter.md
│ ├── compile.sh
│ └── lpp.pl
├── AHB-Lite_PLIC_Markdown.tex
├── AHB-Lite_PLIC_Datasheet.tex
├── pkg
│ └── roalogictitle.sty
└── Getting_Started.md
├── assets
├── img
│ ├── CONFIG.png
│ ├── Folders.png
│ ├── plic-if.png
│ ├── RoaLogicLogo.png
│ ├── plic-ports.png
│ ├── plic-system.png
│ ├── plic-handshake.png
│ ├── PLIC-block-diagram.png
│ └── AHB-Lite_PLIC_Worksheet.png
└── css
│ └── style.scss
├── .gitmodules
├── _config.yml
├── rtl
├── filelist_apb4.f
├── filelist_ahb3lite.f
└── verilog
│ ├── LICENSE.txt
│ ├── core
│ ├── plic_cell.sv
│ ├── plic_target.sv
│ ├── plic_priority_index.sv
│ ├── plic_gateway.sv
│ ├── plic_core.sv
│ └── plic_dynamic_registers.sv
│ ├── apb4
│ └── apb4_plic_top.sv
│ └── ahb3lite
│ └── ahb3lite_plic_top.sv
├── README.md
├── _layouts
└── default.html
├── bench
└── verilog
│ ├── testbench_top.sv
│ ├── ahb3lite_bfm.sv
│ └── test.sv
└── LICENSE.md
/.gitignore:
--------------------------------------------------------------------------------
1 | docs/build
2 |
3 |
--------------------------------------------------------------------------------
/sim/ahb3lite/run/Makefile:
--------------------------------------------------------------------------------
1 | ../bin/Makefile
--------------------------------------------------------------------------------
/docs/tex/tableofcontents.tex:
--------------------------------------------------------------------------------
1 | \tableofcontents
2 | \newpage
--------------------------------------------------------------------------------
/sim/ahb3lite/run/Makefile.include:
--------------------------------------------------------------------------------
1 | ../bin/Makefile.include
--------------------------------------------------------------------------------
/assets/img/CONFIG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/assets/img/CONFIG.png
--------------------------------------------------------------------------------
/assets/img/Folders.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/assets/img/Folders.png
--------------------------------------------------------------------------------
/assets/img/plic-if.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/assets/img/plic-if.png
--------------------------------------------------------------------------------
/assets/img/RoaLogicLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/assets/img/RoaLogicLogo.png
--------------------------------------------------------------------------------
/assets/img/plic-ports.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/assets/img/plic-ports.png
--------------------------------------------------------------------------------
/assets/img/plic-system.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/assets/img/plic-system.png
--------------------------------------------------------------------------------
/docs/assets/img/CONFIG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/docs/assets/img/CONFIG.png
--------------------------------------------------------------------------------
/assets/img/plic-handshake.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/assets/img/plic-handshake.png
--------------------------------------------------------------------------------
/docs/AHB-Lite_PLIC_Datasheet.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/docs/AHB-Lite_PLIC_Datasheet.pdf
--------------------------------------------------------------------------------
/docs/assets/csv/configreg.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/docs/assets/csv/configreg.xlsx
--------------------------------------------------------------------------------
/assets/img/PLIC-block-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/assets/img/PLIC-block-diagram.png
--------------------------------------------------------------------------------
/docs/assets/img/RoaLogicHeader.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/docs/assets/img/RoaLogicHeader.eps
--------------------------------------------------------------------------------
/docs/assets/csv/RegisterMapping.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/docs/assets/csv/RegisterMapping.xlsx
--------------------------------------------------------------------------------
/assets/img/AHB-Lite_PLIC_Worksheet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/assets/img/AHB-Lite_PLIC_Worksheet.png
--------------------------------------------------------------------------------
/docs/assets/img/AHB-Lite_PLIC_Worksheet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/docs/assets/img/AHB-Lite_PLIC_Worksheet.png
--------------------------------------------------------------------------------
/docs/assets/img/plic-if-eps-converted-to.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/docs/assets/img/plic-if-eps-converted-to.pdf
--------------------------------------------------------------------------------
/docs/assets/img/plic-ports-eps-converted-to.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/docs/assets/img/plic-ports-eps-converted-to.pdf
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "submodules/ahb3lite_pkg"]
2 | path = submodules/ahb3lite_pkg
3 | url = https://github.com/roalogic/ahb3lite_pkg.git
4 |
--------------------------------------------------------------------------------
/docs/assets/img/Tagged_Logo-eps-converted-to.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/docs/assets/img/Tagged_Logo-eps-converted-to.pdf
--------------------------------------------------------------------------------
/docs/assets/img/plic-system-eps-converted-to.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/docs/assets/img/plic-system-eps-converted-to.pdf
--------------------------------------------------------------------------------
/docs/assets/img/RoaLogicHeader-eps-converted-to.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/docs/assets/img/RoaLogicHeader-eps-converted-to.pdf
--------------------------------------------------------------------------------
/docs/assets/img/plic-handshake-eps-converted-to.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/docs/assets/img/plic-handshake-eps-converted-to.pdf
--------------------------------------------------------------------------------
/docs/assets/img/PLIC-block-diagram-eps-converted-to.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoaLogic/plic/HEAD/docs/assets/img/PLIC-block-diagram-eps-converted-to.pdf
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-dinky
2 | title: AHB-Lite PLIC
3 | description: RISC-V Platform Level Interrupt Controller
4 | show_downloads: true
5 | show_license: true
6 | license: BSD License
7 |
--------------------------------------------------------------------------------
/docs/markdown/frontmatter.md:
--------------------------------------------------------------------------------
1 | ---
2 | Title: AHB-Lite Platform-Level Interrupt Controller (PLIC)
3 | Category: Datasheet
4 | Author: Roa Logic
5 | ---
6 | # AHB-Lite Platform-Level Interrupt Controller (PLIC) Datasheet
7 |
8 | ## Contents
9 |
--------------------------------------------------------------------------------
/rtl/filelist_apb4.f:
--------------------------------------------------------------------------------
1 | verilog/core/plic_dynamic_registers.sv
2 | verilog/core/plic_priority_index.sv
3 | verilog/core/plic_cell.sv
4 | verilog/core/plic_target.sv
5 | verilog/core/plic_gateway.sv
6 | verilog/core/plic_core.sv
7 | verilog/apb4/apb4_plic_top.sv
8 |
9 |
--------------------------------------------------------------------------------
/rtl/filelist_ahb3lite.f:
--------------------------------------------------------------------------------
1 | verilog/core/plic_dynamic_registers.sv
2 | verilog/core/plic_priority_index.sv
3 | verilog/core/plic_cell.sv
4 | verilog/core/plic_target.sv
5 | verilog/core/plic_gateway.sv
6 | verilog/core/plic_core.sv
7 | verilog/ahb3lite/ahb3lite_plic_top.sv
8 |
9 |
--------------------------------------------------------------------------------
/docs/tex/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 | 13-Oct-2017 & 1.0 & Initial Release\\
12 | 01-Dec-2017 & 1.1 & RISC-V Privileged Spec v1.10 compliance\\
13 | & & \\
14 | & & \\
15 | \bottomrule
16 | \caption{Revision History}
17 | \label{tab:REVS}
18 | \end{longtable}
19 |
--------------------------------------------------------------------------------
/docs/AHB-Lite_PLIC_Markdown.tex:
--------------------------------------------------------------------------------
1 | \documentclass[oneside,11pt]{book}
2 |
3 | % Document Setup
4 | \input{markdown/preamble}
5 | \input{markdown/setup.tex}
6 |
7 | \begin{document}
8 |
9 | \mainmatter
10 |
11 | \input{markdown/introduction.tex}
12 |
13 | \input{markdown/specification.tex}
14 |
15 | \input{markdown/configuration.tex}
16 |
17 | \input{markdown/interfaces.tex}
18 |
19 | \input{markdown/resources.tex}
20 |
21 | \input{markdown/references.tex}
22 |
23 | \input{markdown/history.tex}
24 |
25 | \listoftodos % Temporary list of ToDo items
26 |
27 | \end{document}
28 |
--------------------------------------------------------------------------------
/docs/AHB-Lite_PLIC_Datasheet.tex:
--------------------------------------------------------------------------------
1 | \documentclass[a4paper,oneside,11pt,openany]{book}
2 |
3 | % Document Setup
4 | \input{tex/preamble.tex}
5 | \input{tex/setup.tex}
6 |
7 | % \usepackage{showframe}
8 |
9 | \begin{document}
10 |
11 | %\frontmatter
12 |
13 | \maketitle
14 | %\thispagestyle{empty}
15 |
16 | %\mainmatter
17 |
18 | \tableofcontents
19 |
20 | % \listoftodos % Temporary list of ToDo items
21 |
22 | \input{tex/introduction.tex}
23 |
24 | \input{tex/specification.tex}
25 |
26 | \input{tex/configuration.tex}
27 |
28 | \input{tex/interfaces.tex}
29 |
30 | \input{tex/resources.tex}
31 |
32 | \input{tex/references.tex}
33 |
34 | \input{tex/history.tex}
35 |
36 | \end{document}
37 |
--------------------------------------------------------------------------------
/docs/tex/references.tex:
--------------------------------------------------------------------------------
1 | \chapter{References}
2 |
3 | The PLIC is designed to be compliant with the following specifications, as licensed under the Creative Commons Attribution 4.0 International License:
4 |
5 | \begin{quote}
6 | ``The \href{https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-spec-v2.2.pdf}{RISC-V Instruction Set Manual, Volume I: User-Level ISA, Document
7 | Version 2.2}", Editors Andrew Waterman and Krste Asanović,RISC-V
8 | Foundation, May 2017.
9 | \end{quote}
10 |
11 | \begin{quote}
12 | ``The \href{https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-privileged-v1.10.pdf}{RISC-VInstruction Set Manual, Volume II: Privileged Architecture,
13 | Version 1.10}", Editors Andrew Waterman and Krste Asanović, RISC-V
14 | Foundation, May 2017.
15 | \end{quote}
16 |
--------------------------------------------------------------------------------
/docs/tex/resources.tex:
--------------------------------------------------------------------------------
1 | \chapter{Resources}
2 |
3 | Below are some example implementations for various platforms. All implementations are push button, with no effort undertaken to reduce area or improve performance.
4 | \setlength\LTleft{0pt}
5 | \setlength\LTright{0pt}
6 |
7 | \begin{longtable}[]{@{\extracolsep{\fill}}lcccc@{}}
8 | \toprule
9 | \textbf{Platform} & \textbf{DFF} & \textbf{Logic Cells/Elements} &
10 | \textbf{Memory} & \textbf{Performance (MHz)}\tabularnewline
11 | \midrule
12 | \endhead
13 | Altera Cyclone4 & 1234 & 4470 LEs & 0 & \tabularnewline
14 | & & & &\tabularnewline
15 | & & & &\tabularnewline
16 | \bottomrule
17 | \caption{Resource Utilisation Examples}
18 | \label{tab:RESOURCES}
19 | \end{longtable}
20 |
21 | Note: This table will be updated as more examples are compiled.
22 |
--------------------------------------------------------------------------------
/docs/markdown/compile.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | topfile="AHB-Lite_PLIC_Markdown"
4 |
5 | # Run from markdown directory only
6 | curdir=${PWD##*/}
7 |
8 | if [ "$curdir" != "markdown" ]
9 | then
10 | echo "Must run from markdown directory"
11 | exit
12 | fi
13 |
14 | # Pre-process LaTeX Source
15 | for entry in ../tex/*.tex
16 | do
17 | base="${entry##*/}"
18 | ./lpp.pl $entry > $base
19 | done
20 |
21 |
22 | # Generate new Markdown
23 | cd ..
24 | pandoc --atx-headers \
25 | --base-header-level=2 \
26 | --number-sections \
27 | --default-image-extension=png \
28 | --file-scope \
29 | --toc \
30 | --toc-depth=1 \
31 | -t markdown_github \
32 | -B markdown/frontmatter.md \
33 | -o ../DATASHEET.md \
34 | $topfile.tex
35 |
36 | cd markdown
37 |
38 | # Remove Preprocessed LaTeX source
39 | rm *.tex
40 |
--------------------------------------------------------------------------------
/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{AHB-Lite Platform Level Interrupt Controller}
9 | \heading{AHB-Lite Platform Level Interrupt Controller}
10 | \author{Roa Logic}
11 | \date{1st December, 2017}
12 | \version{1.1}
13 | \doctype{Datasheet}
14 | \project{http://roalogic.github.io/plic}
15 | \author{Paul Hardy}
16 |
17 | % Set page headers/footer
18 | \pagestyle{fancy}
19 | \fancyhf{}
20 | \fancyhead[L]{\theheading\space(v\theversion)}
21 | \fancyhead[R]{\includegraphics[width=50px,trim=0 25px 0 0]{assets/img/RoaLogicHeader}}
22 | \fancyfoot[C]{\thepage}
23 | % \fancyhead[R]{\thepage}
24 | % \fancyhead[L]{AHB-Lite Platform Level Interrupt Controller}
25 | % \fancyfoot[C]{\textcircled{c} Roa Logic}
26 |
27 | %\newcommand*{\MARKDOWN}{}%
28 |
--------------------------------------------------------------------------------
/docs/markdown/lpp.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/perl
2 |
3 |
4 | # print "Latex PreProcessor v0.1\n";
5 |
6 | my @defines = qw/MARKDOWN/;
7 | my @if = qw/0/;
8 | my @skip = qw/0/;
9 |
10 |
11 | #Go through input files
12 | while (<>) {
13 | chomp;
14 | # print $_;
15 |
16 | #get rid of comments; they mess up the checks
17 | s/%.*//;
18 |
19 |
20 | #check for new define
21 | if (/\\newcommand\*{\\(\w+)}{}/) {
22 | push @defines, $1;
23 | next;
24 | }
25 |
26 |
27 | #check for if
28 | if (/\\ifdefined\\(\w+)/) {
29 | my $index = 0;
30 | ++$index until $defines[$index] == $1 or $index > $#defines;
31 |
32 | if ($index > $#defines) {
33 | #value not found
34 | unshift @skip, 1;
35 | } else {
36 | #value found
37 | unshift @skip,0;
38 | }
39 |
40 | #found an if
41 | unshift @if,1;
42 |
43 | next;
44 | }
45 |
46 |
47 | #check for else
48 | if (/\\else/) {
49 | die "ELSE without IF\n" if $if[0] == 0;
50 |
51 | if ($skip[0] == 0) {
52 | $skip[0] = 1;
53 | } else {
54 | $skip[0] = 0;
55 | }
56 |
57 | next;
58 | }
59 |
60 |
61 | #check for end-if
62 | if (/\\fi\s*$/) {
63 | die "FI without IF\n" if $if[0] == 0;
64 |
65 | shift @if;
66 | shift @skip;
67 |
68 | next;
69 | }
70 |
71 |
72 | #write string
73 | print "$_\n" unless $skip[0];
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/docs/tex/introduction.tex:
--------------------------------------------------------------------------------
1 | \chapter{Product Brief}
2 |
3 | The Roa Logic AHB-Lite PLIC (Platform Level Interrupt Controller) IP is a fully parameterised soft IP implementing the Interrupt Controller defined in the \emph{\href{https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-privileged-v1.10.pdf}{RISC-V Privileged v1.10 specification}}\footnote{Full specification details are provided in the References section}.
4 |
5 | The IP features an AHB-Lite Slave interface, fully compliant with the \emph{\href{https://www.arm.com/products/system-ip/amba-specifications}{AMBA 3 AHB-Lite v1.0}} specifications.
6 |
7 | Bus address and data widths as well as the number of Interrupt Sources and Targets supported are configurable via compile-time parameters. The controller further supports user configurable priority levels and pending events, in addition to interrupt masking via programmable priority thresholds.
8 |
9 | \begin{figure}[!htb]
10 | \includegraphics{assets/img/plic-ports}
11 | \caption{PLIC Port Diagram}
12 | \label{fig:PORTDIAG}
13 | \end{figure}
14 |
15 | \section{Features}
16 |
17 | \begin{itemize}
18 | \item
19 | AHB-Lite Interface with parameterised address and data width
20 | \item
21 | User defined number of Interrupt Sources and Targets
22 | \item
23 | User defined priority level per Interrupt Source
24 | \item
25 | Interrupt masking per target via Priority Threshold support
26 | \item
27 | User defined Interrupt Pending queue depth per source
28 | \end{itemize}
29 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AHB-Lite Platform-Level Interrupt Controller (PLIC)
2 |
3 | ## Overview
4 |
5 | Fully Parameterized & Programmable Platform Level Interrupt Controller (PLIC) for RISC-V based Processor Systems supporting a user-defined number of interrupt sources and targets, and featuring a single AHB-Lite Slave interface
6 |
7 | The core supports a programmable number of simultaneous pending interrupt requests per source and individual routing of those interrupt requests to each target, full interrupt prioritisation of each interrupt source and separate enables per target via a matrix of interrupt enable bits.
8 |
9 | To reduce latency, the PLIC core presents all asserted interrupts to the target in priority order, queuing them so that a software interrupt handler can service all pending interrupts without the need to restore the interrupted context.
10 |
11 | 
12 |
13 | ## Documentation
14 |
15 | - [Datasheet](DATASHEET.md)
16 | - [PDF Format](docs/AHB-Lite_PLIC_Datasheet.pdf)
17 | - [Register Map Worksheet](docs/assets/csv/RegisterMapping.xlsx)
18 |
19 | ## Features
20 |
21 | - AHB-Lite Interface with programmable address and data width
22 | - User defined number of Interrupt Sources & Targets
23 | - User defined priority level per Interrupt Source
24 | - Interrupt masking per target via Priority Threshold support
25 | - User defined Interrupt Pending queue depth per source
26 |
27 | ## Compatibility
28 |
29 | Compliant to the [RISC-V Privilege Level 1.9, 1.9.1, 1.10 specifications](https://github.com/riscv/riscv-isa-manual/releases/tag/archive)
30 |
31 | ## Interfaces
32 |
33 | - AHB3 Lite
34 | - Dynamic Registers
35 |
36 | The PLIC core implements Dynamic Registers, which means the registers and register mapping are automatically generated based on the parameters provided to the core. The core prints the register mapping during simulation (and for some tools during synthesis).
37 |
38 | ## License
39 |
40 | Released under the RoaLogic [BSD License](/LICENSE.md)
41 |
42 | ## Dependencies
43 | Requires the Roa Logic [AHB3Lite Package](). This is included as a submodule.
44 | After cloning the git repository, perform a `git submodule init` to download the submodule.
45 |
--------------------------------------------------------------------------------
/assets/css/style.scss:
--------------------------------------------------------------------------------
1 | ---
2 | ---
3 |
4 | @import "{{ site.theme }}";
5 |
6 | body {
7 | background-color: #FFFFFF;
8 | }
9 |
10 | /* Add Roa Logic Font */
11 | h1, h2, h3 {
12 | font-family: Montserrat, Monaco, serif;
13 | }
14 |
15 | h4, h5, h6 {
16 | font-family: Montserrat, Monaco, serif;
17 | font-weight: 700;
18 | }
19 |
20 | th {
21 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
22 | }
23 |
24 | h1.header {
25 | font-family: Montserrat, sans-serif;
26 | }
27 |
28 | /* Roa Logic Blue for Links */
29 | a {
30 | color: #050692;
31 | }
32 |
33 | /* Reduce left margin by 10px */
34 | header {
35 | padding: 34px 25px 22px 40px;
36 | background-color: #159957;
37 | background-image: linear-gradient(120deg, #155799, #159957);
38 | -webkit-border-radius: 4px;
39 | -moz-border-radius: 4px;
40 | border-radius: 4px;
41 | border: 0px;
42 | margin: 30px 25px;
43 | }
44 |
45 | footer {
46 | padding-left: 40px;
47 | }
48 |
49 | /* Recolour Buttons (Roa Logic Blue) */
50 | header li {
51 | background: #0506CF;
52 | background: -moz-linear-gradient(top, #0506CF 0%, #050692 100%);
53 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd));
54 | background: -webkit-linear-gradient(top, #0506CF 0%,#050692 100%);
55 | background: -o-linear-gradient(top, #0506CF 0%,#050692 100%);
56 | background: -ms-linear-gradient(top, #0506CF 0%,#050692 100%);
57 | background: linear-gradient(top, #0506CF 0%,#050692 100%);
58 |
59 | border-radius:4px;
60 | border:1px solid #0D0D0D;
61 |
62 | -webkit-box-shadow: inset 0px 1px 1px 0 rgba(0,102,204, 1);
63 | box-shadow: inset 0px 1px 1px 0 rgba(0,102,204, 1);
64 |
65 | }
66 | header li:hover {
67 | background: #0066CC;
68 | background: -moz-linear-gradient(top, #0066CC 0%, #004080 100%);
69 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd));
70 | background: -webkit-linear-gradient(top, #0066CC 0%,#004080 100%);
71 | background: -o-linear-gradient(top, #0066CC 0%,#004080 100%);
72 | background: -ms-linear-gradient(top, #0066CC 0%,#004080 100%);
73 | background: linear-gradient(top, #0066CC 0%,#004080 100%);
74 | }
75 |
76 | /* Format Logo in Header */
77 | p.logo {
78 | /*background-color: #F7F7F7;
79 | border: 1px solid #000;*/
80 | -webkit-border-radius: 4px;
81 | -moz-border-radius: 4px;
82 | border-radius: 4px;
83 | margin: 0px 10px 10px 0px;
84 | padding: 5px;
85 | }
86 |
87 | code, pre {
88 | font-size: 12px;
89 | }
90 |
--------------------------------------------------------------------------------
/rtl/verilog/LICENSE.txt:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////
2 | // //
3 | // ██████╗ ██████╗ █████╗ //
4 | // ██╔══██╗██╔═══██╗██╔══██╗ //
5 | // ██████╔╝██║ ██║███████║ //
6 | // ██╔══██╗██║ ██║██╔══██║ //
7 | // ██║ ██║╚██████╔╝██║ ██║ //
8 | // ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ //
9 | // ██╗ ██████╗ ██████╗ ██╗ ██████╗ //
10 | // ██║ ██╔═══██╗██╔════╝ ██║██╔════╝ //
11 | // ██║ ██║ ██║██║ ███╗██║██║ //
12 | // ██║ ██║ ██║██║ ██║██║██║ //
13 | // ███████╗╚██████╔╝╚██████╔╝██║╚██████╗ //
14 | // ╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝ //
15 | // //
16 | // Technology independent (inferrable) 1RW RAM //
17 | // //
18 | /////////////////////////////////////////////////////////////////
19 | // //
20 | // Copyright (C) 2014-2017 ROA Logic BV //
21 | // www.roalogic.com //
22 | // //
23 | // This source file may be used and distributed without //
24 | // restriction provided that this copyright statement is not //
25 | // removed from the file and that any derivative work contains //
26 | // the original copyright notice and the associated disclaimer.//
27 | // //
28 | // THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //
29 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //
30 | // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //
31 | // FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //
32 | // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //
33 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //
35 | // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //
36 | // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //
37 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //
38 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //
39 | // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //
40 | // POSSIBILITY OF SUCH DAMAGE. //
41 | // //
42 | /////////////////////////////////////////////////////////////////
43 |
44 |
--------------------------------------------------------------------------------
/_layouts/default.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {% seo %}
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
30 |
31 | {% if site.show_license %}
32 |
33 | {% endif %}
34 |
35 | {% if site.github.is_user_page %}
36 |
39 | {% endif %}
40 |
41 | {% if site.github.is_project_page %}
42 |
43 | {% endif %}
44 |
45 |
46 |
47 |
50 |
51 |
56 |
57 |
58 | {% if site.google_analytics %}
59 |
67 | {% endif %}
68 |
69 |
70 |
--------------------------------------------------------------------------------
/docs/Getting_Started.md:
--------------------------------------------------------------------------------
1 | # Getting Started
2 |
3 | ## Deliverables
4 |
5 | All IP is delivered as a zipped tarball, which can be unzipped with all common compression tools (like unzip, winrar, tar, …).
6 |
7 | The tarball contains a directory structure as outlined below:
8 |
9 | 
10 |
11 | The *doc* directory contains relevant documents like user guides, application notes, and datasheets.
12 |
13 | The *rtl* directory contains the actual IP design files. Depending on the license agreement the AHB-Lite PLIC is delivered as either encrypted Verilog-HDL or as plain SystemVerilog source files. Encrypted files have the extension “.enc.sv”, plain source files have the extension “.sv”. The files are encryption according to the IEEE-P1735 encryption standard. Encryption keys for Mentor Graphics (Modelsim, Questasim, Precision), Synplicity (Synplify, Synplify-Pro), and Aldec (Active-HDL, Riviera-Pro) are provided. As such there should be no issue targeting any existing FPGA technology.
14 |
15 | If any other synthesis or analysis tool is used then a plain source RTL delivery may be needed. A separate license agreement and NDA is required for such a delivery.
16 |
17 | The *bench* directory contains the (encrypted) source files for the testbench.
18 |
19 | The *sim* directory contains the files/structure to run the simulations. Section ''[Running the testbench](#running-the-testbench)'' provides for instructions on how to use the makefile.
20 |
21 | ## Running the testbench
22 |
23 | The IP comes with a dedicated testbench that tests all features of the design and finally runs a full random test. The testbench is started from a Makefile that is provided with the IP.
24 |
25 | The Makefile is located in the <*install\_dir*>/sim/rtlsim/run directory. The Makefile supports most commonly used simulators; Modelsim/Questasim, Cadence ncsim, Aldec Riviera, and Synopsys VCS.
26 |
27 | To start the simulation, enter the <*install\_dir*>/sim/rtlsim/run directory and type: **make <*simulator*>**. Where simulator is any of: msim (for modelsim/questasim), ncsim (for Cadence ncsim), riviera (for Aldec Riviera-Pro), or vcs (for Synopsys VCS). For example type **make msim** to start the testbench in Modelsim/Questasim.
28 |
29 | ### Self-checking testbench
30 |
31 | The testbenches is a self-checking testbench intended to be executed from the command line. There is no need for a GUI or a waveform viewer. Once the testbench completes it displays a summary and closes the simulator.
32 |
33 | ### Makefile setup
34 |
35 | The simulator is executed in its associated directory. Inside this directory is another Makefile that contains simulator specific commands to start and execute the simulation. The <*install\_dir*>/sim/rtlsim/run/Makefile enters the correct directory and calls the simulator specific Makefile.
36 |
37 | For example modelsim is executed in the <*install\_dir*>/sim/rtlsim/run/msim directory. Typing **make msim** loads the main Makefile, which then enters the msim sub-directory and calls its Makefile. This Makefile contains commands to compile the RTL and testbench sources with Modelsim, start the Modelsim simulator, and run the simulation.
38 |
39 | ### Makefile backup
40 |
41 | The <*install\_dir*>/sim/rtlsim/bin directory contains backups of the original Makefiles. It may be desirable to modify or extend the Makefiles or to completely clean the run directory. Use the backups to restore the original setup.
42 |
43 | ### No Makefile
44 |
45 | For users unfamiliar with Makefiles or those on systems that do not natively support make (e.g. Windows) a run.do file is provided that can be used with Modelsim/Questasim and Riviera-Pro.
--------------------------------------------------------------------------------
/docs/tex/configuration.tex:
--------------------------------------------------------------------------------
1 | \chapter{Configurations}
2 |
3 | \section{Core Parameters} \label{sec:core-parameters}
4 |
5 | The size and implementation style of the PLIC module is defined via HDL parameters as specified below:
6 |
7 | \begin{longtable}[c]{@{\extracolsep{\fill}}lccl@{}}
8 | \toprule
9 | \textbf{Parameter} & \textbf{Type} & \textbf{Default} & \textbf{Description}\\
10 | \midrule
11 | \endhead
12 | \emph{AHB Interface:}\\
13 | \texttt{HADDR\_SIZE} & Integer & 32 & Width of AHB Address Bus\\
14 | \texttt{HDATA\_SIZE} & Integer & 32 & Width of AHB Data Buses\\
15 | & & & \\
16 | \emph{PLIC Configuration:}\\
17 | \texttt{SOURCES} & Integer & 16 & Number of Interrupt Sources\\
18 | \texttt{TARGETS} & Integer & 4 & Number of Interrupt Targets\\
19 | \texttt{PRIORITIES} & Integer & 8 & Number of Priority Levels\\
20 | \texttt{MAX\_PENDING\_COUNT} & Integer & 8 & Max number of pending events\\
21 | \texttt{HAS\_THRESHOLD} & Integer & 1 & Is Threshold Implemented\\
22 | \texttt{HAS\_CONFIG\_REG} & Integer & 1 & Is Config Reg. Implemented\\
23 | \bottomrule
24 | \caption{Core Parameters}
25 | \label{tab:CoreParams}
26 | \end{longtable}
27 |
28 | \section{AHB Interface Parameters}
29 |
30 | \subsection{HADDR\_SIZE}
31 |
32 | The \texttt{HADDR\_SIZE} parameter specifies the address bus size to connect to the AHB-Lite based host. Valid values are 32 and 64. The default value is 32.
33 |
34 | \subsection{HDATA\_SIZE}
35 |
36 | The \texttt{HDATA\_SIZE} parameter specifies the data bus size to connect to the AHB-Lite based host. Valid values are 32 and 64. The default value is 32
37 |
38 | \hypertarget{SOURCES}{\subsection{SOURCES}\label{sec:SOURCES}}
39 |
40 | The \texttt{SOURCES} parameter defines the number of individual
41 | interrupt sources supported by the PLIC IP. The default value is 16. The
42 | minimum value is 1.
43 |
44 | \hypertarget{TARGETS}{\subsection{TARGETS}\label{sec:TARGETS}}
45 |
46 | The \texttt{TARGETS} parameter defines the number of targets supported
47 | by the PLIC IP. The default value is 4. The minimum value is 1.
48 |
49 | \pagebreak
50 |
51 | \section{PLIC Interface Parameters}
52 |
53 | \subsection{PRIORITIES}
54 |
55 | The PLIC IP supports prioritisation of individual interrupt sources. The \texttt{PRIORITIES} parameter defines the number of priority levels supported by the PLIC IP. The default value is 8. The minimum value is 1.
56 |
57 | \subsection{MAX\_PENDING\_COUNT}
58 |
59 | An interrupt source may generate multiple edge-triggered interrupts before being fully serviced by the target. To support this the PLIC is able to queue these requests up to a user-defined limit per interrupt source. This limit is defined by the parameter \texttt{MAX\_PENDING\_COUNT}.
60 |
61 | If the number of interrupts generated by a source exceeds the value of \texttt{MAX\_PENDING\_COUNT}, those additional interrupts are silently ignored.
62 |
63 | The default value of \texttt{MAX\_PENDING\_COUNT} is 8. The minimum value is 0.
64 |
65 | \subsection{HAS\_THRESHOLD}
66 |
67 | The PLIC module supports interrupt thresholds -- the masking of individual interrupt sources based on their priority level.
68 | The \texttt{HAS\_THRESHOLD} parameter defines if this capability is enabled.
69 |
70 | The default value is enabled (`1'). To disable, this parameter should be set to `0'.
71 |
72 | \subsection{HAS\_CONFIG\_REG}
73 |
74 | The PLIC module supports an optional Configuration Register, which is documented in section 0.
75 | The \texttt{HAS\_CONFIG\_REG} parameter defines if this capability is enabled.
76 |
77 | The default value is enabled (`1'). To disable, this parameter should be set to `0'.
78 |
--------------------------------------------------------------------------------
/sim/ahb3lite/bin/Makefile.riviera:
--------------------------------------------------------------------------------
1 | #####################################################################
2 | ## ,------. ,--. ,--. ##
3 | ## | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. ##
4 | ## | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' ##
5 | ## | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. ##
6 | ## `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' ##
7 | ## `---' ##
8 | ## Riviera-Pro Simulator Command File ##
9 | ## ##
10 | #####################################################################
11 | ## ##
12 | ## Copyright (C) 2017 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 OR ##
24 | ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ##
25 | ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ##
26 | ## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ##
27 | ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ##
28 | ## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ##
29 | ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR ##
30 | ## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ##
31 | ## SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ##
32 | ## ##
33 | #####################################################################
34 |
35 | all: sim
36 |
37 | #####################################################################
38 | # Make Targets
39 | #####################################################################
40 | SIM_OPTS=-c -ses -O2 "-threads 4" +notimingchecks
41 |
42 | .PHONY: sim simw clean
43 |
44 | LOG = $(TOP).log
45 |
46 | sim: vlog
47 | echo "--- Running sim"
48 | vsim $(SIM_OPTS) \
49 | -l $(LOG) $(TOP) \
50 | -do "run -all; quit" \
51 | $(foreach p, $(PARAMS), -g`echo $p | sed -r 's/(\w+)=([^0-9].*)/\1="\2"/'`)
52 |
53 |
54 | simw: vlog
55 | echo "--- Running sim"
56 | vsim $(SIM_OPTS) \
57 | -l $(LOG) $(TOP) +access +r \
58 | -do "log -mem -rec /$(TOP)/*; run -all; quit" \
59 | $(foreach p, $(PARAMS), -g`echo $p | sed -r 's/(\w+)=([^0-9].*)/\1="\2"/'`)
60 |
61 | clean:
62 | @rm -rf work *.log
63 |
64 |
65 |
66 | #####################################################################
67 | ## VHDL
68 | #####################################################################
69 |
70 |
71 | #####################################################################
72 | ## Verilog
73 | #####################################################################
74 | .PHONY: vlog
75 |
76 | vlog: work $(VLOG) $(VLOG_LIBS)
77 | echo "--- Running vlog"
78 | vlog -work work $(VLOG) \
79 | -sv2k9 -threads 3 \
80 | $(foreach d,$(DEFINES),+define+$d) \
81 | $(foreach d,$(INCDIRS),+incdir+$d) \
82 | $(foreach l,$(wildcard $(LIBDIRS)),-y $l) \
83 | +libext$(foreach e,$(LIBEXT),+$e) \
84 | $(foreach l,$(wildcard $(TECHLIBS)/*.v),-v $l)
85 | echo "--- vlog done"
86 |
87 |
88 | #####################################################################
89 | ## libraries
90 | #####################################################################
91 | work:
92 | vlib $@
93 |
--------------------------------------------------------------------------------
/sim/ahb3lite/bin/Makefile.include:
--------------------------------------------------------------------------------
1 | #####################################################################
2 | ## ,------. ,--. ,--. ##
3 | ## | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. ##
4 | ## | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' ##
5 | ## | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. ##
6 | ## `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' ##
7 | ## `---' ##
8 | ## RISC-V Platform-Level Interrupt Controller ##
9 | ## Simulator Include File ##
10 | ## ##
11 | #####################################################################
12 | ## ##
13 | ## Copyright (C) 2017 ROA Logic BV ##
14 | ## www.roalogic.com ##
15 | ## ##
16 | ## This source file may be used and distributed without ##
17 | ## restriction provided that this copyright statement is not ##
18 | ## removed from the file and that any derivative work contains ##
19 | ## the original copyright notice and the associated disclaimer. ##
20 | ## ##
21 | ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ##
22 | ## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ##
23 | ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ##
24 | ## FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR OR ##
25 | ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ##
26 | ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ##
27 | ## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ##
28 | ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ##
29 | ## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ##
30 | ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR ##
31 | ## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ##
32 | ## SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ##
33 | ## ##
34 | #####################################################################
35 |
36 | #####################################################################
37 | # Implementation details
38 | #####################################################################
39 | TECHNOLOGY =
40 | TARGET =
41 | busif = ahb3lite
42 |
43 |
44 | #####################################################################
45 | # OVL checker
46 | # This can be changed on the command line
47 | #####################################################################
48 | OVL_ASSERT = OFF
49 | OVL_INIT_MSG = ON
50 | STD_OVL_DIR = /projects/OVL/std_ovl
51 |
52 |
53 | #####################################################################
54 | # Design constants
55 | #####################################################################
56 | INCDIRS:=
57 | DEFINES:=
58 |
59 |
60 | #####################################################################
61 | # Design Sources
62 | #####################################################################
63 | DUT_SRC_DIR=$(ROOT_DIR)/rtl/verilog
64 | RTL_TOP = $(busif)_plic_top
65 | RTL_VLOG = $(ROOT_DIR)/submodules/$(busif)_pkg/rtl/verilog/$(busif)_pkg.sv \
66 | $(DUT_SRC_DIR)/core/plic_gateway.sv \
67 | $(DUT_SRC_DIR)/core/plic_cell.sv \
68 | $(DUT_SRC_DIR)/core/plic_priority_index.sv \
69 | $(DUT_SRC_DIR)/core/plic_target.sv \
70 | $(DUT_SRC_DIR)/core/plic_dynamic_registers.sv \
71 | $(DUT_SRC_DIR)/core/plic_core.sv \
72 | $(DUT_SRC_DIR)/$(busif)/$(busif)_plic_top.sv
73 | RTL_VHDL =
74 |
75 |
76 | #####################################################################
77 | # Testbench Sources
78 | #####################################################################
79 | TB_PREREQ=
80 | TB_TOP=testbench_top
81 | TB_SRC_DIR=$(ROOT_DIR)/bench/verilog/
82 |
83 | TB_VLOG = $(TB_SRC_DIR)/testbench_top.sv \
84 | $(TB_SRC_DIR)/test.sv \
85 | $(TB_SRC_DIR)/$(busif)_bfm.sv
86 | TB_VHDL =
87 |
--------------------------------------------------------------------------------
/bench/verilog/testbench_top.sv:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////
2 | // ,------. ,--. ,--. //
3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
7 | // `---' //
8 | // RISC-V Platform-Level Interrupt Controller Testbench (top) //
9 | // //
10 | /////////////////////////////////////////////////////////////////////
11 | // //
12 | // Copyright (C) 2017 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 | module testbench_top;
35 | parameter SOURCES = 35; //Number of interrupt sources
36 | parameter TARGETS = 4; //Number of interrupt targets
37 | parameter PRIORITIES = 7; //Number of priority levels
38 | parameter MAX_PENDING_COUNT = 8; //Number of 'event' counts
39 | parameter HAS_THRESHOLD = 1; //Has 'Priority' Threshold?
40 | parameter HAS_CONFIG_REG = 1; //Has 'config' register?
41 |
42 | parameter HADDR_SIZE = 16;
43 | parameter HDATA_SIZE = 32;
44 |
45 |
46 | /////////////////////////////////////////////////////////
47 | //
48 | // Variables
49 | //
50 | //AHB signals
51 | logic HSEL;
52 | logic [HADDR_SIZE -1:0] HADDR;
53 | logic [HDATA_SIZE -1:0] HWDATA;
54 | logic [HDATA_SIZE -1:0] HRDATA;
55 | logic HWRITE;
56 | logic [ 2:0] HSIZE;
57 | logic [ 2:0] HBURST;
58 | logic [ 3:0] HPROT;
59 | logic [ 1:0] HTRANS;
60 | logic HMASTLOCK;
61 | logic HREADY;
62 | logic HREADYOUT;
63 | logic HRESP;
64 |
65 | //Interrupt signals
66 | logic [SOURCES -1:0] src;
67 | logic [TARGETS -1:0] irq;
68 |
69 |
70 | /////////////////////////////////////////////////////////
71 | //
72 | // Clock & Reset
73 | //
74 | bit HCLK, HRESETn;
75 | initial begin : gen_HCLK
76 | HCLK <= 1'b0;
77 | forever #10 HCLK = ~ HCLK;
78 | end : gen_HCLK
79 |
80 | initial begin : gen_HRESETn;
81 | HRESETn = 1'b1;
82 | //ensure falling edge of HRESETn
83 | #10;
84 | HRESETn = 1'b0;
85 | #32;
86 | HRESETn = 1'b1;
87 | end : gen_HRESETn;
88 |
89 |
90 | /////////////////////////////////////////////////////////
91 | //
92 | // Instantiate the TB and DUT
93 | //
94 | test #(
95 | .HADDR_SIZE ( HADDR_SIZE ),
96 | .HDATA_SIZE ( HDATA_SIZE ),
97 | .SOURCES ( SOURCES ),
98 | .TARGETS ( TARGETS ),
99 | .PRIORITIES ( PRIORITIES ),
100 | .MAX_PENDING_COUNT ( MAX_PENDING_COUNT ),
101 | .HAS_THRESHOLD ( HAS_THRESHOLD ),
102 | .HAS_CONFIG_REG ( HAS_CONFIG_REG ))
103 | tb (
104 | .*
105 | );
106 |
107 |
108 | ahb3lite_plic_top #(
109 | .HADDR_SIZE ( HADDR_SIZE ),
110 | .HDATA_SIZE ( HDATA_SIZE ),
111 |
112 | .SOURCES ( SOURCES ),
113 | .TARGETS ( TARGETS ),
114 | .PRIORITIES ( PRIORITIES ),
115 | .MAX_PENDING_COUNT ( MAX_PENDING_COUNT ),
116 | .HAS_THRESHOLD ( HAS_THRESHOLD ),
117 | .HAS_CONFIG_REG ( HAS_CONFIG_REG )
118 | )
119 | dut (
120 | .*
121 | );
122 |
123 | assign HREADY = HREADYOUT;
124 |
125 | endmodule : testbench_top
126 |
--------------------------------------------------------------------------------
/rtl/verilog/core/plic_cell.sv:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////
2 | // ,------. ,--. ,--. //
3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
7 | // `---' //
8 | // RISC-V Platform-Level Interrupt Controller //
9 | // //
10 | /////////////////////////////////////////////////////////////////////
11 | // //
12 | // Copyright (C) 2017 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 OR //
24 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, //
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT //
26 | // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; //
27 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) //
28 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN //
29 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR //
30 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS //
31 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
32 | // //
33 | /////////////////////////////////////////////////////////////////////
34 |
35 | // +FHDR - Semiconductor Reuse Standard File Header Section -------
36 | // FILE NAME : plic_cell.sv
37 | // DEPARTMENT :
38 | // AUTHOR : rherveille
39 | // AUTHOR'S EMAIL :
40 | // ------------------------------------------------------------------
41 | // RELEASE HISTORY
42 | // VERSION DATE AUTHOR DESCRIPTION
43 | // 1.0 2017-07-01 rherveille initial release
44 | // ------------------------------------------------------------------
45 | // KEYWORDS : RISC-V PLATFORM LEVEL INTERRUPT CONTROLLER - PLIC
46 | // ------------------------------------------------------------------
47 | // PURPOSE : One source-target combination. Single cell of the
48 | // source-target matrix.
49 | // ------------------------------------------------------------------
50 | // PARAMETERS
51 | // PARAM NAME RANGE DESCRIPTION DEFAULT UNITS
52 | // ID 1+ ID (source number) 1
53 | // SOURCES 1+ No. of interupt sources 8
54 | // PRIORITIES 1+ No. of priority levels 8
55 | // ------------------------------------------------------------------
56 | // REUSE ISSUES
57 | // Reset Strategy : none
58 | // Clock Domains : none, asynchronous block
59 | // Critical Timing :
60 | // Test Features :
61 | // Asynchronous I/F : Fully asynchronous block
62 | // Scan Methodology : na
63 | // Instantiations : none
64 | // Synthesizable (y/n) : Yes
65 | // Other : End-points (registers) are in the
66 | // plic_target module
67 | // -FHDR-------------------------------------------------------------
68 |
69 | module plic_cell #(
70 | parameter ID = 1,
71 | parameter SOURCES = 8,
72 | parameter PRIORITIES = 7,
73 |
74 | //These should be localparams, but that's not supported by all tools yet
75 | parameter SOURCES_BITS = $clog2(SOURCES +1), //0=reserved
76 | parameter PRIORITY_BITS = $clog2(PRIORITIES)
77 | )
78 | (
79 | input rst_ni, //Asynchronous active low reset
80 | input clk_i, //System clock
81 |
82 | //Interrupt Request
83 | input ip_i, //Interrupt pending
84 | input ie_i, //Interrupt Enable
85 | input [PRIORITY_BITS-1:0] priority_i, //Interrupt priority
86 |
87 | output reg [SOURCES_BITS -1:0] id_o, //Pending interrupt ID
88 | output reg [PRIORITY_BITS-1:0] priority_o //Pending interrupt priority
89 | );
90 | //////////////////////////////////////////////////////////////////
91 | //
92 | // Module Body
93 | //
94 |
95 | always @(posedge clk_i,negedge rst_ni)
96 | if (!rst_ni ) priority_o <= 0;
97 | else if ( ip_i && ie_i) priority_o <= priority_i;
98 | else priority_o <= 0;
99 |
100 | always @(posedge clk_i,negedge rst_ni)
101 | if (!rst_ni ) id_o <= 0;
102 | else if ( ip_i && ie_i) id_o <= ID;
103 | else id_o <= 0;
104 |
105 | endmodule : plic_cell
106 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: BSD License Agreement
3 | ---
4 | # BSD License Agreement
5 |
6 | PLEASE CAREFULLY REVIEW THE FOLLOWING TERMS AND CONDITIONS BEFORE DOWNLOADING AND USING THE LICENSED MATERIALS. THIS LICENSE AGREEMENT (“AGREEMENT”) IS A LEGAL AGREEMENT BETWEEN YOU (EITHER A SINGLE INDIVIDUAL, OR A SINGLE LEGAL ENTITY) (“YOU”) AND ROA LOGIC BV (“ROA LOGIC”) COVERING THE PRODUCTS OR SERVICES YOU PURCHASE FROM ROA LOGIC.
7 |
8 | By downloading and/or using or installing products from Roa Logic you automatically agree to and are bound by the terms and conditions of this agreement.
9 |
10 | ## 1. DEFINITIONS
11 |
12 | “Intellectual Property” means any or all of the following and all rights in, arising out of, or associated with:
13 |
14 | 1. All inventions (whether patentable or not), invention disclosures, improvements, trade secrets, proprietary information, know how, technology, algorithms, techniques, methods, devices, technical data, customer lists, and all documentation embodying or evidencing any of the foregoing;
15 | 2. All computer software, source codes, object codes, firmware, development tools, files, records, data, and all media on which any of the foregoing is recorded
16 |
17 | “Product” means an Intellectual Property block consisting of, but not limited to, Verilog, VHDL, and/or SystemVerilog design files, specifications, block diagrams and documentation.
18 |
19 | “Physical Implementation” means any implementation in programmable or non-programmable technologies including, but not limited to Field Programmable Gate Arrays (FPGAs), Complex Programmable Logic Devices (CPLDs), Application Specific Integrated Circuits (ASICs), Application Specific Standard Products (ASSPs)
20 |
21 | “Silicon Device(s)” means any customer Physical Implementation containing a unique part number.
22 |
23 | “You” the opposite contract party as referred to in article 6:231, subsection c, of the Dutch Civil Code, being the party to whom an offer is made by Roa Logic, or with whom an agreement is concluded by Roa Logic, or to whom the Product is supplied.
24 |
25 | ## 2. LICENSE TO USE
26 |
27 | Roa Logic hereby grants you the following limited, non-exclusive, no-charge, and royalty-free licenses to use, modify, and distribute the Product:
28 |
29 | 1. Copyright license
30 | 2. Patent license, where such license only applies to those patent claims licensable by Roa Logic.
31 |
32 | Specifically you are allowed to:
33 |
34 | 1. Use the Product in your design to create, simulate, implement, manufacture, use, and sell a Silicon Device;
35 | 2. Distribute the Product and/or Silicon Device, provided the original disclaimer and copyright notice are retained and this Agreement is part of the distribution.
36 |
37 | ## 3. OWNERSHIP
38 |
39 | The Product, its documentation, and any associated material is owned by Roa Logic and is protected by copyright and other intellectual property right laws.
40 |
41 | Any modification or addition to the Product, documentation, and any associated materials or derivatives thereof, that You intentionally submit to Roa Logic for inclusion in the Product will become part of the Product and thus owned and copyrighted by Roa Logic. By submitting any material for inclusion you wave any ownership, copyright, and patent rights and claims for the use of the submitted material in the Product.
42 |
43 | “Submitting” means any form of electronic, verbal, or written communication sent to Roa Logic or its representatives, including, but not limited to, email, mailing lists, source repositories, and issue tracking systems for the purpose of discussing and improving the Product.
44 |
45 | You shall not remove any copyright, disclaimers, or other notices from any parts of the Product.
46 |
47 | ## 4. DISCLAIMER OF WARRANTY
48 |
49 | The Product is provided “AS IS”. Roa Logic has no obligation to provide maintenance or support services in connection with the Product.
50 |
51 | ROA LOGIC DISCLAIMS ALL WARRANTIES, CONDITIONS AND REPRESENTATIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, THOSE RELATED TO MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, SATISFACTORY QUALITY, ACCURACY OR COMPLETENESS OR RESULTS, CONFORMANCE WITH DESCRIPTION, AND NON-INFRINGEMENT.
52 |
53 | ## 5. LIMITATION OF LIABILITY
54 |
55 | TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL ROA LOGIC BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY INDIRECT, SPECIAL, CONSEQUENTIAL OR INCIDENTAL DAMAGES WHATSOEVER (INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR LOSS OF PROFIT, BUSINESS INTERRUPTIONS OR LOSS OF INFORMATION) ARISING OUT OF THE USE OR INABILITY TO USE THE PRODUCT WHETHER BASED ON A CLAIM UNDER CONTRACT, TORT OR OTHER LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
56 |
57 | ## 6. APPLICABLE LAW AND CHOICE OF FORUM
58 |
59 | All agreements and contracts between you and Roa Logic, which these conditions are applicable to, shall be governed by Dutch law with the exclusion of the uniform UN Convention on Contracts for the International Sale of Goods (CISG) and other bilateral or multilateral treaties for the purpose of unifying international sales.
60 |
61 | The competent courts in the district where Roa Logic has its registered office in the Netherlands has jurisdiction over all disputes concerning rights and obligations associated with the contractual relations.
62 |
63 | Conversion: If any clause or sentence of this agreement is held by a court of law to be illegal or unenforceable, the remaining provisions of the agreement remain in effect. The failure of Roa Logic to enforce any of the provisions in the agreement does not constitute a waiver of Roa Logic’s rights to enforce any provision of the agreement in the future.
64 |
--------------------------------------------------------------------------------
/docs/tex/preamble.tex:
--------------------------------------------------------------------------------
1 | %define new document type
2 |
3 | \usepackage[utf8]{inputenc}
4 | \usepackage[english]{babel}
5 |
6 | % Define Roa Logic Colour Scheme
7 | \usepackage[table]{xcolor}
8 | \newcommand{\headlinecolor}{\normalcolor}
9 | \definecolor{rlchapter}{HTML}{3D5986}
10 | \definecolor{rlsection}{HTML}{5B80B8}
11 | \definecolor{rltable}{HTML}{D5DFED}
12 |
13 | % Load packages
14 | \usepackage{graphicx,grffile} % Graphics support
15 | \usepackage{geometry}
16 | \usepackage{array}
17 | \usepackage{xcolor}
18 | \usepackage{placeins}
19 | \usepackage{multirow}
20 | \usepackage{float}
21 | \usepackage[shadow]{todonotes}
22 | \usepackage{lmodern} % Font Library
23 | \usepackage{amssymb,amsmath} % Math Fonts
24 | \usepackage{ifxetex,ifluatex}
25 | \usepackage{longtable} % Long table supprot
26 | \usepackage{vmargin} % Margin control
27 | \usepackage{tabularx} % Table support
28 | \usepackage{booktabs} % For \toprule, \midrule and \bottomrule
29 | \usepackage{csvsimple} % Import CSV files
30 | \usepackage{layout} % Show summary of page layout
31 | \usepackage{hyperref} % Hyperlink support
32 | \usepackage{titlesec} %Headings Styliser
33 | \usepackage{fancyhdr} % Header & Footer control
34 | \usepackage{comment}
35 | \usepackage[olditem,oldenum]{paralist}
36 | \usepackage{titling}
37 |
38 | % Setup margins & page style
39 |
40 | %\setlength{\topmargin}{-0.5in}
41 | %\setlength{\textheight}{9in}
42 | %\setlength{\oddsidemargin}{0in}
43 | %\setlength{\evensidemargin}{0in}
44 | %\setlength{\textwidth}{6.5in}
45 |
46 | % Page Layout Control
47 |
48 | % Hyperlink formatting
49 | \hypersetup{
50 | colorlinks=true,
51 | linkcolor=blue,
52 | filecolor=magenta,
53 | urlcolor=blue,
54 | }
55 |
56 | \urlstyle{same}
57 |
58 | % Font & Colour control
59 | \renewcommand{\familydefault}{\rmdefault}
60 | \renewcommand{\headlinecolor}{\color{rlcolor}}
61 |
62 |
63 | % Heading Formats
64 | \titleformat{\chapter}
65 | {\normalfont\Huge\bfseries\color{rlchapter}\sffamily}{\thechapter.}{1em}{}[{\titlerule[0.8pt]}]
66 |
67 | \titleformat{\section}
68 | {\color{rlsection}\sffamily\LARGE\bfseries}{\thesection}{1em}{}
69 |
70 | \titleformat{\subsection}
71 | {\color{rlsection}\sffamily\large\bfseries}{\thesubsection}{1em}{}
72 |
73 | \titleformat{\subsubsection}
74 | {\color{rlsection}\sffamily\large\bfseries}{\thesubsubsection}{1em}{}
75 |
76 | %\titlespacing*{\chapter} {0pt}{1.5ex plus 1ex minus .2ex}{2.3ex plus .2ex}
77 | \titlespacing*{\chapter} {0pt}{-50pt}{20pt}
78 | \titlespacing*{\section} {0pt}{1.5ex plus 1ex minus .2ex}{2.3ex plus .2ex}
79 | \titlespacing*{\subsection} {0pt}{1.25ex plus 1ex minus .2ex}{1.5ex plus .2ex}
80 | \titlespacing*{\subsubsection}{0pt}{1.25ex plus 1ex minus .2ex}{1.5ex plus .2ex}
81 | \titlespacing*{\paragraph} {0pt}{1.25ex plus 1ex minus .2ex}{0.5em}
82 | \titlespacing*{\subparagraph} {\parindent}{3.25ex plus 1ex minus .2ex}{0.5em}
83 |
84 | \setlength{\headheight}{13.6pt} % Fix spurious build warnings
85 |
86 | % Paragraph formatting
87 | %\setlength{\parindent}{1em}
88 | \setlength{\parskip}{0.5em}
89 |
90 | % Long table formatting
91 | % \newcolumntype{L}[1]{>{\raggedright\arraybackslash}p{#1}}
92 | % \newcolumntype{C}[1]{>{\centering\arraybackslash}p{#1}}
93 | % \newcolumntype{R}[1]{>{\raggedleft\arraybackslash}p{#1}}
94 | \usepackage{subfig}
95 | \captionsetup{belowskip=0pt,aboveskip=7pt}
96 |
97 | % Pad All Table Rows
98 | % \renewcommand{\arraystretch}{1.2}
99 |
100 |
101 | % Center all Floats (Figs & Tables)
102 | \makeatletter
103 | \g@addto@macro\@floatboxreset\centering
104 | \makeatother
105 |
106 | %
107 | % Custom Commands
108 | %
109 |
110 | % Define ToDo Colours
111 | \presetkeys{todonotes}{color=blue!30, backgroundcolor=white, bordercolor=black, figcolor=white}{}
112 |
113 | % Commands for register format figures.
114 |
115 | % New column types to use in tabular environment for instruction formats.
116 | % Allocate 0.18in per bit.
117 | \newcolumntype{I}{>{\centering\arraybackslash}p{0.18in}}
118 | % Two-bit centered column.
119 | \newcolumntype{W}{>{\centering\arraybackslash}p{0.36in}}
120 | % Three-bit centered column.
121 | \newcolumntype{F}{>{\centering\arraybackslash}p{0.54in}}
122 | % Four-bit centered column.
123 | \newcolumntype{Y}{>{\centering\arraybackslash}p{0.72in}}
124 | % Five-bit centered column.
125 | \newcolumntype{R}{>{\centering\arraybackslash}p{0.9in}}
126 | % Six-bit centered column.
127 | \newcolumntype{S}{>{\centering\arraybackslash}p{1.08in}}
128 | % Seven-bit centered column.
129 | \newcolumntype{O}{>{\centering\arraybackslash}p{1.26in}}
130 | % Eight-bit centered column.
131 | \newcolumntype{E}{>{\centering\arraybackslash}p{1.44in}}
132 | % Ten-bit centered column.
133 | \newcolumntype{T}{>{\centering\arraybackslash}p{1.8in}}
134 | % Twelve-bit centered column.
135 | \newcolumntype{M}{>{\centering\arraybackslash}p{2.2in}}
136 | % Sixteen-bit centered column.
137 | \newcolumntype{K}{>{\centering\arraybackslash}p{2.88in}}
138 | % Twenty-bit centered column.
139 | \newcolumntype{U}{>{\centering\arraybackslash}p{3.6in}}
140 | % Twenty-bit centered column.
141 | \newcolumntype{L}{>{\centering\arraybackslash}p{3.6in}}
142 | % Twenty-five-bit centered column.
143 | \newcolumntype{J}{>{\centering\arraybackslash}p{4in}} % RL Change
144 |
145 | \newcommand{\instbit}[1]{\mbox{\scriptsize #1}}
146 | \newcommand{\instbitrange}[2]{~\instbit{#1} \hfill \instbit{#2}~}
147 | \newcommand{\reglabel}[1]{\hfill \texttt{#1}\hfill\ }
148 |
149 | \newcommand{\wiri}{\textbf{WIRI}}
150 | \newcommand{\wpri}{\textbf{WPRI}}
151 | \newcommand{\wlrl}{\textbf{WLRL}}
152 | \newcommand{\warl}{\textbf{WARL}}
153 |
154 |
155 |
--------------------------------------------------------------------------------
/rtl/verilog/core/plic_target.sv:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////
2 | // ,------. ,--. ,--. //
3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
7 | // `---' //
8 | // RISC-V Platform-Level Interrupt Controller //
9 | // //
10 | /////////////////////////////////////////////////////////////////////
11 | // //
12 | // Copyright (C) 2017 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 OR //
24 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, //
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT //
26 | // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; //
27 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) //
28 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN //
29 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR //
30 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS //
31 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
32 | // //
33 | /////////////////////////////////////////////////////////////////////
34 |
35 | // +FHDR - Semiconductor Reuse Standard File Header Section -------
36 | // FILE NAME : plic_target.sv
37 | // DEPARTMENT :
38 | // AUTHOR : rherveille
39 | // AUTHOR'S EMAIL :
40 | // ------------------------------------------------------------------
41 | // RELEASE HISTORY
42 | // VERSION DATE AUTHOR DESCRIPTION
43 | // 1.0 2017-07-01 rherveille initial release
44 | // ------------------------------------------------------------------
45 | // KEYWORDS : RISC-V PLATFORM LEVEL INTERRUPT CONTROLLER - PLIC
46 | // ------------------------------------------------------------------
47 | // PURPOSE : PLIC Target
48 | // Generates Interrupt Request and ID for each target
49 | // ------------------------------------------------------------------
50 | // PARAMETERS
51 | // PARAM NAME RANGE DESCRIPTION DEFAULT UNITS
52 | // SOURCES 1+ No. of interupt sources 8
53 | // PRIORITIES 1+ No. of priority levels 8
54 | // ------------------------------------------------------------------
55 | // REUSE ISSUES
56 | // Reset Strategy : external asynchronous active low; rst_ni
57 | // Clock Domains : 1, clk, rising edge
58 | // Critical Timing :
59 | // Test Features : na
60 | // Asynchronous I/F : no
61 | // Scan Methodology : na
62 | // Instantiations : plic_priority_index
63 | // Synthesizable (y/n) : Yes
64 | // Other :
65 | // -FHDR-------------------------------------------------------------
66 |
67 | module plic_target #(
68 | parameter SOURCES = 8,
69 | parameter PRIORITIES = 7,
70 |
71 | //These should be localparams, but that's not supported by all tools yet
72 | parameter SOURCES_BITS = $clog2(SOURCES +1), //0=reserved
73 | parameter PRIORITY_BITS = $clog2(PRIORITIES)
74 | )
75 | (
76 | input rst_ni, //Active low asynchronous reset
77 | clk_i, //System clock
78 |
79 | input [SOURCES_BITS -1:0] id_i [SOURCES], //Interrupt source
80 | input [PRIORITY_BITS-1:0] priority_i [SOURCES], //Interrupt Priority
81 |
82 | input [PRIORITY_BITS-1:0] threshold_i, //Interrupt Priority Threshold
83 |
84 | output reg ireq_o, //Interrupt Request (EIP)
85 | output reg [SOURCES_BITS -1:0] id_o //Interrupt ID
86 | );
87 | //////////////////////////////////////////////////////////////////
88 | //
89 | // Constant
90 | //
91 |
92 |
93 | //////////////////////////////////////////////////////////////////
94 | //
95 | // Variables
96 | //
97 | logic [SOURCES_BITS -1:0] id;
98 | logic [PRIORITY_BITS-1:0] pr;
99 |
100 |
101 | //////////////////////////////////////////////////////////////////
102 | //
103 | // Module Body
104 | //
105 |
106 | /** Select highest priority pending interrupt
107 | */
108 | plic_priority_index #(
109 | .SOURCES ( SOURCES ),
110 | .PRIORITIES ( PRIORITIES ),
111 | .HI ( SOURCES -1 ),
112 | .LO ( 0 )
113 | )
114 | priority_index_tree (
115 | .priority_i ( priority_i ),
116 | .idx_i ( id_i ),
117 | .priority_o ( pr ),
118 | .idx_o ( id )
119 | );
120 |
121 |
122 | /** Generate output
123 | */
124 | always @(posedge clk_i,negedge rst_ni)
125 | if (!rst_ni ) ireq_o <= 1'b0;
126 | else if ( pr > threshold_i) ireq_o <= 1'b1;
127 | else ireq_o <= 1'b0;
128 |
129 | always @(posedge clk_i)
130 | id_o <= id;
131 |
132 | endmodule : plic_target
133 |
--------------------------------------------------------------------------------
/sim/ahb3lite/bin/Makefile:
--------------------------------------------------------------------------------
1 | #####################################################################
2 | ## ,------. ,--. ,--. ##
3 | ## | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. ##
4 | ## | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' ##
5 | ## | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. ##
6 | ## `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' ##
7 | ## `---' ##
8 | ## Main Simulation Makefile ##
9 | ## ##
10 | #####################################################################
11 | ## ##
12 | ## Copyright (C) 2017 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 OR ##
24 | ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ##
25 | ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ##
26 | ## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ##
27 | ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ##
28 | ## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ##
29 | ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR ##
30 | ## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ##
31 | ## SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ##
32 | ## ##
33 | #####################################################################
34 |
35 | all: Makefile
36 |
37 | SIMULATORS = ncsim vcs silos icarus riviera
38 | LINTERS = $(addsuffix _lint, $(SIMULATORS))
39 | SIMWAVES = $(addsuffix _waves, $(SIMULATORS))
40 |
41 | MS = -s
42 |
43 | ROOT_DIR=../../..
44 |
45 | #####################################################################
46 | #
47 | # Regression variables
48 | #
49 | #####################################################################
50 | #add regression variables here
51 |
52 |
53 | #####################################################################
54 | #
55 | # Sources
56 | #
57 | #####################################################################
58 | -include Makefile.include
59 |
60 |
61 | #####################################################################
62 | #
63 | # Misc Variables
64 | #
65 | #####################################################################
66 | INCDIRS:=$(INCDIRS)
67 | DEFINES:=$(DEFINES)
68 |
69 | shell=/bin/sh
70 |
71 |
72 | #####################################################################
73 | #
74 | # OVL
75 | #
76 | #####################################################################
77 | ifeq ($(OVL_ASSERT),ON)
78 | INCDIRS +=$(STD_OVL_DIR)
79 | DEFINES +=OVL_ASSERT_ON
80 | LIBDIRS +=$(STD_OVL_DIR)
81 | LIBEXT +=.vlib
82 |
83 | ifeq ($(OVL_INIT_MSG),ON)
84 | DEFINES +=OVL_INIT_MSG
85 | endif
86 | endif
87 |
88 |
89 | #####################################################################
90 | #
91 | # Make Targets
92 | #
93 | #####################################################################
94 | .PHONY: $(SIMULATORS) $(LINTERS) $(SIMWAVES)
95 | $(SIMULATORS): % : %/Makefile $(TB_PREREQ)
96 | @$(MAKE) $(MS) -C $@ sim \
97 | VLOG="$(abspath $(RTL_VLOG) $(TB_VLOG))" \
98 | TECHLIBS="$(TECHLIBS)" \
99 | LIBDIRS="$(LIBDIRS)" \
100 | LIBEXT="$(LIBEXT)" \
101 | VHDL="$(abspath $(RTL_VHDL) $(TB_VHDL))" \
102 | INCDIRS="$(abspath $(INCDIRS))" \
103 | DEFINES="$(DEFINES)" \
104 | TOP=$(TB_TOP) \
105 | LOG=$(LOG) PARAMS="$(PARAMS)"
106 |
107 | $(SIMWAVES): %_waves : %/Makefile $(TB_PREREQ)
108 | @$(MAKE) $(MS) -C $(subst _waves,,$@) simw \
109 | VLOG="$(abspath $(RTL_VLOG) $(TB_VLOG))" \
110 | TECHLIBS="$(TECHLIBS)" \
111 | LIBDIRS="$(LIBDIRS)" \
112 | LIBEXT="$(LIBEXT)" \
113 | VHDL="$(abspath $(RTL_VHDL) $(TB_VHDL))" \
114 | INCDIRS="$(abspath $(INCDIRS))" \
115 | DEFINES="$(DEFINES)" \
116 | TOP=$(TB_TOP) \
117 | LOG=$(LOG) PARAMS="$(PARAMS)"
118 |
119 | $(LINTERS): %_lint : %/Makefile $(TB_PREREQ)
120 | @$(MAKE) $(MS) -C $(subst _lint,,$@) lint \
121 | VLOG="$(abspath $(RTL_VLOG))" \
122 | VHDL="$(abspath $(RTL_VHDL))" \
123 | INCDIRS="$(abspath $(INCDIRS))" \
124 | DEFINES="$(DEFINES)" \
125 | TOP=$(RTL_TOP)
126 |
127 |
128 | .PHONY: bps
129 | bps: % : %/Makefile
130 | @$(MAKE) $(MS) -C $@ $@ \
131 | VLOG="$(abspath $(RTL_VLOG))" \
132 | VHDL="$(abspath $(RTL_VHDL))" \
133 | TOP=$(RTL_TOP)
134 |
135 |
136 | .PHONY: clean distclean mrproper
137 | clean:
138 | @for f in $(wildcard *); do \
139 | if test -d $$f; then $(MAKE) -C $$f clean; fi \
140 | done
141 |
142 | distclean:
143 | @rm -rf $(SIMULATORS) Makefile.include $(TB_PREREQ)
144 |
145 | mrproper:
146 | @rm -rf *
147 |
148 |
149 | #####################################################################
150 | #
151 | # Make simulation structure
152 | #
153 | #####################################################################
154 | Makefile.include:
155 | @cp ../bin/Makefile.include .
156 |
157 | %/Makefile:
158 | @mkdir -p $*
159 | @cp ../bin/Makefile.$* $@
160 |
161 | $(TB_PREREQ):
162 | @cp ../bin/$@ $@
163 |
--------------------------------------------------------------------------------
/rtl/verilog/core/plic_priority_index.sv:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////
2 | // ,------. ,--. ,--. //
3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
7 | // `---' //
8 | // RISC-V Platform-Level Interrupt Controller //
9 | // //
10 | /////////////////////////////////////////////////////////////////////
11 | // //
12 | // Copyright (C) 2017 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 OR //
24 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, //
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT //
26 | // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; //
27 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) //
28 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN //
29 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR //
30 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS //
31 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
32 | // //
33 | /////////////////////////////////////////////////////////////////////
34 |
35 | // +FHDR - Semiconductor Reuse Standard File Header Section -------
36 | // FILE NAME : plic_priority_index.sv
37 | // DEPARTMENT :
38 | // AUTHOR : rherveille
39 | // AUTHOR'S EMAIL :
40 | // ------------------------------------------------------------------
41 | // RELEASE HISTORY
42 | // VERSION DATE AUTHOR DESCRIPTION
43 | // 1.0 2017-11-14 rherveille initial release
44 | // ------------------------------------------------------------------
45 | // KEYWORDS : RISC-V PLATFORM LEVEL INTERRUPT CONTROLLER - PLIC
46 | // ------------------------------------------------------------------
47 | // PURPOSE : PLIC Target - Priority Index
48 | // Builds a binary tree to search for the highest priority
49 | // and its associated ID
50 | // ------------------------------------------------------------------
51 | // PARAMETERS
52 | // PARAM NAME RANGE DESCRIPTION DEFAULT UNITS
53 | // SOURCES 1+ No. of interupt sources 8
54 | // PRIORITIES 1+ No. of priority levels 8
55 | // ------------------------------------------------------------------
56 | // REUSE ISSUES
57 | // Reset Strategy : none
58 | // Clock Domains : none
59 | // Critical Timing :
60 | // Test Features : na
61 | // Asynchronous I/F : yes
62 | // Scan Methodology : na
63 | // Instantiations : Itself (recursive)
64 | // Synthesizable (y/n) : Yes
65 | // Other :
66 | // -FHDR-------------------------------------------------------------
67 |
68 | module plic_priority_index #(
69 | parameter SOURCES = 16,
70 | parameter PRIORITIES = 7,
71 | parameter HI = 16,
72 | parameter LO = 0,
73 |
74 | //These should be localparams, but that's not supported by all tools yet
75 | parameter SOURCES_BITS = $clog2(SOURCES +1), //0=reserved
76 | parameter PRIORITY_BITS = $clog2(PRIORITIES)
77 | )
78 | (
79 | input [PRIORITY_BITS-1:0] priority_i [SOURCES], //Interrupt Priority
80 | input [SOURCES_BITS -1:0] idx_i [SOURCES],
81 | output [PRIORITY_BITS-1:0] priority_o,
82 | output [SOURCES_BITS -1:0] idx_o
83 | );
84 |
85 | //////////////////////////////////////////////////////////////////
86 | //
87 | // Variables
88 | //
89 |
90 | logic [PRIORITY_BITS-1:0] priority_hi, priority_lo;
91 | logic [SOURCES_BITS -1:0] idx_hi, idx_lo;
92 |
93 | //initial if (HI-LO>1) $display ("HI=%0d, LO=%0d -> hi(%0d,%0d) lo(%0d,%0d)", HI, LO, HI, HI-(HI-LO)/2, LO+(HI-LO)/2, LO);
94 |
95 | //////////////////////////////////////////////////////////////////
96 | //
97 | // Module Body
98 | //
99 |
100 | generate
101 | if (HI - LO > 1)
102 | begin
103 | plic_priority_index #(
104 | .SOURCES ( SOURCES ),
105 | .PRIORITIES ( PRIORITIES ),
106 | .HI ( LO + (HI-LO)/2 ),
107 | .LO ( LO )
108 | )
109 | lo (
110 | .priority_i ( priority_i ),
111 | .idx_i ( idx_i ),
112 | .priority_o ( priority_lo ),
113 | .idx_o ( idx_lo )
114 | );
115 |
116 | plic_priority_index #(
117 | .SOURCES ( SOURCES ),
118 | .PRIORITIES ( PRIORITIES ),
119 | .HI ( HI ),
120 | .LO ( HI - (HI-LO)/2 )
121 | ) hi
122 | (
123 | .priority_i ( priority_i ),
124 | .idx_i ( idx_i ),
125 | .priority_o ( priority_hi ),
126 | .idx_o ( idx_hi )
127 | );
128 | end
129 | else
130 | begin
131 | assign priority_lo = priority_i[LO];
132 | assign priority_hi = priority_i[HI];
133 | assign idx_lo = idx_i [LO];
134 | assign idx_hi = idx_i [HI];
135 | end
136 | endgenerate
137 |
138 | assign priority_o = priority_hi > priority_lo ? priority_hi : priority_lo;
139 | assign idx_o = priority_hi > priority_lo ? idx_hi : idx_lo;
140 |
141 | endmodule : plic_priority_index
142 |
143 |
--------------------------------------------------------------------------------
/docs/tex/interfaces-ahblite.tex:
--------------------------------------------------------------------------------
1 | \section{AHB-Lite Interface}
2 |
3 | The AHB-Lite interface is a regular AHB-Lite slave port. All signals are
4 | supported. See the
5 | \emph{\href{https://www.arm.com/products/system-ip/amba-specifications}{AMBA
6 | 3 AHB-Lite Specification}} for a complete description of the signals.
7 |
8 | \begin{longtable}[c]{@{\extracolsep{\fill}}cccl@{}}
9 | \toprule
10 | \textbf{Port} & \textbf{Size} & \textbf{Direction} & \textbf{Description}\\
11 | \midrule
12 | \endhead
13 | \texttt{HRESETn} & 1 & Input & Asynchronous active low reset\\
14 | \texttt{HCLK} & 1 & Input & Clock Input\\
15 | \texttt{HSEL} & 1 & Input & Bus Select\\
16 | \texttt{HTRANS} & 2 & Input & Transfer Type\\
17 | \texttt{HADDR} & \texttt{HADDR\_SIZE} & Input & Address Bus\\
18 | \texttt{HWDATA} & \texttt{HDATA\_SIZE} & Input & Write Data Bus\\
19 | \texttt{HRDATA} & \texttt{HDATA\_SIZE} & Output & Read Data Bus\\
20 | \texttt{HWRITE} & 1 & Input & Write Select\\
21 | \texttt{HSIZE} & 3 & Input & Transfer Size\\
22 | \texttt{HBURST} & 3 & Input & Transfer Burst Size\\
23 | \texttt{HPROT} & 4 & Input & Transfer Protection Level\\
24 | \texttt{HREADYOUT} & 1 & Output & Transfer Ready Output\\
25 | \texttt{HREADY} & 1 & Input & Transfer Ready Input\\
26 | \texttt{HRESP} & 1 & Output & Transfer Response\\
27 | \bottomrule
28 | \caption{PLIC Interface Signals}
29 | \label{tab:AHBIF}
30 | \end{longtable}
31 |
32 | \subsection{HRESETn}
33 |
34 | When the active low asynchronous \texttt{HRESETn} input is asserted
35 | (`0'), the interface is put into its initial reset state.
36 |
37 | \subsection{HCLK}
38 |
39 | \texttt{HCLK} is the interface system clock. All internal logic for the
40 | AHB-Lite interface operates at the rising edge of this system clock and
41 | AHB bus timings are related to the rising edge of \texttt{HCLK}.
42 |
43 | \subsection{HSEL}
44 |
45 | The AHB-Lite interface only responds to other signals on its bus -- with
46 | the exception of the global asynchronous reset signal \texttt{HRESETn}
47 | -- when \texttt{HSEL} is asserted (`1'). When \texttt{HSEL} is negated
48 | (`0') the interface considers the bus \texttt{IDLE}.
49 |
50 | \subsection{HTRANS}
51 |
52 | HTRANS indicates the type of the current transfer as shown in Table \ref{tab:HTRANS}
53 | \being{comment}
54 | This shows as [tab:HTRANS]: on screen (DATASHEET.md)
55 | \end{comment}
56 |
57 |
58 | \begin{longtable}[c]{@{\extracolsep{\fill}}ccp{7cm}}
59 | \toprule
60 | \textbf{HTRANS} & \textbf{Type} & \textbf{Description}\\
61 | \midrule
62 | \endhead
63 | 00 & \texttt{IDLE} & No transfer required\\
64 | 01 & \texttt{BUSY} & Connected master is not ready to accept data, but intents to continue the current burst.\\
65 | 10 & \texttt{NONSEQ} & First transfer of a burst or a single transfer\\
66 | 11 & \texttt{SEQ} & Remaining transfers of a burst\\
67 | \bottomrule
68 | \caption{HTRANS Signal Types}
69 | \label{tab:HTRANS}
70 | \end{longtable}
71 |
72 | \subsection{HADDR}
73 |
74 | \texttt{HADDR} is the address bus. Its size is determined by the
75 | \texttt{HADDR\_SIZE} parameter and is driven to the connected
76 | peripheral.
77 |
78 | \subsection{HWDATA}
79 |
80 | \texttt{HWDATA} is the write data bus. Its size is determined by the
81 | \texttt{HDATA\_SIZE} parameter and is driven to the connected
82 | peripheral.
83 |
84 | \subsection{HRDATA}
85 |
86 | \texttt{HRDATA} is the read data bus. Its size is determined by the
87 | \texttt{HDATA\_SIZE} parameter and is sourced by the connected
88 | peripheral.
89 |
90 | \subsection{HWRITE}
91 |
92 | \texttt{HWRITE} is the read/write signal. \texttt{HWRITE} asserted (`1')
93 | indicates a write transfer.
94 |
95 | \subsection{HSIZE}
96 |
97 | \texttt{HSIZE} indicates the size of the current transfer as shown in
98 | \ifdefined\MARKDOWN
99 | Table \ref{tab:HSIZE}
100 | \else
101 | the table below:
102 | \fi
103 |
104 | \begin{longtable}[c]{@{\extracolsep{\fill}}ccl}
105 | \toprule
106 | \textbf{HSIZE} & \textbf{Size} & \textbf{Description}\\
107 | \midrule
108 | \endhead
109 | 000 & 8 bit & Byte\\
110 | 001 & 16 bit & Half Word\\
111 | 010 & 32 bit & Word\\
112 | 011 & 64 bits & Double Word\\
113 | 100 & 128 bit &\\
114 | 101 & 256 bit &\\
115 | 110 & 512 bit &\\
116 | 111 & 1024 bit &\\
117 | \bottomrule
118 | \caption{HSIZE Values}
119 | \label{tab:HSIZE}
120 | \end{longtable}
121 |
122 | \subsection{HBURST}
123 |
124 | HBURST indicates the transaction burst type -- a single transfer or part
125 | of a burst.
126 |
127 | \begin{longtable}[c]{@{\extracolsep{\fill}}ccl}
128 | \toprule
129 | \textbf{HBURST} & \textbf{Type} & \textbf{Description}\\
130 | \midrule
131 | \endhead
132 | 000 & \texttt{SINGLE} & Single access**\\
133 | 001 & \texttt{INCR} & Continuous incremental burst\\
134 | 010 & \texttt{WRAP4} & 4-beat wrapping burst\\
135 | 011 & \texttt{INCR4} & 4-beat incrementing burst\\
136 | 100 & \texttt{WRAP8} & 8-beat wrapping burst\\
137 | 101 & \texttt{INCR8} & 8-beat incrementing burst\\
138 | 110 & \texttt{WRAP16} & 16-beat wrapping burst\\
139 | 111 & \texttt{INCR16} & 16-beat incrementing burst\\
140 | \bottomrule
141 | \caption{HBURST Types}
142 | \label{tab:HBURST}
143 | \end{longtable}
144 |
145 | \subsection{HPROT}
146 |
147 | The \texttt{HPROT} signals provide additional information about the bus
148 | transfer and are intended to implement a level of protection.
149 |
150 | \begin{longtable}[c]{@{}lccl}
151 | \toprule
152 | & \textbf{Bit\#} & \textbf{Value} & \textbf{Description}\\
153 | \midrule
154 | \endhead
155 | & 3 & 1 & Cacheable region addressed\\
156 | & & 0 & Non-cacheable region addressed\\
157 | & 2 & 1 & Bufferable\\
158 | & 0 & Non-bufferable\\
159 | & 1 & 1 & Privileged Access\\
160 | & & 0 & User Access\\
161 | & 0 & 1 & Data Access\\
162 | & & 0 & Opcode fetch\\
163 | \bottomrule
164 | \caption{HPROT Indicators}
165 | \label{tab:HPROT}
166 | \end{longtable}
167 |
168 | \subsection{HREADYOUT}
169 |
170 | \texttt{HREADYOUT} indicates that the current transfer has finished.
171 | Note, for the AHB-Lite PLIC this signal is constantly asserted as the
172 | core is always ready for data access.
173 |
174 | \subsection{HREADY}
175 |
176 | \texttt{HREADY} indicates whether or not the addressed peripheral is
177 | ready to transfer data. When \texttt{HREADY} is negated (`0') the
178 | peripheral is not ready, forcing wait states. When \texttt{HREADY} is
179 | asserted (`1') the peripheral is ready and the transfer completed.
180 |
181 | \subsection{HRESP}
182 |
183 | \texttt{HRESP} is the instruction transfer response and indicates OKAY
184 | (`0') or ERROR (`1').
185 |
--------------------------------------------------------------------------------
/rtl/verilog/core/plic_gateway.sv:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////
2 | // ,------. ,--. ,--. //
3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
7 | // `---' //
8 | // RISC-V Platform-Level Interrupt Controller //
9 | // //
10 | /////////////////////////////////////////////////////////////////////
11 | // //
12 | // Copyright (C) 2017 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 OR //
24 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, //
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT //
26 | // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; //
27 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) //
28 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN //
29 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR //
30 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS //
31 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
32 | // //
33 | /////////////////////////////////////////////////////////////////////
34 |
35 | // +FHDR - Semiconductor Reuse Standard File Header Section -------
36 | // FILE NAME : plic_gateway.sv
37 | // DEPARTMENT :
38 | // AUTHOR : rherveille
39 | // AUTHOR'S EMAIL :
40 | // ------------------------------------------------------------------
41 | // RELEASE HISTORY
42 | // VERSION DATE AUTHOR DESCRIPTION
43 | // 1.0 2017-07-01 rherveille initial release
44 | // 2017-09-12 rherveille Added 'claim' and 'complete'
45 | // ------------------------------------------------------------------
46 | // KEYWORDS : RISC-V PLATFORM LEVEL INTERRUPT CONTROLLER - PLIC
47 | // ------------------------------------------------------------------
48 | // PURPOSE : PLIC Gateway, input section for each interrupt source
49 | // Supports edge-level triggered selection and interrupt
50 | // pending counter for events (edge triggered interrupts)
51 | // ------------------------------------------------------------------
52 | // PARAMETERS
53 | // PARAM NAME RANGE DESCRIPTION DEFAULT UNITS
54 | // MAX_PENDING_COUNT 0+ Max. pending interrupts 0
55 | // ------------------------------------------------------------------
56 | // REUSE ISSUES
57 | // Reset Strategy : external asynchronous active low; rst_n
58 | // Clock Domains : 1, clk, rising edge
59 | // Critical Timing :
60 | // Test Features : na
61 | // Asynchronous I/F : no
62 | // Scan Methodology : na
63 | // Instantiations : none
64 | // Synthesizable (y/n) : Yes
65 | // Other :
66 | // -FHDR-------------------------------------------------------------
67 |
68 | module plic_gateway #(
69 | parameter MAX_PENDING_COUNT = 16
70 | )
71 | (
72 | input rst_n, //Active low asynchronous reset
73 | clk, //System clock
74 |
75 | input src, //Interrupt source
76 | input edge_lvl, //(rising) edge or level triggered
77 |
78 | output ip, //interrupt pending
79 | input claim, //interrupt claimed
80 | input complete //interrupt handling completed
81 | );
82 |
83 |
84 | //////////////////////////////////////////////////////////////////
85 | //
86 | // Constants
87 | //
88 | localparam SAFE_MAX_PENDING_COUNT = (MAX_PENDING_COUNT >= 0) ? MAX_PENDING_COUNT : 0;
89 | localparam COUNT_BITS = $clog2(SAFE_MAX_PENDING_COUNT+1);
90 | localparam LEVEL = 1'b0,
91 | EDGE = 1'b1;
92 |
93 |
94 | //////////////////////////////////////////////////////////////////
95 | //
96 | // Variables
97 | //
98 | logic src_dly, src_edge;
99 | logic [COUNT_BITS-1:0] nxt_pending_cnt, pending_cnt;
100 | logic decr_pending;
101 | logic [ 1:0] ip_state;
102 |
103 |
104 | //////////////////////////////////////////////////////////////////
105 | //
106 | // Module Body
107 | //
108 |
109 | /** detect rising edge on interrupt source
110 | */
111 | always @(posedge clk,negedge rst_n)
112 | if (!rst_n)
113 | begin
114 | src_dly <= 1'b0;
115 | src_edge <= 1'b0;
116 | end
117 | else
118 | begin
119 | src_dly <= src;
120 | src_edge <= src & ~src_dly;
121 | end
122 |
123 |
124 | /** generate pending-counter
125 | */
126 | always_comb
127 | case ({decr_pending,src_edge})
128 | 2'b00: nxt_pending_cnt = pending_cnt; //do nothing
129 | 2'b01: if (pending_cnt < SAFE_MAX_PENDING_COUNT)
130 | nxt_pending_cnt = pending_cnt +'h1;
131 | else
132 | nxt_pending_cnt = pending_cnt;
133 | 2'b10: if (pending_cnt > 0)
134 | nxt_pending_cnt = pending_cnt -'h1;
135 | else
136 | nxt_pending_cnt = pending_cnt;
137 | 2'b11: nxt_pending_cnt = pending_cnt; //do nothing
138 | endcase
139 |
140 |
141 | always @(posedge clk,negedge rst_n)
142 | if (!rst_n ) pending_cnt <= 'h0;
143 | else if ( edge_lvl != EDGE) pending_cnt <= 'h0;
144 | else pending_cnt <= nxt_pending_cnt;
145 |
146 |
147 | /** generate interrupt pending
148 | * 1. assert IP
149 | * 2. target 'claims IP'
150 | * clears IP bit
151 | * blocks IP from asserting again
152 | * 3. target 'completes'
153 | */
154 | always @(posedge clk,negedge rst_n)
155 | if (!rst_n)
156 | begin
157 | ip_state <= 2'b00;
158 | decr_pending <= 1'b0;
159 | end
160 | else
161 | begin
162 | decr_pending <= 1'b0; //strobe signal
163 |
164 | case (ip_state)
165 | //wait for interrupt request from source
166 | 2'b00 : if ((edge_lvl == EDGE && |nxt_pending_cnt) ||
167 | (edge_lvl == LEVEL && src ))
168 | begin
169 | ip_state <= 2'b01;
170 | decr_pending <= 1'b1; //decrement
171 | end
172 |
173 | //wait for 'interrupt claim'
174 | 2'b01 : if (claim ) ip_state <= 2'b10;
175 |
176 | //wait for 'interrupt completion'
177 | 2'b10 : if (complete) ip_state <= 2'b00;
178 |
179 | //oops ...
180 | default: ip_state <= 2'b00;
181 | endcase
182 | end
183 |
184 | //IP-bit is ip_state LSB
185 | assign ip = ip_state[0];
186 |
187 | endmodule : plic_gateway
188 |
--------------------------------------------------------------------------------
/docs/tex/specification.tex:
--------------------------------------------------------------------------------
1 | \chapter{Specifications} \label{specifications}
2 |
3 | \section{Overview}
4 |
5 | The AHB-Lite PLIC IP core is a fully parameterised Platform-Level Interrupt
6 | Controller, featuring a single AHB-Lite Slave interface and support for a user-defined number of both Interrupt Sources and Targets.
7 |
8 | The purpose of the PLIC core is to connect multiple interrupt sources to
9 | one or more interrupt targets. The core supports a programmable number
10 | of simultaneous pending interrupt requests per source and individual routing of those interrupt requests to each target.
11 |
12 | Per the \href{https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-privileged-v1.10.pdf}{RISC-V Privileged Architecture Instruction Set specification (v1.10)}, the core performs full interrupt prioritisation of each interrupt source; each may be assigned a separate priority and enabled per target via a matrix of interrupt enable bits. Further, an optional priority threshold per target may be defined to mask lower priority interrupts.
13 |
14 | To reduce latency, the PLIC core presents all asserted interrupts to the target in priority order, queuing them so that a software interrupt handler can service all pending interrupts without the need to restore the interrupted context.
15 |
16 | For illustration, a simplified example system using the PLIC core is shown below:
17 |
18 | \begin{figure}[htb]
19 | \includegraphics{assets/img/plic-system}
20 | \caption{PLIC System Diagram}
21 | \label{fig:SYSDIAG}
22 | \end{figure}
23 |
24 | \section{PLIC Operation}
25 |
26 | As stated in the \href{https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-privileged-v1.10.pdf}{RISC-V Privileged Architecture Instruction Set specification (v1.10)}:
27 |
28 | \begin{quote}
29 |
30 | PLIC connects global \emph{interrupt sources}, which are usually
31 | I/O devices, to \emph{interrupt targets}, which are usually \emph{hart
32 | contexts}. The PLIC contains multiple \emph{interrupt gateways}, one
33 | per interrupt source, together with a \emph{PLIC core} that performs
34 | interrupt prioritization and routing. Global interrupts are sent from
35 | their source to an \emph{interrupt gateway} that processes the
36 | interrupt signal from each source and sends a single \emph{interrupt
37 | request} to the PLIC core, which latches these in the core interrupt
38 | pending bits (IP). Each interrupt source is assigned a separate
39 | priority. The PLIC core contains a matrix of interrupt enable (IE)
40 | bits to select the interrupts that are enabled for each target. The
41 | PLIC core forwards an \emph{interrupt notification} to one or more
42 | targets if the targets have any pending interrupts enabled, and the
43 | priority of the pending interrupts exceeds a per-target threshold.
44 | When the target takes the external interrupt, it sends an \emph{
45 | interrupt claim} request to retrieve the identifier of the
46 | highest-priority global interrupt source pending for that target from
47 | the PLIC core, which then clears the corresponding interrupt source
48 | pending bit. After the target has serviced the interrupt, it sends
49 | the associated interrupt gateway an \emph{interrupt completion} message
50 | and the interrupt gateway can now forward another interrupt request
51 | for the same source to the PLIC.
52 |
53 | \end{quote}
54 |
55 | \begin{figure}[htb]
56 | \centering
57 | \includegraphics[width=\textwidth]{assets/img/PLIC-block-diagram}
58 | \caption{Platform-Level Interrupt Controller (PLIC) conceptual block diagram.}
59 | \label{fig:plic-block-diagram}
60 | \end{figure}
61 |
62 | \ifdefined\MARKDOWN
63 | The figure above provides an overview of PLIC operation, showing the first two of potentially many interrupt sources, and the first two of potentially many interrupt targets.
64 | \else
65 | Figure~\ref{fig:plic-block-diagram} provides an overview of PLIC operation, showing the first two of potentially many interrupt sources, and the first two of potentially many interrupt targets.
66 | \fi
67 |
68 | \clearpage
69 |
70 | \section{Interrupt Handling Handshake}
71 |
72 | \subsection{Overview}
73 |
74 | \ifdefined\MARKDOWN
75 | The following figure shows the logical flow of the Interrupt Handling Handshake as implemented byt the Roa Logic PLIC core. The following sections describe the stages depicted: Interrupt Request, Interrupt Notification, Interrupt Claim Response, Processing the Interrupt and Interrupt Completion.
76 | \else
77 | Figure \ref{fig:HANDSHAKE} shows the logical flow of the Interrupt Handling Handshake as implemented byt the Roa Logic PLIC core. The following sections describe the stages depicted: Interrupt Request, Interrupt Notification, Interrupt Claim Response, Processing the Interrupt and Interrupt Completion.
78 | \fi
79 |
80 |
81 | \begin{figure}[!htb]
82 | \includegraphics{assets/img/plic-handshake}
83 | \caption{Interrupt Handling Handshake}
84 | \label{fig:HANDSHAKE}
85 | \end{figure}
86 |
87 | Prior to operation, the PLIC system must be defined and configured as follows:
88 |
89 | \begin{itemize}
90 | \item
91 | Each source must be assigned an Interrupt Identifier (\texttt{ID}) - a unique unsigned integer. This identifier will determine interrupt priority when 2 or more interrupts with the same priority level are asserted; The \emph{lower} the \texttt{ID} assigned to the source, the \emph{greater} the interrupt priority
92 | \item
93 | A matrix of Interrupt Enable vectors - one IE register per target - must be set to determine which target processes the interrupts from which source.
94 | \item
95 | Each Interrupt Source attached to the PLIC assigned a Priority Level - an unsigned integer value - that determines the relative priority of the interrupt source. Larger values have higher priority.
96 | \item
97 | Optionally, a Priority Threshold per target set to mask lower priority interrupts such that interrupts will only be presented to a target if the assigned Priority Level is greater than the Priority Threshold.
98 | \end{itemize}
99 |
100 | \subsection{Interrupt Request Stage}
101 |
102 | A source asserts an interrupt request to the PLIC. The PLIC validates
103 | the request by first checking if an interrupt enable bit is set for each
104 | target and if the priority of the interrupt source exceeds any defined
105 | Interrupt Priority Threshold. If these conditions do not hold, the
106 | Interrupt Request is deemed invalid and stalled pending updates to the interrupt enable and/or priority threshold bits.
107 |
108 | The PLIC also determines if a previous interrupt request has been made by the same source.
109 | If an interrupt is defined as level triggered and has already been asserted but not yet serviced, the request is ignored.
110 | If an interrupt is defined as edge triggered and has already been asserted but not yet serviced, the request is queued by incrementing its Interrupt Pending counter.
111 | The depth of this counter is parameterised.
112 |
113 | If the request is deemed valid the request is forwarded to the
114 | appropriate target. In the case of queued edge-triggered requests, the
115 | interrupt pending counter is decremented by one immediately upon claim of the interrupt by the target.
116 |
117 | \subsection{Interrupt Notification Stage}
118 |
119 | A target is notified of an interrupt request by asserting the IRQ output for that target.
120 | The PLIC blocks forwarding any further requests from the interrupt source until the current request is serviced.
121 |
122 | On each clock cycle the ID register is loaded with the unique identifier of the highest priority interrupt to be processed.
123 | This ensures that the Interrupt Service Routine always reads the highest pending interrupt request.
124 |
125 | \subsection{Claim Response Stage} \label{sec:claim-response}
126 |
127 | A target makes an interrupt claim response by reading the ID register,
128 | which also notifies the target of the interrupt source to service. The
129 | PLIC de-asserts the IRQ output for the target in response to the claim.
130 | unless another, lower priority, interrupt is still pending.
131 |
132 | \subsection{Interrupt Handler Stage}
133 |
134 | If the ID read is greater than zero, the target services the identified interrupt source.
135 | If the ID read is zero, this indicates no outstanding pending interrupts remain and the handler may terminate.
136 |
137 | \subsection{Interrupt Completion Stage}
138 |
139 | Once an interrupt has been serviced, completion is signalled to the PLIC by writing to the ID register.
140 | The act of writing to the register is the completion notification; the value written is irrelevant.
141 |
142 | On receiving the completion notification the PLIC will again allow interrupts to be forwarded from the corresponding source.
143 |
144 | The Interrupt Handler may then exit, however it is possible a new
145 | interrupt request may have been asserted while the handler was running.
146 | To reduce latency the handler may instead determine if a new interrupt
147 | has been received and if so again claim the interrupt (See earlier). In this
148 | way the interrupt handler can service all interrupts without the need to
149 | restore the interrupted context.
150 |
--------------------------------------------------------------------------------
/rtl/verilog/core/plic_core.sv:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////
2 | // ,------. ,--. ,--. //
3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
7 | // `---' //
8 | // RISC-V Platform-Level Interrupt Controller //
9 | // //
10 | /////////////////////////////////////////////////////////////////////
11 | // //
12 | // Copyright (C) 2017 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 OR //
24 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, //
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT //
26 | // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; //
27 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) //
28 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN //
29 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR //
30 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS //
31 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
32 | // //
33 | /////////////////////////////////////////////////////////////////////
34 |
35 | // +FHDR - Semiconductor Reuse Standard File Header Section -------
36 | // FILE NAME : plic_core.sv
37 | // DEPARTMENT :
38 | // AUTHOR : rherveille
39 | // AUTHOR'S EMAIL :
40 | // ------------------------------------------------------------------
41 | // RELEASE HISTORY
42 | // VERSION DATE AUTHOR DESCRIPTION
43 | // 1.0 2017-07-01 rherveille initial release
44 | // 2017-09-12 rherveille Added 'claim' and 'complete'
45 | // ------------------------------------------------------------------
46 | // KEYWORDS : RISC-V PLATFORM LEVEL INTERRUPT CONTROLLER - PLIC
47 | // ------------------------------------------------------------------
48 | // PURPOSE : PLIC Core Top Level
49 | // ------------------------------------------------------------------
50 | // PARAMETERS
51 | // PARAM NAME RANGE DESCRIPTION DEFAULT UNITS
52 | // SOURCES 1+ No. of interupt sources 8
53 | // TARGETS 1+ No. of interrupt targets 1
54 | // PRIORITIES 1+ No. of priority levels 8
55 | // MAX_PENDING_COUNT 0+ Max. pending interrupts 0
56 | // ------------------------------------------------------------------
57 | // REUSE ISSUES
58 | // Reset Strategy : external asynchronous active low; rst_n
59 | // Clock Domains : 1, clk, rising edge
60 | // Critical Timing : cell-array for each target
61 | // Test Features : na
62 | // Asynchronous I/F : no
63 | // Scan Methodology : na
64 | // Instantiations : plic_gateway, plic_cell, plic_target
65 | // Synthesizable (y/n) : Yes
66 | // Other :
67 | // -FHDR-------------------------------------------------------------
68 |
69 | module plic_core #(
70 | parameter SOURCES = 8, //Number of interrupt sources
71 | parameter TARGETS = 1, //Number of interrupt targets
72 | parameter PRIORITIES = 8, //Number of Priority levels
73 | parameter MAX_PENDING_COUNT = 0,
74 |
75 | //These should be localparams, but that's not supported by all tools yet
76 | parameter SOURCES_BITS = $clog2(SOURCES+1), //0=reserved
77 | parameter PRIORITY_BITS = $clog2(PRIORITIES)
78 | )
79 | (
80 | input rst_n, //Active low asynchronous reset
81 | clk, //System clock
82 |
83 | input [SOURCES -1:0] src, //Interrupt request from devices/sources
84 | el, //Edge/Level sensitive for each source
85 | output [SOURCES -1:0] ip, //Interrupt Pending for each source
86 |
87 | input [SOURCES -1:0] ie [TARGETS], //Interrupt enable per source, for each target
88 | input [PRIORITY_BITS-1:0] ipriority[SOURCES], //Priority for each source (priority is a reserved keyword)
89 | input [PRIORITY_BITS-1:0] threshold[TARGETS], //Priority Threshold for each target
90 |
91 | output [TARGETS -1:0] ireq, //Interrupt request for each target
92 | output [SOURCES_BITS -1:0] id [TARGETS], //Interrupt ID (1..SOURCES), for each target
93 | input [TARGETS -1:0] claim, //Interrupt claim
94 | input [TARGETS -1:0] complete //Interrupt handling complete
95 | );
96 | //////////////////////////////////////////////////////////////////
97 | //
98 | // Variables
99 | //
100 | genvar s, t;
101 |
102 | logic [SOURCES_BITS -1:0] id_array [TARGETS][SOURCES];
103 | logic [PRIORITY_BITS-1:0] pr_array [TARGETS][SOURCES];
104 |
105 | logic [SOURCES_BITS -1:0] id_claimed [TARGETS];
106 | logic [TARGETS -1:0] claim_array [SOURCES];
107 | logic [TARGETS -1:0] complete_array [SOURCES];
108 |
109 |
110 | //////////////////////////////////////////////////////////////////
111 | //
112 | // Module Body
113 | //
114 |
115 |
116 | /** Generate claim/complete per source, for each target
117 | */
118 | generate
119 | for (s=0; s < SOURCES; s++)
120 | begin : gen_claims_source_array
121 | for (t=0; t < TARGETS; t++)
122 | begin : gen_claim_complete
123 | assign claim_array [s][t] = (id[t] == s+1) ? claim[t] : 1'b0;
124 | assign complete_array[s][t] = (id_claimed[t] == s+1) ? complete[t] : 1'b0;
125 | end
126 | end
127 | endgenerate
128 |
129 |
130 | /** Store claimed ID
131 | */
132 | generate
133 | for (t=0; t < TARGETS; t++)
134 | begin : gen_id_claimed
135 | always @(posedge clk,negedge rst_n)
136 | if (!rst_n ) id_claimed[t] <= 'h0;
137 | else if ( claim[t]) id_claimed[t] <= id[t];
138 | end
139 | endgenerate
140 |
141 |
142 | /** Build Gateways
143 | *
144 | * For each Interrupt Source there's a gateway
145 | */
146 | generate
147 | for (s = 0; s < SOURCES; s++)
148 | begin : gen_gateway
149 | plic_gateway #(MAX_PENDING_COUNT)
150 | gateway_inst (
151 | .rst_n ( rst_n ),
152 | .clk ( clk ),
153 | .src ( src [s] ),
154 | .edge_lvl ( el [s] ),
155 | .ip ( ip [s] ),
156 | .claim (|claim_array [s] ),
157 | .complete (|complete_array[s] )
158 | );
159 | end : gen_gateway
160 | endgenerate
161 |
162 |
163 | /** Build cell-array
164 | *
165 | * Generate array of ID/Priority cells
166 | * One cell for each source-target combination
167 | */
168 | generate
169 | for (t=0; t < TARGETS; t++)
170 | begin : gen_cell_target_array
171 | for (s=0; s < SOURCES; s++)
172 | begin : gen_cell_source_array
173 | plic_cell #(
174 | .ID ( s +1 ),
175 | .SOURCES ( SOURCES ),
176 | .PRIORITIES ( PRIORITIES )
177 | )
178 | cell_inst (
179 | .rst_ni ( rst_n ),
180 | .clk_i ( clk ),
181 | .ip_i ( ip [s] ),
182 | .ie_i ( ie [t][s] ), //bitslice from packed array 'ie'
183 | .priority_i ( ipriority [s] ),
184 | .id_o ( id_array [t][s] ),
185 | .priority_o ( pr_array [t][s] )
186 | );
187 | end : gen_cell_source_array
188 | end : gen_cell_target_array
189 | endgenerate
190 |
191 |
192 | /** Build output array
193 | *
194 | * Generate output array for each target
195 | */
196 | generate
197 | for (t=0; t < TARGETS; t++)
198 | begin : gen_target
199 | plic_target #(
200 | .SOURCES ( SOURCES ),
201 | .PRIORITIES ( PRIORITIES )
202 | )
203 | target_inst (
204 | .rst_ni ( rst_n ),
205 | .clk_i ( clk ),
206 | .id_i ( id_array [t] ),
207 | .priority_i ( pr_array [t] ),
208 | .threshold_i ( threshold[t] ),
209 | .id_o ( id [t] ),
210 | .ireq_o ( ireq [t] )
211 | );
212 | end : gen_target
213 | endgenerate
214 |
215 | endmodule : plic_core
216 |
--------------------------------------------------------------------------------
/rtl/verilog/apb4/apb4_plic_top.sv:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////
2 | // ,------. ,--. ,--. //
3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
7 | // `---' //
8 | // RISC-V Platform-Level Interrupt Controller //
9 | // //
10 | /////////////////////////////////////////////////////////////////////
11 | // //
12 | // Copyright (C) 2017-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 OR //
24 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, //
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT //
26 | // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; //
27 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) //
28 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN //
29 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR //
30 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS //
31 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
32 | // //
33 | /////////////////////////////////////////////////////////////////////
34 |
35 | // +FHDR - Semiconductor Reuse Standard File Header Section -------
36 | // FILE NAME : apb4_plic_top.sv
37 | // DEPARTMENT :
38 | // AUTHOR : rherveille
39 | // AUTHOR'S EMAIL :
40 | // ------------------------------------------------------------------
41 | // RELEASE HISTORY
42 | // VERSION DATE AUTHOR DESCRIPTION
43 | // 1.0 2021-10-27 rherveille initial release
44 | // ------------------------------------------------------------------
45 | // KEYWORDS : RISC-V PLATFORM LEVEL INTERRUPT CONTROLLER - PLIC
46 | // APB, APB4, AMBA
47 | // ------------------------------------------------------------------
48 | // PURPOSE : APB4-Lite Top Level
49 | // ------------------------------------------------------------------
50 | // PARAMETERS
51 | // PARAM NAME RANGE DESCRIPTION DEFAULT UNITS
52 | // PADDR_SIZE [32,64] PADDR width 32
53 | // PDATA_SIZE [32,64] PDATA width 32
54 | // SOURCES 1+ No. of interupt sources 16
55 | // TARGETS 1+ No. of interrupt targets 4
56 | // PRIORITIES 1+ No. of priority levels 8
57 | // MAX_PENDING_COUNT 0+ Max. pending events 8
58 | // HAS_THRESHOLD [0,1] Is 'threshold' impl.? 1
59 | // HAS_CONFIG_REG [0,1] Is 'config' implemented? 1
60 | // ------------------------------------------------------------------
61 | // REUSE ISSUES
62 | // Reset Strategy : external asynchronous active low; PRESETn
63 | // Clock Domains : 1, PCLK, rising edge
64 | // Critical Timing : cell-array for each target
65 | // Test Features : na
66 | // Asynchronous I/F : no
67 | // Scan Methodology : na
68 | // Instantiations : plic_core, plic_dynamic_registers
69 | // Synthesizable (y/n) : Yes
70 | // Other :
71 | // -FHDR-------------------------------------------------------------
72 |
73 |
74 |
75 | module apb4_plic_top #(
76 | //AHB Parameters
77 | parameter PADDR_SIZE = 32,
78 | parameter PDATA_SIZE = 32,
79 |
80 | //PLIC Parameters
81 | parameter SOURCES = 64,//35, //Number of interrupt sources
82 | parameter TARGETS = 4, //Number of interrupt targets
83 | parameter PRIORITIES = 8, //Number of Priority levels
84 | parameter MAX_PENDING_COUNT = 8, //Max. number of 'pending' events
85 | parameter HAS_THRESHOLD = 1, //Is 'threshold' implemented?
86 | parameter HAS_CONFIG_REG = 1 //Is the 'configuration' register implemented?
87 | )
88 | (
89 | input PRESETn,
90 | PCLK,
91 |
92 | //AHB Slave Interface
93 | input PSEL,
94 | input PENABLE,
95 | input [PADDR_SIZE -1:0] PADDR,
96 | input PWRITE,
97 | input [PDATA_SIZE/8-1:0] PSTRB,
98 | input [PDATA_SIZE -1:0] PWDATA,
99 | output reg [PDATA_SIZE -1:0] PRDATA,
100 | output PREADY,
101 | output PSLVERR,
102 |
103 | input [SOURCES -1:0] src, //Interrupt sources
104 | output [TARGETS -1:0] irq //Interrupt Requests
105 | );
106 |
107 | //////////////////////////////////////////////////////////////////
108 | //
109 | // Constants
110 | //
111 |
112 | localparam SOURCES_BITS = $clog2(SOURCES+1); //0=reserved
113 | localparam PRIORITY_BITS = $clog2(PRIORITIES);
114 |
115 |
116 | /** Address map
117 | * Configuration (if implemented)
118 | * GateWay control
119 | * [SOURCES -1:0] el
120 | * [PRIORITY_BITS-1:0] priority [SOURCES]
121 | *
122 | * PLIC-Core
123 | * [SOURCES -1:0] ie [TARGETS]
124 | * [PRIORITY_BITS-1:0] threshold [TARGETS] (if implemented)
125 | *
126 | * Target
127 | * [SOURCES_BITS -1:0] id [TARGETS]
128 | */
129 |
130 | //////////////////////////////////////////////////////////////////
131 | //
132 | // Variables
133 | //
134 |
135 | //AHB write action
136 | logic apb_we,
137 | apb_re;
138 |
139 | //Decoded registers
140 | logic [SOURCES -1:0] el,
141 | ip;
142 | logic [PRIORITY_BITS-1:0] p [SOURCES];
143 | logic [SOURCES -1:0] ie [TARGETS];
144 | logic [PRIORITY_BITS-1:0] th [TARGETS];
145 | logic [SOURCES_BITS -1:0] id [TARGETS];
146 |
147 | logic [TARGETS -1:0] claim,
148 | complete;
149 |
150 |
151 | //////////////////////////////////////////////////////////////////
152 | //
153 | // Module Body
154 | //
155 |
156 |
157 | /** APB accesses
158 | */
159 | //The core supports zero-wait state accesses on all transfers.
160 | assign PREADY = 1'b1; //always ready
161 | assign PSLVERR = 1'b0; //Never an error
162 |
163 |
164 | /** APB Read/Write
165 | */
166 | assign apb_re = PSEL & ~PENABLE & ~PWRITE;
167 | assign apb_we = PSEL & PENABLE & PWRITE;
168 |
169 |
170 | /** Hookup Dynamic Register block
171 | */
172 | plic_dynamic_registers #(
173 | //Bus Interface Parameters
174 | .ADDR_SIZE ( PADDR_SIZE ),
175 | .DATA_SIZE ( PDATA_SIZE ),
176 |
177 | //PLIC Parameters
178 | .SOURCES ( SOURCES ),
179 | .TARGETS ( TARGETS ),
180 | .PRIORITIES ( PRIORITIES ),
181 | .MAX_PENDING_COUNT ( MAX_PENDING_COUNT ),
182 | .HAS_THRESHOLD ( HAS_THRESHOLD ),
183 | .HAS_CONFIG_REG ( HAS_CONFIG_REG )
184 | )
185 | dyn_register_inst (
186 | .rst_n ( PRESETn ), //Active low asynchronous reset
187 | .clk ( PCLK ), //System clock
188 |
189 | .we ( apb_we ), //write cycle
190 | .re ( apb_re ), //read cycle
191 | .be ( PSTRB ), //PSTRB=byte-enables
192 | .waddr ( PADDR ), //write address
193 | .raddr ( PADDR ), //read address
194 | .wdata ( PWDATA ), //write data
195 | .rdata ( PRDATA ), //read data
196 |
197 | .el ( el ), //Edge/Level
198 | .ip ( ip ), //Interrupt Pending
199 |
200 | .ie ( ie ), //Interrupt Enable
201 | .p ( p ), //Priority
202 | .th ( th ), //Priority Threshold
203 |
204 | .id ( id ), //Interrupt ID
205 | .claim ( claim ), //Interrupt Claim
206 | .complete ( complete ) //Interrupt Complete
207 | );
208 |
209 |
210 | /** Hookup PLIC Core
211 | */
212 | plic_core #(
213 | .SOURCES ( SOURCES ),
214 | .TARGETS ( TARGETS ),
215 | .PRIORITIES ( PRIORITIES ),
216 | .MAX_PENDING_COUNT ( MAX_PENDING_COUNT )
217 | )
218 | plic_core_inst (
219 | .rst_n ( PRESETn ),
220 | .clk ( PCLK ),
221 |
222 | .src ( src ),
223 | .el ( el ),
224 | .ip ( ip ),
225 | .ie ( ie ),
226 | .ipriority ( p ),
227 | .threshold ( th ),
228 |
229 | .ireq ( irq ),
230 | .id ( id ),
231 | .claim ( claim ),
232 | .complete ( complete )
233 | );
234 |
235 | endmodule : apb4_plic_top
236 |
237 |
--------------------------------------------------------------------------------
/bench/verilog/ahb3lite_bfm.sv:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////
2 | // ,------. ,--. ,--. //
3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
7 | // `---' //
8 | // RISC-V Platform-Level Interrupt Controller Testbench (Tests) //
9 | // //
10 | /////////////////////////////////////////////////////////////////////
11 | // //
12 | // Copyright (C) 2017 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 | module ahb3lite_master_bfm #(
35 | parameter HADDR_SIZE = 16,
36 | parameter HDATA_SIZE = 32
37 | )
38 | (
39 | input HRESETn,
40 | HCLK,
41 |
42 | //AHB Master Interface
43 | output reg HSEL,
44 | output reg [HADDR_SIZE-1:0] HADDR,
45 | output reg [HDATA_SIZE-1:0] HWDATA,
46 | input [HDATA_SIZE-1:0] HRDATA,
47 | output reg HWRITE,
48 | output reg [ 2:0] HSIZE,
49 | output reg [ 2:0] HBURST,
50 | output reg [ 3:0] HPROT,
51 | output reg [ 1:0] HTRANS,
52 | output reg HMASTLOCK,
53 | input HREADY,
54 | input HRESP
55 | );
56 |
57 | always @(negedge HRESETn) reset();
58 |
59 |
60 | //////////////////////////////////////////////////////////////////
61 | //
62 | // Constants
63 | //
64 | import ahb3lite_pkg::*;
65 |
66 |
67 | /////////////////////////////////////////////////////////
68 | //
69 | // Tasks
70 | //
71 | task reset();
72 | //Reset AHB Bus
73 | HSEL = 1'b0;
74 | HADDR = 'hx;
75 | HWDATA = 'hx;
76 | HWRITE = 'hx;
77 | HSIZE = 'hx;
78 | HBURST = 'hx;
79 | HPROT = 'hx;
80 | HTRANS = HTRANS_IDLE;
81 | HMASTLOCK = 'h0;
82 |
83 | @(posedge HRESETn);
84 | endtask
85 |
86 |
87 | task idle ();
88 | //Put AHB Bus in IDLE state
89 | //Call after write or read sequence
90 | wait4hready();
91 | HSEL <= 1'b0;
92 | HTRANS <= HTRANS_IDLE;
93 | endtask
94 |
95 |
96 | task automatic write (
97 | input [HADDR_SIZE-1:0] address,
98 | const ref [HDATA_SIZE-1:0] data[],
99 | input [ 2:0] size,
100 | input [ 2:0] burst
101 | );
102 | int beats;
103 |
104 | beats = get_beats_per_burst(burst);
105 | if (beats < 0) beats = data.size();
106 |
107 | fork
108 | ahb_cmd(address, size, burst, 1'b1, beats);
109 | ahb_data(address, size, burst, 1'b1, beats, data);
110 | join_any
111 | endtask
112 |
113 |
114 | task automatic read (
115 | input [HADDR_SIZE-1:0] address,
116 | ref [HDATA_SIZE-1:0] data[],
117 | input [ 2:0] size,
118 | input [ 2:0] burst
119 | );
120 | int beats;
121 |
122 | beats = get_beats_per_burst(burst);
123 | if (beats < 0) beats = data.size();
124 |
125 | fork
126 | ahb_cmd(address, size, burst, 1'b0, beats);
127 | ahb_data(address, size, burst, 1'b0, beats, data);
128 | join_any
129 | endtask
130 |
131 |
132 | /////////////////////////////////////////////////////////
133 | //
134 | // Sub-Tasks
135 | //
136 | task wait4hready;
137 | do
138 | @(posedge HCLK);
139 | while (!HREADY);
140 | endtask : wait4hready
141 |
142 |
143 | task automatic ahb_cmd (
144 | input [HADDR_SIZE-1:0] addr,
145 | input [ 2:0] size,
146 | input [ 2:0] burst,
147 | input rw,
148 | input int beats
149 | );
150 | wait4hready();
151 | HSEL <= 1'b1;
152 | HADDR <= addr;
153 | HWRITE <= rw;
154 | HSIZE <= size;
155 | HBURST <= burst;
156 | HPROT <= 'hx;
157 | HTRANS <= HTRANS_NONSEQ;
158 | HMASTLOCK <= 1'b0;
159 |
160 | repeat (beats -1)
161 | begin
162 | wait4hready();
163 | HADDR <= next_address(size,burst);
164 | HTRANS <= HTRANS_SEQ;
165 | end
166 | endtask : ahb_cmd
167 |
168 |
169 | task automatic ahb_data (
170 | input [HADDR_SIZE-1:0] address,
171 | input [ 2:0] size,
172 | input [ 2:0] burst,
173 | input rw,
174 | input int beats,
175 | ref [HDATA_SIZE-1:0] data[]
176 | );
177 | logic [(HDATA_SIZE+7)/8 -1:0] byte_offset;
178 | logic [HDATA_SIZE -1:0] data_copy[],
179 | tmp_var;
180 |
181 | if (!rw)
182 | begin
183 | HWDATA <= 'hx;
184 |
185 | //extra cycle for reading
186 | //read at the end of the cycle
187 | wait4hready();
188 | end
189 | else
190 | begin
191 | //copy data, prevent it being overwritten by caller
192 | data_copy = data;
193 | end
194 |
195 | wait4hready();
196 |
197 | //get the address offset. No checks if the offset is legal
198 | byte_offset = address % (HDATA_SIZE/8);
199 |
200 | //transfer beats
201 | for (int nbeat = 0; nbeat < beats; nbeat++)
202 | begin
203 | wait4hready();
204 |
205 | if (rw)
206 | begin
207 | //writing ... transfer from data-buffer to AHB-HWDATA
208 | HWDATA <= 'hx;
209 |
210 | //'byte' is reserved, so use nbyte
211 | for (int nbyte = 0; nbyte < get_bytes_per_beat(size); nbyte++)
212 | HWDATA[(nbyte + byte_offset)*8 +: 8] <= data_copy[nbeat][nbyte*8 +: 8];
213 | end
214 | else
215 | begin
216 | //reading ... transfer from AHB-HRDATA to data-buffer
217 |
218 | //'byte' is reserved, so use nbyte
219 | //Store in temporary variable.
220 | // Using data[nbeat] directly fails when calling with a multi-dimensional dynamic array. Why????
221 | for (int nbyte = 0; nbyte < get_bytes_per_beat(size); nbyte++)
222 | tmp_var[nbyte*8 +: 8] = HRDATA[(nbyte+byte_offset)*8 +: 8];
223 |
224 | //copy read-data
225 | data[nbeat] = tmp_var;
226 | end
227 |
228 | byte_offset += get_bytes_per_beat(size) % (HDATA_SIZE/8);
229 | end
230 | endtask : ahb_data
231 |
232 |
233 |
234 | /////////////////////////////////////////////////////////
235 | //
236 | // Functions
237 | //
238 | function int get_bytes_per_beat(input [2:0] hsize);
239 | case (hsize)
240 | HSIZE_B8 : get_bytes_per_beat = 1;
241 | HSIZE_B16 : get_bytes_per_beat = 2;
242 | HSIZE_B32 : get_bytes_per_beat = 4;
243 | HSIZE_B64 : get_bytes_per_beat = 8;
244 | HSIZE_B128 : get_bytes_per_beat = 16;
245 | HSIZE_B256 : get_bytes_per_beat = 32;
246 | HSIZE_B512 : get_bytes_per_beat = 64;
247 | HSIZE_B1024: get_bytes_per_beat = 128;
248 | endcase
249 | endfunction : get_bytes_per_beat
250 |
251 |
252 | function int get_beats_per_burst(input [2:0] hburst);
253 | case (hburst)
254 | HBURST_SINGLE: get_beats_per_burst = 1;
255 | HBURST_INCR : get_beats_per_burst = -1;
256 | HBURST_INCR4 : get_beats_per_burst = 4;
257 | HBURST_WRAP4 : get_beats_per_burst = 4;
258 | HBURST_INCR8 : get_beats_per_burst = 8;
259 | HBURST_WRAP8 : get_beats_per_burst = 8;
260 | HBURST_INCR16: get_beats_per_burst = 16;
261 | HBURST_WRAP16: get_beats_per_burst = 16;
262 | endcase
263 | endfunction : get_beats_per_burst
264 |
265 |
266 | function [HADDR_SIZE-1:0] next_address(input [2:0] hsize, hburst);
267 | //generate address mask
268 | int beats_per_burst;
269 | logic [10:0] addr_mask;
270 |
271 | beats_per_burst = get_beats_per_burst(hburst);
272 | beats_per_burst = beats_per_burst > 0 ? beats_per_burst : 1;
273 | addr_mask = (get_bytes_per_beat(hsize) * beats_per_burst) -1;
274 |
275 | case (hburst)
276 | HBURST_WRAP4 : next_address = (HADDR & ~addr_mask) | ((HADDR + get_bytes_per_beat(hsize)) & addr_mask);
277 | HBURST_WRAP8 : next_address = (HADDR & ~addr_mask) | ((HADDR + get_bytes_per_beat(hsize)) & addr_mask);
278 | HBURST_WRAP16: next_address = (HADDR & ~addr_mask) | ((HADDR + get_bytes_per_beat(hsize)) & addr_mask);
279 | default : next_address = HADDR + get_bytes_per_beat(hsize);
280 | endcase
281 | endfunction : next_address
282 |
283 | endmodule : ahb3lite_master_bfm
284 |
--------------------------------------------------------------------------------
/rtl/verilog/ahb3lite/ahb3lite_plic_top.sv:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////
2 | // ,------. ,--. ,--. //
3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
7 | // `---' //
8 | // RISC-V Platform-Level Interrupt Controller //
9 | // //
10 | /////////////////////////////////////////////////////////////////////
11 | // //
12 | // Copyright (C) 2017 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 OR //
24 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, //
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT //
26 | // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; //
27 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) //
28 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN //
29 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR //
30 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS //
31 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
32 | // //
33 | /////////////////////////////////////////////////////////////////////
34 |
35 | // +FHDR - Semiconductor Reuse Standard File Header Section -------
36 | // FILE NAME : ahb3lite_plic_top.sv
37 | // DEPARTMENT :
38 | // AUTHOR : rherveille
39 | // AUTHOR'S EMAIL :
40 | // ------------------------------------------------------------------
41 | // RELEASE HISTORY
42 | // VERSION DATE AUTHOR DESCRIPTION
43 | // 1.0 2017-07-05 rherveille initial release
44 | // 2017-09013 rherveille Added 'claim' and 'complete'
45 | // ------------------------------------------------------------------
46 | // KEYWORDS : RISC-V PLATFORM LEVEL INTERRUPT CONTROLLER - PLIC
47 | // AHB3-Lite, AMBA
48 | // ------------------------------------------------------------------
49 | // PURPOSE : AHB3-Lite Top Level
50 | // ------------------------------------------------------------------
51 | // PARAMETERS
52 | // PARAM NAME RANGE DESCRIPTION DEFAULT UNITS
53 | // HADDR_SIZE [32,64] HADDR width 32
54 | // HDATA_SIZE [32,64] HDATA width 32
55 | // SOURCES 1+ No. of interupt sources 16
56 | // TARGETS 1+ No. of interrupt targets 4
57 | // PRIORITIES 1+ No. of priority levels 8
58 | // MAX_PENDING_COUNT 0+ Max. pending events 8
59 | // HAS_THRESHOLD [0,1] Is 'threshold' impl.? 1
60 | // HAS_CONFIG_REG [0,1] Is 'config' implemented? 1
61 | // ------------------------------------------------------------------
62 | // REUSE ISSUES
63 | // Reset Strategy : external asynchronous active low; HRESETn
64 | // Clock Domains : 1, HCLK, rising edge
65 | // Critical Timing : cell-array for each target
66 | // Test Features : na
67 | // Asynchronous I/F : no
68 | // Scan Methodology : na
69 | // Instantiations : plic_core, plic_dynamic_registers
70 | // Synthesizable (y/n) : Yes
71 | // Other :
72 | // -FHDR-------------------------------------------------------------
73 |
74 |
75 |
76 | module ahb3lite_plic_top
77 | import ahb3lite_pkg::*;
78 | #(
79 | //AHB Parameters
80 | parameter HADDR_SIZE = 32,
81 | parameter HDATA_SIZE = 32,
82 |
83 | //PLIC Parameters
84 | parameter SOURCES = 64,//35, //Number of interrupt sources
85 | parameter TARGETS = 4, //Number of interrupt targets
86 | parameter PRIORITIES = 8, //Number of Priority levels
87 | parameter MAX_PENDING_COUNT = 8, //Max. number of 'pending' events
88 | parameter HAS_THRESHOLD = 1, //Is 'threshold' implemented?
89 | parameter HAS_CONFIG_REG = 1 //Is the 'configuration' register implemented?
90 | )
91 | (
92 | input HRESETn,
93 | HCLK,
94 |
95 | //AHB Slave Interface
96 | input HSEL,
97 | input [HADDR_SIZE-1:0] HADDR,
98 | input [HDATA_SIZE-1:0] HWDATA,
99 | output reg [HDATA_SIZE-1:0] HRDATA,
100 | input HWRITE,
101 | input [ 2:0] HSIZE,
102 | input [ 2:0] HBURST,
103 | input [ 3:0] HPROT,
104 | input [ 1:0] HTRANS,
105 | output reg HREADYOUT,
106 | input HREADY,
107 | output HRESP,
108 |
109 | input [SOURCES -1:0] src, //Interrupt sources
110 | output [TARGETS -1:0] irq //Interrupt Requests
111 | );
112 |
113 | //////////////////////////////////////////////////////////////////
114 | //
115 | // Constants
116 | //
117 | localparam HDATA_BYTES = (HDATA_SIZE+7)/8; //number of bytes in HDATA
118 | localparam BE_SIZE = HDATA_BYTES;
119 |
120 | localparam SOURCES_BITS = $clog2(SOURCES+1); //0=reserved
121 | localparam PRIORITY_BITS = $clog2(PRIORITIES);
122 |
123 |
124 | /** Address map
125 | * Configuration (if implemented)
126 | * GateWay control
127 | * [SOURCES -1:0] el
128 | * [PRIORITY_BITS-1:0] priority [SOURCES]
129 | *
130 | * PLIC-Core
131 | * [SOURCES -1:0] ie [TARGETS]
132 | * [PRIORITY_BITS-1:0] threshold [TARGETS] (if implemented)
133 | *
134 | * Target
135 | * [SOURCES_BITS -1:0] id [TARGETS]
136 | */
137 |
138 | //////////////////////////////////////////////////////////////////
139 | //
140 | // Variables
141 | //
142 |
143 | //AHB write action
144 | logic ahb_we,
145 | ahb_re;
146 | logic [BE_SIZE -1:0] ahb_be;
147 | logic [HADDR_SIZE -1:0] ahb_waddr;
148 |
149 | //Decoded registers
150 | logic [SOURCES -1:0] el,
151 | ip;
152 | logic [PRIORITY_BITS-1:0] p [SOURCES];
153 | logic [SOURCES -1:0] ie [TARGETS];
154 | logic [PRIORITY_BITS-1:0] th [TARGETS];
155 | logic [SOURCES_BITS -1:0] id [TARGETS];
156 |
157 | logic [TARGETS -1:0] claim,
158 | complete;
159 |
160 | //////////////////////////////////////////////////////////////////
161 | //
162 | // Functions
163 | //
164 |
165 | /** AHB Accesses
166 | */
167 | function logic [6:0] address_offset;
168 | //returns a mask for the lesser bits of the address
169 | //meaning bits [ 0] for 16bit data
170 | // [1:0] for 32bit data
171 | // [2:0] for 64bit data
172 | //etc
173 |
174 | //default value, prevent warnings
175 | address_offset = 0;
176 |
177 | //What are the lesser bits in HADDR?
178 | case (HDATA_SIZE)
179 | 1024: address_offset = 7'b111_1111;
180 | 512: address_offset = 7'b011_1111;
181 | 256: address_offset = 7'b001_1111;
182 | 128: address_offset = 7'b000_1111;
183 | 64: address_offset = 7'b000_0111;
184 | 32: address_offset = 7'b000_0011;
185 | 16: address_offset = 7'b000_0001;
186 | default: address_offset = 7'b000_0000;
187 | endcase
188 | endfunction : address_offset
189 |
190 |
191 | function logic [6:0] address_mask;
192 | //Returns a mask for the major bits of the address
193 | //meaning bits [HADDR_SIZE-1:0] for 8bits data
194 | // [HADDR_SIZE-1:1] for 16bits data
195 | // [HADDR_SIZE-1:2] for 32bits data
196 | //etc
197 | address_mask = ~address_offset();
198 | endfunction : address_mask
199 |
200 |
201 | function logic [BE_SIZE-1:0] gen_be;
202 | input [ 2:0] hsize;
203 | input [HADDR_SIZE-1:0] haddr;
204 |
205 | logic [127:0] full_be;
206 | logic [ 6:0] haddr_masked;
207 |
208 | //get number of active lanes for a 1024bit databus (max width) for this HSIZE
209 | case (hsize)
210 | HSIZE_B1024: full_be = 'hffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff;
211 | HSIZE_B512 : full_be = 'hffff_ffff_ffff_ffff;
212 | HSIZE_B256 : full_be = 'hffff_ffff;
213 | HSIZE_B128 : full_be = 'hffff;
214 | HSIZE_DWORD: full_be = 'hff;
215 | HSIZE_WORD : full_be = 'hf;
216 | HSIZE_HWORD: full_be = 'h3;
217 | default : full_be = 'h1;
218 | endcase
219 |
220 | //generate masked address
221 | haddr_masked = haddr & address_offset();
222 |
223 | //create byte-enable
224 | gen_be = full_be[BE_SIZE-1:0] << haddr_masked;
225 | endfunction : gen_be
226 |
227 |
228 | function logic [HDATA_SIZE-1:0] gen_wval;
229 | //Returns the new value for a register
230 | // if be[n] == '1' then gen_val[byte_n] = new_val[byte_n]
231 | // else gen_val[byte_n] = old_val[byte_n]
232 | input [HDATA_SIZE-1:0] old_val,
233 | new_val;
234 | input [BE_SIZE -1:0] be;
235 |
236 | for (int n=0; n < BE_SIZE; n++)
237 | gen_wval[n*8 +: 8] = be[n] ? new_val[n*8 +: 8] : old_val[n*8 +: 8];
238 | endfunction : gen_wval
239 |
240 |
241 | //////////////////////////////////////////////////////////////////
242 | //
243 | // Module Body
244 | //
245 |
246 |
247 | /** AHB accesses
248 | */
249 | //The core supports zero-wait state accesses on all transfers.
250 | assign HREADYOUT = 1'b1; //always ready
251 | assign HRESP = HRESP_OKAY; //Never an error
252 |
253 |
254 | /** AHB Reads
255 | */
256 | assign ahb_re = HREADY & HSEL & !HWRITE & (HTRANS != HTRANS_BUSY) & (HTRANS != HTRANS_IDLE);
257 |
258 |
259 | /** AHB Writes
260 | */
261 | //generate internal write signal
262 | always @(posedge HCLK)
263 | if (HREADY) ahb_we <= HSEL & HWRITE & (HTRANS != HTRANS_BUSY) & (HTRANS != HTRANS_IDLE);
264 | else ahb_we <= 1'b0;
265 |
266 | //decode Byte-Enables
267 | always @(posedge HCLK)
268 | if (HREADY) ahb_be <= gen_be(HSIZE,HADDR);
269 |
270 | //store write address
271 | always @(posedge HCLK)
272 | if (HREADY) ahb_waddr <= HADDR;
273 |
274 |
275 | /** Hookup Dynamic Register block
276 | */
277 | plic_dynamic_registers #(
278 | //Bus Interface Parameters
279 | .ADDR_SIZE ( HADDR_SIZE ),
280 | .DATA_SIZE ( HDATA_SIZE ),
281 |
282 | //PLIC Parameters
283 | .SOURCES ( SOURCES ),
284 | .TARGETS ( TARGETS ),
285 | .PRIORITIES ( PRIORITIES ),
286 | .MAX_PENDING_COUNT ( MAX_PENDING_COUNT ),
287 | .HAS_THRESHOLD ( HAS_THRESHOLD ),
288 | .HAS_CONFIG_REG ( HAS_CONFIG_REG )
289 | )
290 | dyn_register_inst (
291 | .rst_n ( HRESETn ), //Active low asynchronous reset
292 | .clk ( HCLK ), //System clock
293 |
294 | .we ( HREADY & ahb_we ), //write when write-cycle and HREADY
295 | .re ( HREADY & ahb_re ), //read when HREADY
296 | .be ( ahb_be ), //stored byte-enables
297 | .waddr ( ahb_waddr ), //stored write address
298 | .raddr ( HADDR ), //read address
299 | .wdata ( HWDATA ), //write data
300 | .rdata ( HRDATA ), //read data
301 |
302 | .el ( el ), //Edge/Level
303 | .ip ( ip ), //Interrupt Pending
304 |
305 | .ie ( ie ), //Interrupt Enable
306 | .p ( p ), //Priority
307 | .th ( th ), //Priority Threshold
308 |
309 | .id ( id ), //Interrupt ID
310 | .claim ( claim ), //Interrupt Claim
311 | .complete ( complete ) //Interrupt Complete
312 | );
313 |
314 |
315 | /** Hookup PLIC Core
316 | */
317 | plic_core #(
318 | .SOURCES ( SOURCES ),
319 | .TARGETS ( TARGETS ),
320 | .PRIORITIES ( PRIORITIES ),
321 | .MAX_PENDING_COUNT ( MAX_PENDING_COUNT )
322 | )
323 | plic_core_inst (
324 | .rst_n ( HRESETn ),
325 | .clk ( HCLK ),
326 |
327 | .src ( src ),
328 | .el ( el ),
329 | .ip ( ip ),
330 | .ie ( ie ),
331 | .ipriority ( p ),
332 | .threshold ( th ),
333 |
334 | .ireq ( irq ),
335 | .id ( id ),
336 | .claim ( claim ),
337 | .complete ( complete )
338 | );
339 |
340 | endmodule : ahb3lite_plic_top
341 |
342 |
--------------------------------------------------------------------------------
/bench/verilog/test.sv:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////
2 | // ,------. ,--. ,--. //
3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
7 | // `---' //
8 | // RISC-V Platform-Level Interrupt Controller Testbench (Tests) //
9 | // //
10 | /////////////////////////////////////////////////////////////////////
11 | // //
12 | // Copyright (C) 2017 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 | module test #(
35 | parameter HADDR_SIZE = 16,
36 | parameter HDATA_SIZE = 32,
37 |
38 | parameter SOURCES = 16, //Number of interrupt sources
39 | parameter TARGETS = 4, //Number of interrupt targets
40 | parameter PRIORITIES = 7, //Number of Priority levels
41 | parameter MAX_PENDING_COUNT = 8, //
42 | parameter HAS_THRESHOLD = 1,
43 | parameter HAS_CONFIG_REG = 1
44 | )
45 | (
46 | input HRESETn,
47 | HCLK,
48 |
49 | output HSEL,
50 | output [HADDR_SIZE-1:0] HADDR,
51 | output [HDATA_SIZE-1:0] HWDATA,
52 | input [HDATA_SIZE-1:0] HRDATA,
53 | output HWRITE,
54 | output [ 2:0] HSIZE,
55 | output [ 2:0] HBURST,
56 | output [ 3:0] HPROT,
57 | output [ 1:0] HTRANS,
58 | output HMASTLOCK,
59 | input HREADY,
60 | input HRESP,
61 |
62 | output reg [SOURCES -1:0] src,
63 | input [TARGETS -1:0] irq
64 | );
65 |
66 | //////////////////////////////////////////////////////////////////
67 | //
68 | // Constants
69 | //
70 | import ahb3lite_pkg::*;
71 |
72 | localparam BE_SIZE = (HDATA_SIZE+7)/8;
73 | localparam PRIORITY_BITS = $clog2(PRIORITIES);
74 |
75 | typedef enum {CONFIG, EDGE_LEVEL, IPRIORITY, IENABLE, PTHRESHOLD, ID} registers_t;
76 |
77 | //Configuration Bits
78 | localparam MAX_SOURCES_BITS = 16;
79 | localparam MAX_TARGETS_BITS = 16;
80 | localparam MAX_PRIORITY_BITS = MAX_SOURCES_BITS;
81 | localparam HAS_THRESHOLD_BITS = 1;
82 |
83 | //How many CONFIG registers are there (only 1)
84 | localparam CONFIG_REGS = HAS_CONFIG_REG == 0 ? 0 : (MAX_SOURCES_BITS + MAX_TARGETS_BITS + MAX_PRIORITY_BITS + HAS_THRESHOLD_BITS + HDATA_SIZE -1) / HDATA_SIZE;
85 |
86 | //Amount of Edge/Level registers
87 | localparam EDGE_LEVEL_REGS = (SOURCES + HDATA_SIZE -1) / HDATA_SIZE;
88 |
89 | //Amount of Interrupt Enable registers
90 | localparam IE_REGS = EDGE_LEVEL_REGS * TARGETS;
91 |
92 | //Each PRIORITY field starts at a new nibble boundary
93 | //Get the number of nibbles in 'PRIORITY_BITS' ?
94 | localparam PRIORITY_NIBBLES = (PRIORITY_BITS +3 -1) / 4;
95 |
96 | //How many PRIORITY fields fit in 1 register?
97 | localparam PRIORITY_FIELDS_PER_REG = HDATA_SIZE / (PRIORITY_NIBBLES*4);
98 |
99 | //Amount of Priority registers
100 | localparam PRIORITY_REGS = (SOURCES + PRIORITY_FIELDS_PER_REG -1) / PRIORITY_FIELDS_PER_REG;
101 |
102 | //Amount of Threshold registers
103 | localparam PTHRESHOLD_REGS = HAS_THRESHOLD == 0 ? 0 : TARGETS;
104 |
105 | //Amount of ID registers
106 | localparam ID_REGS = TARGETS;
107 |
108 | //Total amount of registers
109 | localparam TOTAL_REGS = CONFIG_REGS + EDGE_LEVEL_REGS + IE_REGS + PRIORITY_REGS + PTHRESHOLD_REGS + ID_REGS;
110 |
111 |
112 | //////////////////////////////////////////////////////////////////
113 | //
114 | // Functions
115 | //
116 | function automatic registers_t register_function;
117 | //return register-type for specified register
118 | input int r;
119 |
120 | int idx;
121 | idx = r;
122 |
123 | //1. Configuration Register
124 | if (idx < CONFIG_REGS ) return CONFIG;
125 | idx -= CONFIG_REGS;
126 |
127 | //2. Gateway control registers
128 | // Edge/Level
129 | // Interrupt Pending/Acknowledge
130 | if (idx < EDGE_LEVEL_REGS) return EDGE_LEVEL;
131 | idx -= EDGE_LEVEL_REGS;
132 |
133 | //3. PLIC Core fabric registers
134 | if (idx < PRIORITY_REGS) return IPRIORITY;
135 | idx -= PRIORITY_REGS;
136 | if (idx < IE_REGS ) return IENABLE;
137 | idx -= IE_REGS;
138 |
139 | //4. Target Registers
140 | if (idx < PTHRESHOLD_REGS) return PTHRESHOLD;
141 | return ID;
142 | endfunction : register_function
143 |
144 |
145 | function automatic int register_idx;
146 | //return offset in register-type
147 | input int r;
148 |
149 | int idx;
150 | idx = r;
151 |
152 | //1. Configuration registers
153 | if (idx < CONFIG_REGS ) return idx;
154 | idx -= CONFIG_REGS;
155 |
156 | //2. first Gateway control registers
157 | // Edge/Level
158 | // Interrupt Pending/Acknowledge
159 | if (idx < EDGE_LEVEL_REGS) return idx;
160 | idx -= EDGE_LEVEL_REGS;
161 |
162 | //3. PLIC Core fabric registers
163 | if (idx < PRIORITY_REGS ) return idx;
164 | idx -= PRIORITY_REGS;
165 | if (idx < IE_REGS ) return idx;
166 | idx -= IE_REGS;
167 |
168 | //4. TARGET registers
169 | if (idx < PTHRESHOLD_REGS) return idx;
170 | idx -=PTHRESHOLD_REGS;
171 | return idx;
172 | endfunction : register_idx
173 |
174 |
175 | function string register_function_name;
176 | //returns the 'string' name associated with a register type
177 | input registers_t function_number;
178 |
179 | string name_array[registers_t];
180 | name_array[CONFIG ] = "Configuration";
181 | name_array[EDGE_LEVEL] = "Edge/Level";
182 | name_array[IENABLE ] = "Interrupt Enable";
183 | name_array[IPRIORITY ] = "Interrupt Priority";
184 | name_array[PTHRESHOLD] = "Priority Threshold";
185 | name_array[ID ] = "ID";
186 |
187 | return name_array[function_number];
188 | endfunction : register_function_name
189 |
190 |
191 | //////////////////////////////////////////////////////////////////
192 | //
193 | // Variables
194 | //
195 | int reset_watchdog,
196 | got_reset,
197 | errors;
198 |
199 | /////////////////////////////////////////////////////////
200 | //
201 | // Instantiate the AHB-Master
202 | //
203 | ahb3lite_master_bfm #(
204 | .HADDR_SIZE ( HADDR_SIZE ),
205 | .HDATA_SIZE ( HDATA_SIZE )
206 | )
207 | ahb_mst_bfm (
208 | .*
209 | );
210 |
211 |
212 | initial
213 | begin
214 | errors = 0;
215 | reset_watchdog = 0;
216 | got_reset = 0;
217 |
218 | forever
219 | begin
220 | reset_watchdog++;
221 | @(posedge HCLK);
222 | if (!got_reset && reset_watchdog == 1000)
223 | $fatal(-1,"HRESETn not asserted\nTestbench requires an AHB reset");
224 | end
225 | end
226 |
227 |
228 | always @(negedge HRESETn)
229 | begin
230 | //wait for reset to negate
231 | @(posedge HRESETn);
232 | got_reset = 1;
233 |
234 | welcome_text();
235 |
236 | //check initial values
237 | test_reset_register_values();
238 |
239 | //Test dynamic register access to EL
240 | test_el();
241 |
242 | //Test a single interrupt source
243 | test_single();
244 |
245 |
246 | //Finish simulation
247 | repeat (100) @(posedge HCLK);
248 | finish_text();
249 | $finish();
250 | end
251 |
252 |
253 | /////////////////////////////////////////////////////////
254 | //
255 | // Tasks
256 | //
257 | task welcome_text();
258 | $display ("------------------------------------------------------------");
259 | $display (" ,------. ,--. ,--. ");
260 | $display (" | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. ");
261 | $display (" | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' ");
262 | $display (" | |\\ \\ ' '-' '\\ '-' | | '--.' '-' ' '-' || |\\ `--. ");
263 | $display (" `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' ");
264 | $display (" `---' ");
265 | $display (" AHB3Lite PLIC Testbench Initialized ");
266 | $display ("------------------------------------------------------------");
267 | endtask : welcome_text
268 |
269 |
270 | task finish_text();
271 | if (errors>0)
272 | begin
273 | $display ("------------------------------------------------------------");
274 | $display (" AHB3Lite PLIC Testbench failed with (%0d) errors @%0t", errors, $time);
275 | $display ("------------------------------------------------------------");
276 | end
277 | else
278 | begin
279 | $display ("------------------------------------------------------------");
280 | $display (" AHB3Lite PLIC Testbench finished successfully @%0t", $time);
281 | $display ("------------------------------------------------------------");
282 | end
283 | endtask : finish_text
284 |
285 |
286 | /** test_reset_register_values
287 | * Test if all register are zero after reset
288 | */
289 | task test_reset_register_values;
290 | int r;
291 |
292 | logic [HDATA_SIZE-1:0] rbuffer[][];
293 | logic [ 63:0] config_reg_contents;
294 |
295 | $display ("Checking reset values ...");
296 |
297 | //Is 'config' implemented?
298 | if (HAS_CONFIG_REG)
299 | begin
300 | //create new read-buffers (1 per transaction)
301 | rbuffer = new[CONFIG_REGS];
302 |
303 | //read register(s) contents
304 | for (r=0; r < CONFIG_REGS; r++)
305 | begin
306 | rbuffer[r] = new[1];
307 | ahb_mst_bfm.read (r*HDATA_SIZE/8,
308 | rbuffer[r],
309 | HDATA_SIZE == 32 ? HSIZE_WORD : HSIZE_DWORD,
310 | HBURST_SINGLE);
311 | end
312 | ahb_mst_bfm.idle(); //Idle the AHB bus
313 | wait fork; //Wait for all transactions to finish
314 |
315 | //copy contents into 'config_reg_contents'
316 | for (r=0; r= 0;
403 | hsize--)
404 | begin
405 | error = 0;
406 |
407 | case (hsize)
408 | HSIZE_DWORD: begin
409 | hburst = HBURST_SINGLE;
410 | tsize = 64;
411 | $write(" Testing dword (64bit) accesses ... ");
412 | end
413 | HSIZE_WORD : begin
414 | hburst = HBURST_SINGLE;
415 | tsize = 32;
416 | $write(" Testing word (32bit) accesses ... ");
417 | end
418 | HSIZE_HWORD: begin
419 | hburst = (HDATA_SIZE == 64) ? HBURST_INCR4 : HBURST_SINGLE;
420 | tsize = 16;
421 | $write(" Testing hword (16bit) accesses ... ");
422 | end
423 | HSIZE_BYTE : begin
424 | hburst = (HDATA_SIZE == 64) ? HBURST_INCR8 : HBURST_INCR4;
425 | tsize = 8;
426 | $write(" Testing byte burst (8bit) accesses ... ");
427 | end
428 | endcase
429 |
430 |
431 | //Write test values
432 | for (r=0; r IRQ[%0t]...", s, t);
651 | if (irq == 1 << t)
652 | begin
653 | $display ("PASSED");
654 | end
655 | else
656 | begin
657 | $display ("FAILED");
658 | $error ("Expected IRQ=%0x, received %h @%0t", 1 << t, irq, $time);
659 | errors++;
660 | end
661 |
662 | //check if ID is correct >> claims interrupt <<
663 | ahb_mst_bfm.read ( (id_base_address + t) * HDATA_SIZE/8,
664 | rbuffer,
665 | HDATA_SIZE == 32 ? HSIZE_WORD : HSIZE_DWORD,
666 | HBURST_SINGLE);
667 | ahb_mst_bfm.idle(); //Idle the AHB bus
668 | wait fork; //Wait for all transactions to finish
669 |
670 | $write (" Checking ID/Claim Interrupt ...");
671 | if (rbuffer[0] == s+1)
672 | begin
673 | $display ("PASSED");
674 | end
675 | else
676 | begin
677 | $display ("FAILED");
678 | $error ("Expected ID=%0d, received %h @%0t", s+1, rbuffer[0], $time);
679 | errors++;
680 | end
681 |
682 | //clear source
683 | src[s] = 1'b0;
684 |
685 | repeat (3) @(posedge HCLK);
686 | $write (" Checking IRQ cleared ...");
687 | if (irq == 0)
688 | begin
689 | $display ("PASSED");
690 | end
691 | else
692 | begin
693 | $display ("FAILED");
694 | $error ("Expected IRQ=0, received %d @%0t", irq, $time);
695 | errors++;
696 | end
697 |
698 | //complete interrupt -- dummy write to ID
699 | $display (" Sending Interrupt Complete");
700 | ahb_mst_bfm.write ( (id_base_address +t) * HDATA_SIZE/8,
701 | wbuffer,
702 | HDATA_SIZE == 64 ? HSIZE_DWORD : HSIZE_WORD,
703 | HBURST_SINGLE);
704 |
705 | $write (" Checking IRQ cleared ...");
706 | if (irq == 0)
707 | begin
708 | $display ("PASSED");
709 | end
710 | else
711 | begin
712 | $display ("FAILED");
713 | $error ("Expected IRQ=0, received %d @%0t", irq, $time);
714 | errors++;
715 | end
716 |
717 | //disable interrupt
718 | wbuffer[0] = 0;
719 | ahb_mst_bfm.write ( (ie_base_address + (t * EDGE_LEVEL_REGS) + (s / HDATA_SIZE)) * HDATA_SIZE/8,
720 | wbuffer,
721 | HDATA_SIZE == 64 ? HSIZE_DWORD : HSIZE_WORD,
722 | HBURST_SINGLE);
723 |
724 | end //next s/t
725 |
726 | ahb_mst_bfm.idle(); //Idle the AHB bus
727 | wait fork; //Wait for all transactions to finish
728 | endtask : test_single
729 |
730 | endmodule : test
731 |
--------------------------------------------------------------------------------
/rtl/verilog/core/plic_dynamic_registers.sv:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////
2 | // ,------. ,--. ,--. //
3 | // | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
4 | // | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
5 | // | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
6 | // `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
7 | // `---' //
8 | // RISC-V Platform-Level Interrupt Controller //
9 | // //
10 | /////////////////////////////////////////////////////////////////////
11 | // //
12 | // Copyright (C) 2017 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 OR //
24 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, //
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT //
26 | // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; //
27 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) //
28 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN //
29 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR //
30 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS //
31 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
32 | // //
33 | /////////////////////////////////////////////////////////////////////
34 |
35 | // +FHDR - Semiconductor Reuse Standard File Header Section -------
36 | // FILE NAME : plic_dynamic_registers.sv
37 | // DEPARTMENT :
38 | // AUTHOR : rherveille
39 | // AUTHOR'S EMAIL :
40 | // ------------------------------------------------------------------
41 | // RELEASE HISTORY
42 | // VERSION DATE AUTHOR DESCRIPTION
43 | // 1.0 2017-07-18 rherveille initial release
44 | // 2017-09-13 rherveille Added 'claim' and 'complete'
45 | // ------------------------------------------------------------------
46 | // KEYWORDS : RISC-V PLATFORM LEVEL INTERRUPT CONTROLLER - PLIC
47 | // ------------------------------------------------------------------
48 | // PURPOSE : Dynamic Register generation for PLIC
49 | // ------------------------------------------------------------------
50 | // PARAMETERS
51 | // PARAM NAME RANGE DESCRIPTION DEFAULT UNITS
52 | // ADDR_SIZE [32,64] read/write address width 32
53 | // DATA_SIZE [32,64] read/write data width 32
54 | // SOURCES 1+ No. of interupt sources 8
55 | // TARGETS 1+ No. of interrupt targets 1
56 | // PRIORITIES 1+ No. of priority levels 8
57 | // MAX_PENDING_COUNT 0+ Max. pending interrupts 4
58 | // HAS_THRESHOLD [0,1] Is 'threshold' impl.? 1
59 | // HAS_CONFIG_REG [0,1] Is 'config' implemented? 1
60 | // ------------------------------------------------------------------
61 | // REUSE ISSUES
62 | // Reset Strategy : external asynchronous active low; rst_n
63 | // Clock Domains : 1, clk, rising edge
64 | // Critical Timing : na
65 | // Test Features : na
66 | // Asynchronous I/F : no
67 | // Scan Methodology : na
68 | // Instantiations : none
69 | // Synthesizable (y/n) : Yes
70 | // Other :
71 | // -FHDR-------------------------------------------------------------
72 |
73 | module plic_dynamic_registers #(
74 | //Bus Interface Parameters
75 | parameter ADDR_SIZE = 32,
76 | parameter DATA_SIZE = 32,
77 |
78 | //PLIC Parameters
79 | parameter SOURCES = 8, //Number of interrupt sources
80 | parameter TARGETS = 1, //Number of interrupt targets
81 | parameter PRIORITIES = 8, //Number of Priority levels
82 | parameter MAX_PENDING_COUNT = 4, //
83 | parameter HAS_THRESHOLD = 1, //Is 'threshold' implemented?
84 | parameter HAS_CONFIG_REG = 1, //Is 'config' implemented?
85 |
86 | //These should be 'localparam', but that's not supported by all tools yet
87 | parameter BE_SIZE = (DATA_SIZE+7)/8,
88 | parameter SOURCES_BITS = $clog2(SOURCES+1), //0=reserved
89 | parameter PRIORITY_BITS = $clog2(PRIORITIES)
90 | )
91 | (
92 | input rst_n, //Active low asynchronous reset
93 | clk, //System clock
94 |
95 | input we, //write enable
96 | re, //read enable
97 | input [BE_SIZE -1:0] be, //byte enable (writes only)
98 | input [ADDR_SIZE -1:0] waddr, //write address
99 | raddr, //read address
100 | input [DATA_SIZE -1:0] wdata, //write data
101 | output reg [DATA_SIZE -1:0] rdata, //read data
102 |
103 | output [SOURCES -1:0] el, //Edge/Level sensitive for each source
104 | input [SOURCES -1:0] ip, //Interrupt Pending for each source
105 |
106 | output [SOURCES -1:0] ie[TARGETS], //Interrupt enable per source, for each target
107 | output reg [PRIORITY_BITS-1:0] p [SOURCES], //Priority for each source
108 | output reg [PRIORITY_BITS-1:0] th[TARGETS], //Priority Threshold for each target
109 |
110 | input [SOURCES_BITS -1:0] id[TARGETS], //Interrupt ID for each target
111 | output reg [TARGETS -1:0] claim, //Interrupt Claim
112 | output reg [TARGETS -1:0] complete //Interrupt Complete
113 | );
114 |
115 | //////////////////////////////////////////////////////////////////
116 | //
117 | // Constants
118 | //
119 | localparam DATA_BYTES = BE_SIZE; //number of bytes in DATA
120 |
121 |
122 |
123 | /** Address map
124 | * Configuration
125 | * GateWay control
126 | * [SOURCES -1:0] el
127 | * [PRIORITY_BITS-1:0] priority [SOURCES]
128 | *
129 | * PLIC-Core
130 | * [SOURCES -1:0] ie [TARGETS]
131 | * [PRIORITY_BITS-1:0] threshold [TARGETS]
132 | * [SOURCES_BITS -1:0] ID [TARGETS
133 | */
134 |
135 | /** Calculate Register amount/offset
136 | * Each register is DATA_SIZE wide
137 | */
138 | typedef enum {CONFIG, EL, IE, PRIORITY, THRESHOLD, ID} register_types;
139 |
140 | //Configuration Bits
141 | localparam MAX_SOURCES_BITS = 16;
142 | localparam MAX_TARGETS_BITS = 16;
143 | localparam MAX_PRIORITY_BITS = MAX_SOURCES_BITS;
144 | localparam HAS_THRESHOLD_BITS = 1;
145 |
146 | //How many CONFIG registers are there (only 1)
147 | localparam CONFIG_REGS = HAS_CONFIG_REG == 0 ? 0 : (MAX_SOURCES_BITS + MAX_TARGETS_BITS + MAX_PRIORITY_BITS + HAS_THRESHOLD_BITS + DATA_SIZE -1) / DATA_SIZE;
148 |
149 | //How many Edge/Level registers are there?
150 | localparam EL_REGS = (SOURCES + DATA_SIZE -1) / DATA_SIZE;
151 |
152 | //How many IE registers are there?
153 | localparam IE_REGS = EL_REGS * TARGETS;
154 |
155 | //How many nibbles are there in 'PRIORITY_BITS' ?
156 | //Each PRIORITY starts at a new nibble boundary
157 | localparam PRIORITY_NIBBLES = (PRIORITY_BITS +3 -1) / 4;
158 |
159 | //How many PRIORITY fields fit in 1 register?
160 | localparam PRIORITY_FIELDS_PER_REG = DATA_SIZE / (PRIORITY_NIBBLES*4);
161 |
162 | //How many Priority registers are there?
163 | localparam PRIORITY_REGS = (SOURCES + PRIORITY_FIELDS_PER_REG -1) / PRIORITY_FIELDS_PER_REG;
164 |
165 | //How many Threshold registers are there?
166 | // localparam THRESHOLD_REGS = HAS_THRESHOLD == 0 ? 0 : (TARGETS + PRIORITY_FIELDS_PER_REG -1) / PRIORITY_FIELDS_PER_REG;
167 | localparam THRESHOLD_REGS = HAS_THRESHOLD == 0 ? 0 : TARGETS;
168 |
169 | //How many ID register are there?
170 | localparam ID_REGS = TARGETS;
171 |
172 | //How many registers in total?
173 | localparam TOTAL_REGS = CONFIG_REGS + EL_REGS + IE_REGS + PRIORITY_REGS + THRESHOLD_REGS + ID_REGS;
174 |
175 |
176 | //////////////////////////////////////////////////////////////////
177 | //
178 | // Variables
179 | //
180 |
181 | //Read Variables
182 | int read_register,
183 | read_register_idx;
184 | int write_register;
185 |
186 | //Registers
187 | logic [DATA_SIZE -1:0] registers [TOTAL_REGS];
188 |
189 |
190 | //////////////////////////////////////////////////////////////////
191 | //
192 | // Functions
193 | //
194 | function logic [DATA_SIZE-1:0] gen_wval;
195 | //Returns the new value for a register
196 | // if be[n] == '1' then gen_val[byte_n] = new_val[byte_n]
197 | // else gen_val[byte_n] = old_val[byte_n]
198 | input [DATA_SIZE-1:0] old_val,
199 | new_val;
200 | input [BE_SIZE -1:0] be;
201 |
202 | for (int n=0; n < BE_SIZE; n++)
203 | gen_wval[n*8 +: 8] = be[n] ? new_val[n*8 +: 8] : old_val[n*8 +: 8];
204 | endfunction : gen_wval
205 |
206 |
207 | /** Register Access calculation
208 | * Registers are created dynamically, access is determined by the
209 | * parameter settings
210 | */
211 | function automatic register_types register_function;
212 | //return register-type for specified register
213 | input int r;
214 |
215 | int idx;
216 | idx = r;
217 |
218 | //1. Configuration Register
219 | if (idx < CONFIG_REGS ) return CONFIG;
220 | idx -= CONFIG_REGS;
221 |
222 | //2. Gateway control registers
223 | // Edge/Level
224 | if (idx < EL_REGS ) return EL;
225 | idx -= EL_REGS;
226 |
227 | //3. PLIC Core fabric registers
228 | if (idx < PRIORITY_REGS) return PRIORITY;
229 | idx -= PRIORITY_REGS;
230 | if (idx < IE_REGS ) return IE;
231 | idx -= IE_REGS;
232 |
233 | //4. Target registers
234 | if (idx < THRESHOLD_REGS) return THRESHOLD;
235 | return ID;
236 | endfunction : register_function
237 |
238 |
239 | function automatic int register_idx;
240 | //return offset in register-type
241 | input int r;
242 |
243 | int idx;
244 | idx = r;
245 |
246 | //1. Configuration registers
247 | if (idx < CONFIG_REGS ) return idx;
248 | idx -= CONFIG_REGS;
249 |
250 | //2. first Gateway control registers
251 | // Edge/Level
252 | // Interrupt Pending/Acknowledge
253 | if (idx < EL_REGS ) return idx;
254 | idx -= EL_REGS;
255 |
256 | //3. PLIC Core fabric registers
257 | if (idx < PRIORITY_REGS) return idx;
258 | idx -= PRIORITY_REGS;
259 | if (idx < IE_REGS ) return idx;
260 | idx -= IE_REGS;
261 |
262 | //4. Target registers
263 | if (idx < THRESHOLD_REGS) return idx;
264 | idx -= THRESHOLD_REGS;
265 | return idx;
266 | endfunction : register_idx
267 |
268 |
269 | function automatic int address2register;
270 | //Translate 'address' into register number
271 | input [ADDR_SIZE-1:0] address;
272 |
273 | return address / DATA_BYTES;
274 | endfunction : address2register
275 |
276 |
277 | function automatic [TARGETS-1:0] gen_claim;
278 | //generate internal 'claim' signal
279 | input re;
280 | input [ADDR_SIZE-1:0] address;
281 |
282 | int r, idx;
283 |
284 | r = address2register(address);
285 | idx = register_idx(r);
286 |
287 | if (register_function(r) == ID && re)
288 | return (1 << idx);
289 | else
290 | return {TARGETS{1'b0}};
291 | endfunction : gen_claim
292 |
293 |
294 | function automatic [SOURCES-1:0] gen_complete;
295 | //generate internal 'complete' signal
296 | input we;
297 | input [ADDR_SIZE-1:0] address;
298 |
299 | int r, idx;
300 |
301 | r = address2register(address);
302 | idx = register_idx(r);
303 |
304 | if (register_function(r) == ID && we)
305 | return (1 << idx);
306 | else
307 | return {TARGETS{1'b0}};
308 | endfunction : gen_complete
309 |
310 |
311 | function automatic [DATA_SIZE-1:0] encode_config;
312 | //encode 'rdata' when reading from CONFIG
313 | input int r; //which register
314 |
315 | logic [MAX_SOURCES_BITS -1:0] sources_bits;
316 | logic [MAX_TARGETS_BITS -1:0] targets_bits;
317 | logic [MAX_PRIORITY_BITS-1:0] priority_bits;
318 | logic has_th_bit;
319 |
320 | sources_bits = SOURCES;
321 | targets_bits = TARGETS;
322 | priority_bits = PRIORITIES;
323 | has_th_bit = HAS_THRESHOLD ? 1'b1 : 1'b0;
324 |
325 | if (CONFIG_REGS == 1)
326 | return {15'h0,has_th_bit,priority_bits,targets_bits,sources_bits};
327 | else
328 | if (r == 0)
329 | return {targets_bits,sources_bits};
330 | else
331 | return {15'h0,has_th_bit,priority_bits};
332 | endfunction : encode_config
333 |
334 |
335 | function automatic [DATA_SIZE-1:0] encode_p;
336 | //encode 'rdata' when reading from PRIORITY
337 | input int r; //which register
338 |
339 | //clear all bits
340 | encode_p = {DATA_SIZE{1'b0}};
341 |
342 | //move PRIORITY fields into bit-positions
343 | if ((r+1)*PRIORITY_FIELDS_PER_REG <= SOURCES)
344 | for (int n=0; n < PRIORITY_FIELDS_PER_REG; n++)
345 | encode_p |= p[r*PRIORITY_FIELDS_PER_REG +n] << (n * PRIORITY_NIBBLES*4);
346 | else
347 | for (int n=0; n < SOURCES % PRIORITY_FIELDS_PER_REG; n++)
348 | encode_p |= p[r*PRIORITY_FIELDS_PER_REG +n] << (n * PRIORITY_NIBBLES*4);
349 | endfunction : encode_p
350 |
351 |
352 | function automatic [PRIORITY_BITS-1:0] decode_p;
353 | //extract/decode 'priority' fields from PRIORITY-register
354 | input int r; //which register
355 | input int s; //which field (source)
356 |
357 | logic [DATA_SIZE-1:0] tmp;
358 | int field;
359 |
360 | field = s % PRIORITY_FIELDS_PER_REG;
361 | tmp = registers[r];
362 | tmp = tmp >> (field * PRIORITY_NIBBLES * 4);
363 | return tmp[PRIORITY_BITS-1:0];
364 | endfunction : decode_p
365 |
366 |
367 | function automatic [DATA_SIZE-1:0] encode_th;
368 | //encode 'rdata' when reading from THRESHOLD
369 | input int r; //which register
370 |
371 | //clear all bits
372 | encode_th = {DATA_SIZE{1'b0}};
373 |
374 | //move THRESHOLD fields into bit-positions
375 | if ((r+1)*PRIORITY_FIELDS_PER_REG <= TARGETS)
376 | for (int n=0; n < PRIORITY_FIELDS_PER_REG; n++)
377 | encode_th |= p[r*PRIORITY_FIELDS_PER_REG +n] << (n * PRIORITY_NIBBLES*4);
378 | else
379 | for (int n=0; n < TARGETS % PRIORITY_FIELDS_PER_REG; n++)
380 | encode_th |= p[r*PRIORITY_FIELDS_PER_REG +n] << (n * PRIORITY_NIBBLES*4);
381 | endfunction : encode_th
382 |
383 |
384 | /** Display Register layout/map
385 | */
386 | //synopsys translate_off
387 | function string register_function_name;
388 | //returns the 'string' name associated with a register type
389 | input register_types function_number;
390 |
391 | string name_array[register_types];
392 | name_array[CONFIG ] = "Configuration";
393 | name_array[EL ] = "Edge/Level";
394 | name_array[IE ] = "Interrupt Enable";
395 | name_array[PRIORITY ] = "Interrupt Priority";
396 | name_array[THRESHOLD] = "Priority Threshold";
397 | name_array[ID ] = "ID";
398 |
399 | return name_array[function_number];
400 | endfunction : register_function_name
401 |
402 |
403 | //Display IP configuration; register map
404 | task display_configuration;
405 | $display ("------------------------------------------------------------");
406 | $display (" ,------. ,--. ,--. ");
407 | $display (" | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. ");
408 | $display (" | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' ");
409 | $display (" | |\\ \\ ' '-' '\\ '-' | | '--.' '-' ' '-' || |\\ `--. ");
410 | $display (" `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' ");
411 | $display (" `---' ");
412 | $display (" RISC-V Platform Level Interrupt Controller ");
413 |
414 | $display ("- Configuration Report -------------------------------------");
415 | $display (" Sources | Targets | Priority-lvl | Threshold? | Event-Cnt ");
416 | $write (" %4d |", SOURCES);
417 | $write (" %3d |", TARGETS);
418 | $write (" %5d |", PRIORITIES);
419 | $write (" %5s |", HAS_THRESHOLD ? "YES" : "NO");
420 | $display(" %3d ", MAX_PENDING_COUNT);
421 |
422 | $display ("- Register Map ---------------------------------------------");
423 | display_register_map();
424 |
425 | $display ("- End Configuration Report ---------------------------------");
426 | endtask : display_configuration
427 |
428 | task display_register_map;
429 | int address;
430 |
431 | $display (" Address Function Mapping");
432 | for (int r=0; r < TOTAL_REGS; r++)
433 | begin
434 | //display address + function
435 | address = r * (DATA_SIZE / 8);
436 | $write (" 0x%04x %-23s", address, register_function_name(register_function(r)));
437 |
438 | //display register mapping
439 | case ( register_function(r) )
440 | CONFIG : display_config_map ( register_idx(r) );
441 | EL : display_el_map ( register_idx(r) );
442 | PRIORITY : display_priority_map ( register_idx(r) );
443 | IE : display_ie_map ( register_idx(r) );
444 | THRESHOLD: display_threshold_map( register_idx(r) );
445 | ID : display_id_map ( register_idx(r) );
446 | default : $display("");
447 | endcase
448 | end
449 | endtask : display_register_map
450 |
451 | task display_config_map;
452 | input int r;
453 |
454 | if (CONFIG_REGS == 1)
455 | $display ("15'h0,TH,PRIORITES,TARGETS,SOURCES");
456 | else
457 | if (r == 0)
458 | $display ("TARGETS,SOURCES");
459 | else
460 | $display ("15'h0,TH,PRIORITIES");
461 | endtask : display_config_map
462 |
463 | task display_el_map;
464 | input int r;
465 |
466 | if ((r+1)*DATA_SIZE <= SOURCES)
467 | $display ("EL[%0d:%0d]", (r+1)*DATA_SIZE -1, r*DATA_SIZE);
468 | else
469 | $display ("%0d'h0, EL[%0d:%0d]", (r+1)*DATA_SIZE-SOURCES, SOURCES-1, r*DATA_SIZE);
470 | endtask : display_el_map
471 |
472 | task display_ie_map;
473 | input int ri;
474 |
475 | int target, r;
476 |
477 | target = ri / EL_REGS;
478 | r = ri % EL_REGS;
479 |
480 | if ((r+1)*DATA_SIZE <= SOURCES)
481 | $display ("IE[%0d][%0d:%0d]", target, (r+1)*DATA_SIZE -1, r*DATA_SIZE);
482 | else
483 | $display ("%0d'h0, IE[%0d][%0d:%0d]", (r+1)*DATA_SIZE-SOURCES, target, SOURCES-1, r*DATA_SIZE);
484 | endtask : display_ie_map
485 |
486 | task display_priority_map;
487 | input int r;
488 |
489 | if ((r+1)*PRIORITY_FIELDS_PER_REG <= SOURCES)
490 | begin
491 | for (int s=(r+1)*PRIORITY_FIELDS_PER_REG -1; s >= r*PRIORITY_FIELDS_PER_REG; s--)
492 | begin
493 | if (PRIORITY_BITS % 4) $write("%0d'b0,", 4- (PRIORITY_BITS % 4));
494 | $write ("P[%0d][%0d:%0d]", s, PRIORITY_BITS -1, 0);
495 | if (s != r*PRIORITY_FIELDS_PER_REG) $write(",");
496 | end
497 | end
498 | else
499 | begin
500 | $write ("%0d'h0,", DATA_SIZE - (SOURCES-r*PRIORITY_FIELDS_PER_REG) * PRIORITY_NIBBLES*4);
501 |
502 | for (int s=SOURCES-1; s >= r*PRIORITY_FIELDS_PER_REG; s--)
503 | begin
504 | if (PRIORITY_BITS % 4) $write("%0d'b0,", 4- (PRIORITY_BITS % 4));
505 | $write ("P[%0d][%0d:%0d]", s, PRIORITY_BITS -1, 0);
506 | if (s != r*PRIORITY_FIELDS_PER_REG) $write(",");
507 | end
508 | end
509 |
510 | $display("");
511 | endtask : display_priority_map
512 |
513 | /*
514 | task display_threshold_map;
515 | input int r;
516 |
517 | if ((r+1)*PRIORITY_FIELDS_PER_REG <= TARGETS)
518 | begin
519 | for (int t=(r+1)*PRIORITY_FIELDS_PER_REG -1; t >= r*PRIORITY_FIELDS_PER_REG; t--)
520 | begin
521 | if (PRIORITY_BITS % 4) $write("%0d'b0,", 4- (PRIORITY_BITS % 4));
522 | $write ("Th[%0d][%0d:%0d]", t, PRIORITY_BITS -1, 0);
523 | if (t != r*PRIORITY_FIELDS_PER_REG) $write(",");
524 | end
525 | end
526 | else
527 | begin
528 | $write ("%0d'h0,", DATA_SIZE - (TARGETS-r*PRIORITY_FIELDS_PER_REG) * PRIORITY_NIBBLES*4);
529 |
530 | for (int t=TARGETS-1; t >= r*PRIORITY_FIELDS_PER_REG; t--)
531 | begin
532 | if (PRIORITY_BITS % 4) $write("%0d'b0,", 4- (PRIORITY_BITS % 4));
533 | $write ("Th[%0d][%0d:%0d]", t, PRIORITY_BITS -1, 0);
534 | if (t != r*PRIORITY_FIELDS_PER_REG) $write(",");
535 | end
536 | end
537 |
538 | $display("");
539 | endtask : display_threshold_map
540 | */
541 |
542 | task display_threshold_map;
543 | input int r;
544 |
545 | $display ("%0d'h0, Th[%0d][%0d:%0d]", DATA_SIZE-PRIORITY_BITS, r, PRIORITY_BITS-1, 0);
546 | endtask : display_threshold_map
547 |
548 |
549 | task display_id_map;
550 | input int r;
551 |
552 | $display ("%0d'h0, ID[%0d][%0d:%0d]", DATA_SIZE-SOURCES_BITS, r, SOURCES_BITS-1, 0);
553 | endtask : display_id_map
554 |
555 | //synopsys translate_on
556 |
557 |
558 | //////////////////////////////////////////////////////////////////
559 | //
560 | // Module Body
561 | //
562 | //synopsys translate_off
563 | initial display_configuration();
564 | //synopsys translate_on
565 |
566 |
567 | /** Write Registers
568 | *
569 | * This core has a dynamic array of registers, depending on the
570 | * parameter settings
571 | * Writing to the ID register generates a strobe
572 | */
573 | assign write_register = address2register(waddr);
574 |
575 | always @(posedge clk,negedge rst_n)
576 | if (!rst_n)
577 | for (int n=0; n < TOTAL_REGS; n++)
578 | registers[n] <= 'h0;
579 | else if (we)
580 | case (register_function(write_register))
581 | ID : ; //A write to ID generates a strobe signal
582 | default: registers[write_register] <= gen_wval( registers[write_register], wdata, be);
583 | endcase
584 |
585 |
586 | /** Claim / Complete
587 | * Special cases for Claim / Complete
588 | * A read generates a claim strobe
589 | * A write doesn't access the register, but generates a complete strobe instead
590 | */
591 | always @(posedge clk, negedge rst_n)
592 | if (!rst_n) claim <= 0;
593 | else claim <= gen_claim(re, raddr);
594 |
595 | always @(posedge clk, negedge rst_n)
596 | if (!rst_n) complete <= 0;
597 | else complete <= gen_complete(we, waddr);
598 |
599 |
600 | /** Decode registers
601 | */
602 | generate
603 | genvar r, t, s;
604 |
605 | for (r=0; r < TOTAL_REGS; r++)
606 | begin : decode_registers
607 | case ( register_function(r) )
608 | //Decode EL register(s)
609 | // There are SOURCES EL-bits, spread out over
610 | // DATA_SIZE wide registers
611 | EL : begin
612 | if ( (register_idx(r)+1) * DATA_SIZE <= SOURCES )
613 | assign el[register_idx(r) * DATA_SIZE +: DATA_SIZE] = registers[r];
614 | else
615 | assign el[SOURCES-1:register_idx(r) * DATA_SIZE] = registers[r];
616 | end
617 |
618 | //Decode PRIORITY register(s)
619 | // There are SOURCES priority-fields, each PRIORITY_BITS
620 | // wide, spread out over DATA_SIZE wide registers,
621 | // with each field starting at a nibble boundary
622 | // Need to use always_comb, because we're not assigning a fixed value
623 | PRIORITY : begin
624 | if ( (register_idx(r)+1) * PRIORITY_FIELDS_PER_REG <= SOURCES )
625 | for (s = register_idx(r) * PRIORITY_FIELDS_PER_REG;
626 | s < (register_idx(r)+1) * PRIORITY_FIELDS_PER_REG;
627 | s++)
628 | begin : decode_p0
629 | always_comb p[s] = decode_p(r,s);
630 | end
631 | else
632 | for (s = register_idx(r) * PRIORITY_FIELDS_PER_REG;
633 | s < SOURCES;
634 | s++)
635 | begin : decode_p1
636 | always_comb p[s] = decode_p(r,s);
637 | end
638 | end
639 |
640 | //Decode IE register(s)
641 | // For each TARGET there's SOURCES IE-fields
642 | // Layout is the same as for the EL-registers, with each
643 | // TARGET starting at a new register
644 | IE : begin
645 | if ( ((register_idx(r) % EL_REGS)+1) * DATA_SIZE <= SOURCES )
646 | assign ie[register_idx(r) / EL_REGS][(register_idx(r) % EL_REGS) * DATA_SIZE +: DATA_SIZE] = registers[r];
647 | else
648 | assign ie[register_idx(r) / EL_REGS][SOURCES-1 : (register_idx(r) % EL_REGS) * DATA_SIZE] = registers[r];
649 | end
650 |
651 | /*
652 | //Decode THRESHOLD register(s)
653 | // There are TARGETS threshold-fields, each PRIORITY_BITS
654 | // wide, spread out over DATA_SIZE wide registers,
655 | // with each field starting at a nibble boundary
656 | THRESHOLD: if (HAS_THRESHOLD)
657 | begin
658 | if ( (register_idx(r)+1) * PRIORITY_FIELDS_PER_REG <= TARGETS )
659 | for (t = register_idx(r) * PRIORITY_FIELDS_PER_REG;
660 | t < (register_idx(r)+1) * PRIORITY_FIELDS_PER_REG;
661 | t++)
662 | begin : decode_th0
663 | always_comb
664 | begin
665 | logic [DATA_SIZE-1:0] tmp; //local variable
666 | tmp = registers[r];
667 | tmp = tmp >> (t * PRIORITY_NIBBLES);
668 | th[t] = tmp[PRIORITY_BITS-1:0];
669 | end
670 | end
671 | else
672 | for (t = register_idx(r) * PRIORITY_FIELDS_PER_REG;
673 | t < TARGETS;
674 | t++)
675 | begin : decode_th1
676 | always_comb
677 | begin
678 | logic [DATA_SIZE-1:0] tmp; //local variable
679 | tmp = registers[r];
680 | tmp = tmp >> (t * PRIORITY_NIBBLES);
681 | th[t] = tmp[PRIORITY_BITS-1:0];
682 | end
683 | end
684 | end
685 | */
686 |
687 | THRESHOLD: if (HAS_THRESHOLD)
688 | begin
689 | assign th[register_idx(r)] = registers[r][PRIORITY_BITS-1:0];
690 | end
691 | endcase
692 | end
693 | endgenerate
694 |
695 |
696 | /** Read Registers
697 | */
698 | assign read_register = address2register(raddr);
699 | assign read_register_idx = register_idx(read_register);
700 |
701 | always @(posedge clk, negedge rst_n)
702 | if (!rst_n) rdata <= {$bits(rdata){1'b0}};
703 | else if (re)
704 | case ( register_function(read_register) )
705 | CONFIG : if (HAS_CONFIG_REG) rdata <= encode_config(read_register_idx);
706 | EL : rdata <= el >> (read_register_idx * DATA_SIZE);
707 | PRIORITY : rdata <= encode_p(read_register_idx);
708 | IE : rdata <= ie[read_register_idx / EL_REGS] >> ((read_register_idx % EL_REGS) * DATA_SIZE);
709 | // THRESHOLD: if (HAS_THRESHOLD) rdata <= encode_th(read_register_idx);
710 | THRESHOLD: if (HAS_THRESHOLD) rdata <= th[read_register_idx];
711 | ID : rdata <= id[read_register_idx];
712 | endcase
713 |
714 | endmodule : plic_dynamic_registers
715 |
716 |
--------------------------------------------------------------------------------