Merge batman content

This commit is contained in:
Xiretza 2020-03-22 18:54:41 +01:00
commit ed378c0917
Signed by: xiretza
GPG key ID: E51A6C6A1EB378ED
27 changed files with 726 additions and 37 deletions

2
.gitignore vendored
View file

@ -27,4 +27,4 @@
work-*.cf work-*.cf
svg-inkscape/ svg-inkscape/
core/entities/ /sections/core/entities/

73
Diplomschrift.bib Normal file
View file

@ -0,0 +1,73 @@
@online{nandgame,
author = {Olav Junker Kjær},
title = {The Nand Game},
url = {http://nandgame.com},
}
@online{breadboard_computer,
author = {Ben Eater},
title = {Building an 8-bit breadboard computer!},
url = {https://www.youtube.com/playlist?list=PLowKtXNTBypGqImE405J2565dvjafglHU},
year = {2016},
}
@unpublished{yosys-paper,
author = {Clifford Wolf, Johann Glaser},
title = {Yosys - A Free Verilog Synthesis Suite},
url = {http://www.clifford.at/yosys/files/yosys-austrochip2013.pdf},
year = {2013},
}
@software{yosys,
author = {Various Contributors},
title = {Yosys - Yosys Open SYnthesis Suite},
url = {https://github.com/YosysHQ/yosys},
}
@software{nextpnr,
author = {Various Contributors},
title = {nextpnr - a portable FPGA place and route tool},
url = {https://github.com/YosysHQ/nextpnr},
}
@software{nextpnr-xilinx,
author = {David Shah},
title = {nextpnr-xilinx},
url = {https://github.com/daveshah1/nextpnr-xilinx},
}
@online{prjxray,
author = {SymbiFlow},
title = {Project X-Ray},
url = {https://github.com/SymbiFlow/prjxray},
}
@software{ghdlsynth-beta,
author = {Tristan Gingold},
title = {ghdlsynth-beta},
url = {https://github.com/tgingold/ghdlsynth-beta},
}
@software{ghdl,
author = {Tristan Gingold},
title = {ghdl},
url = {https://github.com/ghdl/ghdl},
}
@software{liteeth,
author = {Florent Kermarrec},
title = {LiteEth},
url = {https://github.com/enjoy-digital/liteeth}
}
@software{open-fpga-loader,
author = {Gwenhael Goavec-Merou},
title = {openFPGALoader},
url = {https://github.com/trabucayre/openFPGALoader},
}
@software{gtkwave,
author = {Tony Bybell},
title = {GTKWave},
url = {http://gtkwave.sourceforge.net},
}

View file

@ -1,4 +1,6 @@
\input{preamble.tex} \input{preamble.tex}
\usepackage{subfiles}
\begin{document} \begin{document}
\selectlanguage{ngerman} \selectlanguage{ngerman}
@ -125,6 +127,9 @@ geschlechtsunabh"angig verstanden werden soll.
\clearpage \clearpage
%\MR\input{sections/Kapitel/MR/EntwicklungAufgaben.tex} %\MR\input{sections/Kapitel/MR/EntwicklungAufgaben.tex}
\subfile{sections/vhdl_intro/vhdl_intro.tex}
\subfile{sections/soc/soc.tex}
\subfile{sections/core/core.tex}
%==================================================================================== %====================================================================================
\clearpage\vfill\newpage{} \clearpage\vfill\newpage{}
@ -202,4 +207,3 @@ geschlechtsunabh"angig verstanden werden soll.
\label{LastPage} \label{LastPage}
%\addtocontents{toc}{\protect\end{multicols}} %\addtocontents{toc}{\protect\end{multicols}}
\end{document} \end{document}

35
Makefile Normal file
View file

@ -0,0 +1,35 @@
ifndef YARM_DIRECTORY
$(error YARM_DIRECTORY must be set to the root directory of the YARM SoC)
endif
VHDL_DIR = $(YARM_DIRECTORY)/vhdl
CODEDIR = code
.PHONY: all
all: Diplomschrift.pdf
$(CODEDIR):
mkdir -p $@
define headers_template =
$1: $2
mkdir -p $1
./generate_entity_headers.py --skip-missing --dest-dir $1 $2
HEADER_DIRS += $1
endef
$(eval $(call headers_template,sections/core/entities/,$(wildcard $(VHDL_DIR)/core/*.vhd)))
.PHONY: entity_headers
entity_headers: $(HEADER_DIRS)
.PHONY: Diplomschrift.pdf
Diplomschrift.pdf: $(HEADER_DIRS) Diplomschrift.tex
latexmk --pdfxe --pdfxelatex="xelatex -interaction=nonstopmode --shell-escape" --use-make Diplomschrift.tex
.PHONY: clean
clean:
rm -rf $(HEADER_DIRS)
latexmk -C

54
generate_entity_headers.py Executable file
View file

@ -0,0 +1,54 @@
#!/usr/bin/python
import argparse
import logging
import os
import re
import sys
#declaration_match = re.compile(r'^entity (?P<entity_name>.*?) is$.*?^end (?:(?P=entity_name)|entity);$', re.MULTILINE | re.DOTALL)
declaration_match = re.compile(r'^entity (?P<entity_name>.*?) is$.*?^end (?P=entity_name);$', re.MULTILINE | re.DOTALL)
def directory_path(string):
if os.path.isdir(string):
return string
else:
raise NotADirectoryError(string)
def get_parser():
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--dest-dir', help='The destination directory to store the entity headers in', type=directory_path)
parser.add_argument('source_files', nargs='*', type=argparse.FileType('r'))
parser.add_argument('--pattern', default='{entity_name}_entity.vhd', help='The pattern to use for the destination filename. Available substitutions: {entity_name}.')
parser.add_argument('-s', '--skip-missing', action='store_true', help='Skip over files missing an entity declaration')
parser.add_argument('-v', '--verbose', action='count')
return parser
def parse_header(src_file):
if m := re.search(declaration_match, src_file.read()):
return (m.group('entity_name'), m.group(0))
else:
return None
if __name__ == '__main__':
parser = get_parser()
args = parser.parse_args()
logging.basicConfig(level=args.verbose)
for src_file in args.source_files:
if res := parse_header(src_file):
(entity_name, declaration) = res
dest_file_path = os.path.join(args.dest_dir, args.pattern.format_map({'entity_name': entity_name}))
logging.info(f'Writing header for {entity_name} to {dest_file_path}')
with open(dest_file_path, 'w') as destfile:
destfile.write(declaration)
else:
errmsg = f'No entity declaration found in {src_file.name}'
if args.skip_missing:
logging.warning(errmsg)
else:
logging.error(errmsg)
sys.exit(1)

View file

@ -50,27 +50,45 @@
\usepackage{ifpdf} % fuer {\ifpdf ... \fi} \usepackage{ifpdf} % fuer {\ifpdf ... \fi}
\usepackage{beramono} % monospace font -MR \usepackage{beramono} % monospace font -MR
\usepackage{listings} \usepackage{listings}
\lstset
{ \lstdefinestyle{default}{
columns=space-flexible, columns=space-flexible,
basicstyle=\fontsize{9pt}{9pt}\selectfont\ttfamily, basicstyle=\fontsize{9pt}{9pt}\selectfont\ttfamily,
frame=single, frameround=tttt, frame=single,
showstringspaces=false, breaklines=true, frameround=tttt,
tabsize=4, numbers=left, showstringspaces=false,
breaklines=true,
tabsize=4,
numbers=left,
captionpos=b captionpos=b
} }
% normal font size for inline listings
\makeatletter
\makeatother
\lstdefinestyle{terminal}{ \lstdefinestyle{terminal}{
style=default,
language=bash, language=bash,
frame=none, frame=none,
numbers=none, numbers=none,
backgroundcolor=\color{ltgy} backgroundcolor=\color{ltgy}
} }
\lstdefinelanguage{customvhdl}[]{VHDL}{
morekeywords=[2]{std_logic, std_logic_vector, natural, integer, bit, string},
}
\lstdefinestyle{vhdlstyle}{
language=customvhdl,
belowcaptionskip=1\baselineskip,
keywordstyle=\bfseries\color{green!40!black},
keywordstyle=[2]\bfseries\color{blue!80!white},
commentstyle=\itshape\color{purple},
backgroundcolor=\color{lightgray!20},
stringstyle=\color{orange},
xleftmargin=\parindent,
title=\lstname,
}
\lstset{ \lstset{
style=default,
literate={ö}{{\"o}}1 literate={ö}{{\"o}}1
{ä}{{\"a}}1 {ä}{{\"a}}1
{ü}{{\"u}}1 {ü}{{\"u}}1
@ -90,7 +108,7 @@
\usepackage{fancyhdr} \usepackage{fancyhdr}
%\usepackage{framed} %'\begin{framed}' ... '\end{framed}', schautAusWiePartezettel:-) %\usepackage{framed} %'\begin{framed}' ... '\end{framed}', schautAusWiePartezettel:-)
\usepackage{hyphenat} %fuer '\hyph{}' \usepackage{hyphenat} %fuer '\hyph{}'
%\usepackage{lastpage} %fuer '\pageref{LastPage}' - **funzt nid bei allen** \usepackage{lastpage} %fuer '\pageref{LastPage}' - **funzt nid bei allen**
\usepackage[hyphens]{url} %fuer '\url{...}' \usepackage[hyphens]{url} %fuer '\url{...}'
% lscape oder pdflscape: ('landscape' == Querformat) % lscape oder pdflscape: ('landscape' == Querformat)
@ -141,12 +159,15 @@
\usepackage{tabularx} % Allows the H floating option \usepackage{tabularx} % Allows the H floating option
\usepackage[headheight=0mm, margin=2.5cm]{geometry} \usepackage[headheight=0mm, margin=2.5cm]{geometry}
%%% MR-packages: %%% MR-packages:
%\usepackage[]{hyperref} \usepackage{hyperref}
\usepackage[pdfauthor={tyrolyean,xiretza}, \hypersetup{
pdftitle={YARM}, pdfauthor={Daniel Plank, Armin Brauns},
pdfproducer={5ABHN}, pdftitle=YARM,
pdfproducer=5ABHEL,
bookmarks=true, bookmarks=true,
pdfcreator={xelatex}]{hyperref} pdfcreator=xelatex,
}
\usepackage{tikz,pgfplots} \usepackage{tikz,pgfplots}
\usetikzlibrary{plotmarks} \usetikzlibrary{plotmarks}
\usetikzlibrary{angles,quotes,babel,shapes,arrows,positioning,calc} \usetikzlibrary{angles,quotes,babel,shapes,arrows,positioning,calc}
@ -179,7 +200,6 @@ minimum height=1cm, align=center, text width=3cm, draw=black, fill=blue!30]
\usepackage{mdframed} \usepackage{mdframed}
\usepackage{lipsum} \usepackage{lipsum}
\usepackage{blindtext} \usepackage{blindtext}
\usepackage{titlesec}
\usepackage{pgfgantt} \usepackage{pgfgantt}
%%% Title formatting %%% Title formatting
@ -197,19 +217,16 @@ minimum height=1cm, align=center, text width=3cm, draw=black, fill=blue!30]
% command for regular footer in ToC % command for regular footer in ToC
\fancypagestyle{plain}{% \fancypagestyle{plain}{%
\fancyhf{} \fancyhf{}
\lhead{\HtlHeader} \fancyhead[L]{\HtlHeader}
\chead{} \fancyfoot[L]{Brauns, Plank}
\rhead{} \fancyfoot[R]{\thepage}
\lfoot{Brauns, Plank}
\cfoot{}
\rfoot[\thepage]{\thepage}
\setlength{\headwidth}{1.0\textwidth} \setlength{\headwidth}{1.0\textwidth}
\setlength{\headheight}{12mm} \setlength{\headheight}{12mm}
\renewcommand{\headrulewidth}{0.0pt} \renewcommand{\headrulewidth}{0.0pt}
\renewcommand{\footrulewidth}{0.33pt} \renewcommand{\footrulewidth}{0.33pt}
} }
% make listoflistings it's own section % make listoflistings its own section
\usepackage{tocbasic} \usepackage{tocbasic}
\addtotoclist[float]{lol} \addtotoclist[float]{lol}
\renewcommand*\lstlistoflistings{\listoftoc[{\lstlistlistingname}]{lol}} \renewcommand*\lstlistoflistings{\listoftoc[{\lstlistlistingname}]{lol}}
@ -279,4 +296,40 @@ minimum height=1cm, align=center, text width=3cm, draw=black, fill=blue!30]
%\hfill %\hfill
}%HtlHeader }%HtlHeader
\sloppy \addbibresource{Diplomschrift.bib}
\usepackage{titling}
\usepackage{datetime}
\yyyymmdddate
\renewcommand{\dateseparator}{-}
\setlength{\parindent}{0pt}
\setlength{\parskip}{1em}
\usepackage{footnote}
\newcommand\instrset{rv32i}
\newcommand{\entityheader}[2]{
\lstinputlisting[style=vhdlstyle,title=\texttt{#2}]{#1}
}
\usepackage{tcolorbox}
\newtcbox{\codeBox}[1][gray]{
on line,
arc=2pt,
colback=black!5,
colupper=black!80,
colframe=black!20,
before upper={
\rule[-3pt]{0pt}{10pt}
},
boxrule=1pt,
boxsep=0pt,
left=3pt,
right=3pt,
top=2pt,
bottom=0pt
}
\newcommand{\icode}[1]{\codeBox{\texttt{#1}}}

76
sections/core/core.tex Normal file
View file

@ -0,0 +1,76 @@
\documentclass[../../Diplomschrift.tex]{subfiles}
\begin{document}
\part{The Core}
The core implements the \instrset{} architecture as specified by the RISC-V standard.
It is constructed according to the traditional RISC pipeline:
\begin{description}
\item[Fetch] fetches the next instruction from memory.
\item[Decode] decodes the instruction into its constituent parts. At the same time, operand values are loaded from any required registers.
\item[Execute] performs the action required by the instruction, such as math performed by the Arithmetic Logic Unit (ALU) or writing to Control and Status Registers (CSRs).
\item[Memory] loads values from or stores values to the system's main memory or interacts with memory-mapped hardware devices.
\item[Writeback] stores a potential result value from Execute or Memory stages to the destination register.
\end{description}
\section{Overview}
\begin{figure}
%\includegraphics[width=\textwidth]{core_diagram.png}
% TODO
\caption{Block diagram of the CPU core}
\end{figure}
\section{Control}
\entityheader{entities/control_entity.vhd}{control.vhd}
The control unit is responsible for coordinating subcomponents and the data flow between them. Internally, it is based on \icode{instruction\_info\_t} structures, which contain all the information required to pass an instruction along the different pipeline stages. Before the fetch stage, when an instruction is first scheduled, it contains only the instruction's address (because nothing else is known about it). Then, information is added incrementally by the different stages.
\section{Decoder}
\entityheader{entities/decoder_entity.vhd}{decoder.vhd}
The decoder receives an instruction and interprets it. Among others, it determines
\begin{itemize}
\item The source and destination register addresses
\item The pipeline stages that need to be run for the instruction
\item The ALU operation, if any
\item Whether the instruction should branch, and if so, under what condition
\end{itemize}
\section{Registers}
\entityheader{entities/registers_entity.vhd}{registers.vhd}
The registers store the 32 general-purpose values required by \instrset{} (each 32-bit wide). They are accessible through two read ports and one write port. As specified by the RISC-V standard, the first register (\icode{x0}) is hard-wired to 0, and any writes to it are ignored.
\section{Arithmetic and Logic Unit (ALU)}
\entityheader{entities/alu_entity.vhd}{alu.vhd}
The ALU contains a math/logic unit as well as a comparator. It is used both explicitly by instructions such as \icode{add} or \icode{shiftl}, as well as to add offsets to base addresses for memory instructions and to decide whether an instructions should branch.
\section{Control and Status Registers (CSR)}
\entityheader{entities/csr_entity.vhd}{csr.vhd}
The control and status registers contain configurations relevant to the core itself. For example, they can be used to control interrupts.
\section{Memory Arbiter}
\entityheader{entities/memory_arbiter_entity.vhd}{memory\_arbiter.vhd}
Since both fetch and memory stages need to access the same system memory, access to this common resource has to be controlled. The memory arbiter acts as a proxy for both fetch and data memory requests and stalls either until the other one completes.
\section{Exception Control}
\entityheader{entities/exception_control_entity.vhd}{exception\_control.vhd}
Several components in the core may raise a synchronous exception when an unexpected error (such as a malformed instruction or an unaligned memory access) occurs. Additionally, asynchronous interrupts (like from a timer or a UART) can be triggered externally. When an exception or an enabled interrupt is registered, program flow is diverted to the trap handler, defined using the machine trap vector (\icode{mtvec}) CSR.
\end{document}

View file

@ -0,0 +1 @@
<mxfile host="www.draw.io" modified="2019-12-11T07:44:55.731Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.13.2 Chrome/73.0.3683.105 Safari/537.36" etag="cypgiirZT7mhMw4UHRcL" version="12.3.9" type="device" pages="1"><diagram id="-MZbLzNk5HDaKAr47o4G" name="Page-1">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</diagram></mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View file

@ -0,0 +1 @@
../../Diplomschrift.bib

View file

@ -0,0 +1 @@
<mxfile host="www.draw.io" modified="2020-02-29T14:33:08.452Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.14.1 Chrome/77.0.3865.129 Safari/537.36" etag="1-3t6E_GoiRp_pFxnjN3" version="12.7.9" type="device"><diagram id="A6fsjPniKipRtEl5BEvI" name="Page-1">7Vvbkps4EP0aP2YKENdHzy2pyk5lK7O1mzxtaUDG2sGIFfIY5+tXMuIiZBzfsGPPVqVqTEtq4JzTrW4gI3A3Kz5SmE2fSISSkWVExQjcjyzLtayR+GdEy9IAnKA0xBRHpclsDM/4B5JGQ1rnOEK5MpERkjCcqcaQpCkKmWKDlJKFOm1CEvWsGYyRZngOYaJb/8IRm0qraxjNwCeE46k8dVANzGA1WRryKYzIomUCDyNwRwlh5a9ZcYcSgV2FS7nusWe0vjCKUrbNApx8jpH76bPzBaLHxevf+e3E+mBKenK2rO4YRRwAeUgom5KYpDB5aKy3lMzTCAm3Bj9q5vxGSMaNJjf+gxhbSjbhnBFumrJZIkdRgdk3sfzGc+Thd+lN/L4v2gfL6iBldFmuspzq+Ht7sFm3OqoW5oyS15o9cf7ynsWN9mIpTTmZ0xBtAlBqEtIYsQ3zQM04jxREZohfIV9HUQIZflOvA0rNxvU8uXRMKVy2JmQEpyxvef5dGPgEGX02h3flcVnLVpVIZ77vGZvm8x/lFVRHrVtpTCvZ7SJB57wS3F6BupBamvR20uSlKlCTTAA6krEN1UV5XXJVo6WdpWx1zhNslrI23948v+8+hpV+eco3mMwl/n9+HAsu8Qynsdj9UIooZIRqIaIGwGKKGXrO4EooC74Rq2Kf4CS5Iwl3I9aCCCJ/EtaCbo24oY9eJrU+3xBlqNisUF1RcgEI1jNmLFr7aMXStLWFeh0FtUXY4mMPuME5M43ZzjN11vnZXqcklRvnJ2lFzVDOcRONdaJEcxDHwP2FChpzS5JvDqhnnJUFUjYW1S43hAnMcxxW5kec1FeZRtWklKSotMjxI29K22rFOatWgvNqxfpfKzvlFf+cYrG0vfoPVLDV6bkeKLrELdrtFj2Bs90W7Q61RQMd5af7Z6G0NCTRoSD3g9kH/xFA9u1fDWRbA1nPg034NzniwKJm0OKkh4MWxs4aiCvbgU2Q22k2tBK2vHytCVrjKFAdWY7qqKebOlZD4vQlua/jpwsMPc/wFTiBvWULMljomXrLl+Fi9cg0JIRGOIUM5RrUTLCg4AkTHKciOjkUPC2CWwEUDmEylgMzHEVlwYJy/AO+rFwJomSnzf06tyPnXvjiNUpelivmcYB3DPXBE0dUB95cA7w1GPB60gu56OZ8RzEiyODFQ+7Z3dQBNMi9kyLuaoi/5cs0vHikXcdTN3RHF/e6zWY4pD0N6emVIK3mbxPopdNpkfY1pDWQ15ZOPV2XtkFW1RHY0PPVD577er4pzMS1TBJUyFPuUGnt27KfptLyXFURtr9npeV1nk7aZsfRwJWWGWhKepnnYpUIxIkooy49er3O2yfb8rXo9U8ZvdYRGp/9XyaeK2QCt9OcdJW+bciYRrfNOXHMWHp78h7568bH/vx1PQ3Nn14Rvkf+gHks/rqehuZv3+rnuvi73Pyp1xzvkT8bHIu/rqeB+aue1mtPxy+8UDQNw1aANX0pzHP1eVViVSLFTQSqeQZTBW7337n4hO92QlL2oQRGfMMRZEUzxn/F4m+YvFZ++HWVrsqRKyCx+ryifs/haSSCk5JoDUMiRdEVk6hGomXoPdtpSdTfCB6FxBfh7npZdFUWq3x2NhbXdd5HYDGmCKVXTGMnGKuHRi0a7ZPSqDcAj2RVIn39convB51OaTjk+0F+2HzrX1aEzX+YAA//AQ==</diagram></mxfile>

BIN
sections/soc/graphics.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

146
sections/soc/soc.tex Normal file
View file

@ -0,0 +1,146 @@
\documentclass[../../Diplomschrift.tex]{subfiles}
\begin{document}
\part{Meta}
\section{History}
The project started out with the desire to build a CPU from scratch. Examples such as The NAND Game\cite{nandgame} and Ben Eater's Breadboard Computer series\cite{breadboard_computer} served as inspirations and guidance during development.
At first, a design similar to Ben Eater's consisting solely of discrete integrated circuits was considered, but soon discarded in favor of an FPGA-based design. Designing the logic alone was a difficult task, implementing it in discrete hardware would have pushed the project far over the allotted maximum development time.
RISC-V was chosen as the instruction set architecture for the processor. Its modular design with a very small base instruction set make it easy to implement a basic processor that is still fully compatible with existing software and toolchains.
As a starting point, a Terasic DE0 development board\footnote{\url{https://www.terasic.com.tw/cgi-bin/page/archive.pl?No=364}} containing an Altera Cyclone III\footnote{\url{https://www.intel.com/content/www/us/en/products/programmable/fpga/cyclone-iii.html}} FPGA was borrowed from the school's inventory. It was used to implement a first version of the core.
The only method of synthesis for Altera devices is to use the proprietary Quartus IDE. However, the last version of Quartus to support the Cyclone III series of FPGAs (version 13.1) had already been out of date for several years at the start of the project. Because of this and the increasing resource demand of the developing core, an Arty A7-35T development board\footnote{\url{https://store.digilentinc.com/arty-a7-artix-7-fpga-development-board-for-makers-and-hobbyists/}} with a Xilinx Artix-7\footnote{\url{https://www.xilinx.com/products/silicon-devices/fpga/artix-7.html}} FPGA was ordered from Digilent.
The two FPGAs compare as follows:
\begin{tabular}{l r r}
& Altera EP3C16 & Xilinx XC7A35T \\
Logic Elements & 15000 & 33280 \\
Multipliers & 56 & 90 \\
Block RAM (kb) & 504 & 1800 \\
PLLs & 4 & 5 \\
Global clocks & 20 & 32 \\
\end{tabular}
The periphery on the development boards:
\begin{tabular}{l|r|r}
& Terasic DE0 & Digilent Arty A7-35T \\
Switches & 10 & 4 \\
Buttons & 3 & 4 \\
LEDs & 10 + 4x 7-segment & 4 + 3 RGB \\
GPIOs & 2x 36 & 4x PMOD + chipKIT \\
Memory & 8MB SDRAM & 256MB DDR3L \\
Others & SD card, VGA & Ethernet \\
\end{tabular}
While the Digilent board offers fewer IO options, the DDR3 memory can be interfaced using Free memory cores and allows for much larger programs to be loaded, possibly even a full operating system. The missing VGA port has been substituted by a HDMI-compatible DVI interface that is accessible through one of the high-speed PMOD connectors.
\section{Tooling}
FPGA design is done using a Hardware Description Language (HDL). The two most well-known HDLs are Verilog and VHDL (VHSIC (Very high speed integrated circuit) HDL). As part of our studies at HTL, we exclusively worked with VHDL. For this reason, and because VHDL offers a better type system, it was chosen as the language of choice for the project.
\subsection{Vendor Tools}
The conventional way to work with FPGA designs is to use the FPGA vendor's development solution for simulation, synthesis and place-and-route. All of these tools are proprietary software specialized to a certain FPGA manufacturer, so a change of hardware also requires changing to a completely different software solution.
Vendor tools are usually free-of-charge for basic usage, but this also means there is no guaranteed support. During the development of this project, several bugs and missing features were found in vendor tools that required workarounds.
\subsection{Free Software Tools}
A somewhat recent development is the creation of Free Software\footnotemark{} FPGA toolchains. A breakthrough was achieved by Claire (formerly Clifford) Wolf in 2013 with yosys\cite{yosys-paper, yosys}, a feature-complete Verilog synthesis suite for Lattice's \texttt{iCE40} FPGA series.
\footnotetext{``Free Software'' refers to software that grants its user the freedom to share, study and modify it - see \url{https://www.fsf.org/about/what-is-free-software}.}
Since then, both yosys and place-and-route tools like nextpnr\cite{nextpnr} have matured, however Lattice's iCE40 and ECP5 remained the only supported FPGA architectures for place-and-route.
Thus, two obstacles remained for Free toolchains to be viable for this project: synthesizing \emph{from} VHDL code and synthesizing \emph{to} Artix-7 FPGAs. During the development of the project, both of these were solved: Tristan Gingold released ghdlsynth-beta\parencite*{ghdlsynth-beta}, a bridge between GHDL\cite{ghdl} and yosys allowing VHDL to be synthesized just the same as Verilog, and Dave Shah added Xilinx support to nextpnr\cite{nextpnr-xilinx}. The latter was preceded by many months of volunteer work reverse-engineering the Xilinx bitstream format as part of \textit{Project X-Ray}\parencite*{prjxray}.
With these two pieces in place, the project was switched over to a completely Free toolchain, removing any depencies on vendor tools:
\begin{itemize}
\item yosys, with ghdl as a frontend for processing VHDL, is used to synthesize the design
\item nextpnr-xilinx, together with the Project X-Ray database, is used for place-and-route
\item tools from Project X-Ray are used to convert the routed design to a bitstream
\item openFPGALoader is used to transfer the bitstream to the FPGA via JTAG
\end{itemize}
\section{Peripherals}
\subsection{UART}
% TODO
\subsection{DVI graphics}
The graphics submodule consists of a VGA timing generator, a text renderer with a font ROM, and a DVI encoder frontend:
\begin{figure}[h]
\includegraphics[width=\textwidth]{graphics.png}
\caption{Block diagram of the video core}
\end{figure}
\subsubsection{VGA timing}
The timing of VGA signals dates back to analog monitors. Even though this original purpose is only very rarely used nowadays, the timing remained the same for analog and digital DVI all the way to modern HDMI.
In analog screens, the electron beams (one for each primary color red, green and blue) scan across the screen a single horizontal line at a time while being modulated by the color values, resulting in a continuous mixture of all three components. When a beam reaches the end of a scanline, it continues outside the visible area for a small distance (the ``Front Porch''), is then sent to the beginning of the next line by a pulse of the hsync (Horizontal Sync) signal, and draws the next line after another short off-screen period (the ``Back Porch'').
The same applies to vertical timings: after the beam reaches the end of the last line, a few off-screen Front Porch lines follow, then a pulse of the vsync (Vertical Sync) signal sends the beam to the top of the screen, where the first line of the next frame is drawn after several invisible Back Porch lines.
\begin{figure}[h]
\includegraphics[width=\textwidth]{vga_timing.png}
\caption{Diagram of VGA timing intervals}
\end{figure}
The VGA timing module generates these hsync and vsync signals, along with a blanking signal (active during any front porch, sync and back porch) and, while in the visible area (i.e. not blanking), the row and column of the current pixel relative to the visible area.
\subsubsection{Text renderer}
The text renderer converts a logical representation of a character, such as its ASCII code (henceforth referred to as its \textit{codepoint}) to a visual representation (a \textit{glyph}). This conversion is achieved using a \textit{font}, a mapping of codepoints to glyphs.
\begin{figure}[h]
\includegraphics[width=0.7\textwidth]{text_renderer.png}
\caption{Block diagram of the text renderer}
\end{figure}
First, the current pixel coordinate (created by the VGA timing generator) is split up into two parts: the character index, which specifies the on-screen character the pixel belongs to, and the offset of the pixel in this character. The character index is passed to the text RAM, which contains the codepoint for each on-screen character. This codepoint, along with the pixel offset, is looked up in the font ROM to determine the color of the pixel.
\subsubsection{TMDS encoder}
DVI and HDMI are serial digital transmission standards. Three data lines (corresponding to red, green, and blue channels) along with a clock line transmit all color information as well as synchronization signals. The encoding used for these signals is Transition-minimized differential signaling (TMDS). It is a kind of 8b/10b encoding (transforming every 8-bit chunk of data into a 10-bit chunk) that is designed to minimize the number of changes of the output signal.
\subsection{Ethernet}
The Arty development board contains an RJ-45 Ethernet jack connected to an Ethernet PHY, which exposes a standardized media-independent interface (MII) to the FPGA. The LiteEth core\cite{liteeth}, which is released under a Free Software license, is used to integrate the Ethernet interface into the SoC.
\subsection{WS2812 driver}
A hardware driver for WS2812 serially-addressable RGB LEDs is also included in the SoC. It was developed independently as part of the curriculum at HTL and later incorporated into the SoC.
\begin{figure}[h]
\includegraphics[width=\textwidth]{ws2812.png}
\caption{Block diagram of the WS2812 driver}
\end{figure}
\begin{figure}[h]
\centering\includegraphics[width=0.5\textwidth]{ws2812_timing.png}
\caption{Timing diagram for the WS2812 serial protocol}
\label{fig:ws2812_timing}
\end{figure}
The driver is designed to be attached to external circuitry that provides color data for any given LED index (address). This can either be discrete logic that generates the color value from the address directly, or a memory that stores a separate color value for each address.
The LEDs are controlled using a simple one-wire serial protocol. After a reset (long period of logic 0), the data for all LEDs is transmitted serially in one single blob. Each LED consumes and stores the first 24 bits of the stream and applies them as its color value (8 bits each for red, green, blue), all following bits are passed through unmodified. The second LED thus uses the first 24 bits of the stream it receives, but since the first LED already dropped its data, these are actually the second set of 24 bits of the source data.
Every bit is encoded as a period of logic 1, followed by a period of logic 0. The timing of these sections determines the value, see \ref{fig:ws2812_timing}.
The exact timing differs between models, so all periods can be customized using generics in the VHDL entity.
\subsection{DRAM}
% TODO
\end{document}

View file

@ -0,0 +1 @@
<mxfile host="www.draw.io" modified="2020-02-29T15:56:59.056Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.14.1 Chrome/77.0.3865.129 Safari/537.36" etag="UiIsl6A_6pU7p9bAkSly" version="12.7.9" type="device"><diagram id="s3T3QF90POQK8EX-g02X" name="Page-1">1VnLkusmEP0aL3NLEpIsLT2vZJGpTM2kbnJXKSxhiQQLFcJjeb4+INAD4fFYFT/ijQuapoHD6UPbnoH7df0zg2X+TFNEZp6T1jPwMPO8eeCIT2nYKYMPfGXIGE6Vye0Nb/gDaaOel21wiirDkVNKOC5NY0KLAiXcsEHG6NZ0W1FirlrCDFmGtwQS2/oHTnmuraHj9AO/IJzleum4HVjD1lkbqhymdDswgccZuGeUctVa1/eISOxaXNS8p09Gu40xVPBjJlTP3xd/rfJnz9mGy5dwVX9/ff0p0Hvju/bAKBXn111ElnT72BvuGN0UKZIBHdGjjOc0owUkv1JaCqMrjH8jznf6HuGGU2HK+ZroUVRj/qec/m0e6O4PHU22H+phZ6c7FWf0nw7+UA4XnO2GcWT/R7uG7PSRml4bSh1XnvFTFLWpohuWoAPQeZqNkGWIH/CLursWOYLoGon9iHkMEcjxu7kPqNmadX7d1BeKxQ49RyeW39Jq1zHSDKH2pWf1tFgwBncDt1I6VJ+vAyJznRHLRENFbHuDM/amhokTWNkm/+Vo2fPJm8SnPdTsGB4OCO5+AwcpLjsviGGBHGKn56obXJWs3nxEVj8wQ6gDTCDrgH8nYVyH5H7G9ZQ6kxp6/0UNV7Tgeo14RGbXG7JZrhN/weimN6ZiJYjDF/I5FYaEwKrCSWt+wqRPo7R1KmiBlEWPX0l9XXAWRruxyWj/TOoLIlN9g9B846f5n0et9VW8Q7LRcP6Oarmp18WzlVVmzmxzzNFbCZur3ooC0swPRfV7SihrZoMwidByJSkvSDWwpxBFq6Rj2DtiHNWHOWZTosXQDU0M2xdw29d/7e3ng8pv/AAPSWTI1VR8w9us0U6Y7OfJ4dCPR6+Sf5YkDsavXzAq1L/yjyf6R9P8PXCBkg5YIvFEm029/naLIuGPy+I9IuF6l1SJ+GoqcbxIfFpm92XIsWX2CdUlOrKUOIkKTRYP9wrfvyIrWS1yVTksZZOLfEQfVIa7KwdVY2cflJJfZbLJyel5zSgXN0ELWQc7J8pzd792D/M83JPm3rnS3LWF9BLyqcv5EyBqfRd0bUTBPuV0QXAuTH0L04SmqOwe/iG4XNa2BoKQ4ExyLhEINDSX+OAEkoUeWOM0VaKLKvwBl00oeTU6+UXc4G4WPMhYQmcrJbnuicrZ+aicbUMM8J5flMGBhXaJ6+ZX44RSluICcnTzsLsWzWO7QHAuint4AHeZ5bcOeRCDEeTgykyfW4ivVNFLaKJeqlvH3AeeqS6OrS7RRTG3a5ckhwwmEjwvJBLdpWxlsoXFO1lPuASmTvD/ugMvNHkviH8U78H0OxDd/g8rVW32//qBx38B</diagram></mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
sections/soc/vga_timing.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View file

@ -0,0 +1 @@
<mxfile host="www.draw.io" modified="2020-03-21T11:04:15.081Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.14.1 Chrome/77.0.3865.129 Safari/537.36" etag="-Ab-_8s9oSbsFdSpbEoE" version="12.8.6" type="device"><diagram id="VHRTjtUijQ8ptJTQA8st" name="Page-1">7VrbktsoEP0aP2ZKgNDlMWPPJqlKNqn1biV5ZCQskcjCK6Gxna9fZIF1wZ4465FlufLiggbacJrTdIMmaLrcvMnIKv7AQ5pMoBVuJmg2gdC3XPlbCraVANuwEkQZCysRqAVz9oMqoaWkBQtp3uooOE8EW7WFAU9TGoiWjGQZX7e7LXjS/tcViaghmAckMaWfWShiJXUsq254S1kUC71g1bAkurMS5DEJ+bohQg8TNM04F1VpuZnSpMRO41KN++NI635iGU3FKQM+vYl8+0/gTF99Df8F7/4p3m4/vNJqcrHVK6ahBEBVeSZiHvGUJA+19D7jRRrSUq0la3Wf95yvpBBI4TcqxFZZkxSCS1EslolqpRsmvjTKX0tVd1jVZhuleVfZ6koqsu2XZqUxqqzWw3Y1Pa5aX7moo7hpDHiRBfQZsGy1/0gWUfFMPwD25pW0oHxJ5YTkwIwmRLCn9kSI2qDRvl9tQ1lQZvwFk9rOkCa17lzctOqJNlWjtFnB9RkV4UGNWul9Ikmh/mkes4WQor9oxHJBs1I/dBK5hPtHWXGisvSxEKui7PU3W7I0MjZG2+zrmAk6X5EdXmvpztsmzkXGv9MpT3i2G42cwKOPC9myYEnSkIeEeotgb6Ynmgm6ed5QJq5qAMLKfarzA2r/um54Y31YxA1H7Fo9mQL4v13myewC+sz+qc8clF56mg1+fZ5DD0CTUu8fZiOkEdanwp5G2KCRe4BFTl8sQug3i05nET6RRdAdlEX4xlnkOPZ1sQi4BuKzjwawcsGijR5JWJTKciAXLkMHdF/CwmTW81o1LFkYVpSjOftBHneqSrOsOEvFbhn4foJnpS7JsrwiHHgZmF3ot2EGtgEzOgAz7AtmCG8RZgegDszmbr4szMiE+d3oYcbQujKYzWTiBmB2kHdlMA+ah48swoHuqRGON2SEA83z9rYiHNfD1xXhIHssLHpJNpy7ydXQT6XfrY3r+x0XiXBbRcU+NapjuP00zmCPd+Ps2V/+Xwt7dCB9W4Gr71zZUa//7LZg9jDowDxwGobMW7obCFxd7F4ZzAey3fHD7Ln2dcFs4yEjG+sONt/pdNNP3+lg652uzgl6zxDQqXeg9pmx03ncMa9Ap9Jku/e50YUz3bc3cOrbW3/ZgBlBGrjmMVmVxUVCN6/LL0B2uzJUxVmQkDxnwRFWDBPvH3tbbuCMD8CsZWemBdDumNnumK+av5EWmIq8jiLUUdRzfoHMaPdldkfv9yP/16ldaIN07GrkjaduEASOXIVeaIPYZpweSNdZmM55bNENNF6mfMNVH9oh/UU3ZqxOwlBCk48f605e5JvZp3NRqM37/JAXYvQ4227nm4UDab59UaDN29+sSEePM+pkRsAxw7zLZkZmlJdREm7Hj7TXvrgCeocP5aWxma4YIPeQp6Q8pS+EaCei8A5kKIduXPffl/8CpLJaf61dhST1J+/o4T8=</diagram></mxfile>

BIN
sections/soc/ws2812.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1 @@
../../Diplomschrift.bib

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

5
sections/vhdl_intro/vhdl/.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
*.json
*.fasm
*.frames
*.bit
counter_tb

View file

@ -0,0 +1,33 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity counter is
port (
clk : in std_logic;
reset : in std_logic;
enable : in std_logic;
direction : in std_logic;
count_out : out std_logic_vector(7 downto 0)
);
end counter;
architecture behaviour of counter is
signal count : unsigned(7 downto 0) := (others => '0');
begin
proc: process(clk)
begin
if reset then
count <= (others => '0');
elsif rising_edge(clk) and enable = '1' then
if direction = '1' then
count <= count + 1;
else
count <= count - 1;
end if;
end if;
end process;
count_out <= std_logic_vector(count);
end behaviour;

View file

@ -0,0 +1,27 @@
set_property LOC D9 [get_ports clk]
set_property LOC C9 [get_ports reset]
set_property LOC A8 [get_ports enable]
set_property LOC C11 [get_ports direction]
set_property LOC F6 [get_ports count_out[0]]
set_property LOC J4 [get_ports count_out[1]]
set_property LOC J2 [get_ports count_out[2]]
set_property LOC H6 [get_ports count_out[3]]
set_property LOC H5 [get_ports count_out[4]]
set_property LOC J5 [get_ports count_out[5]]
set_property LOC T9 [get_ports count_out[6]]
set_property LOC T10 [get_ports count_out[7]]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports reset]
set_property IOSTANDARD LVCMOS33 [get_ports enable]
set_property IOSTANDARD LVCMOS33 [get_ports direction]
set_property IOSTANDARD LVCMOS33 [get_ports count_out[0]]
set_property IOSTANDARD LVCMOS33 [get_ports count_out[1]]
set_property IOSTANDARD LVCMOS33 [get_ports count_out[2]]
set_property IOSTANDARD LVCMOS33 [get_ports count_out[3]]
set_property IOSTANDARD LVCMOS33 [get_ports count_out[4]]
set_property IOSTANDARD LVCMOS33 [get_ports count_out[5]]
set_property IOSTANDARD LVCMOS33 [get_ports count_out[6]]
set_property IOSTANDARD LVCMOS33 [get_ports count_out[7]]

View file

@ -0,0 +1,30 @@
[*]
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
[*] Fri Mar 6 16:40:57 2020
[*]
[dumpfile] "/home/xiretza/Nextcloud/School/Diplomarbeit/Diplomschrift/vhdl_intro/vhdl/counter_tb.ghw"
[dumpfile_mtime] "Fri Mar 6 16:40:14 2020"
[dumpfile_size] 814
[savefile] "/home/xiretza/Nextcloud/School/Diplomarbeit/Diplomschrift/vhdl_intro/vhdl/counter_tb.gtkw"
[timestart] 0
[size] 910 543
[pos] 357 86
*-25.819012 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] top.
[treeopen] top.counter_tb.
[treeopen] top.counter_tb.uut.
[sst_width] 221
[signals_width] 169
[sst_expanded] 1
[sst_vpaned_height] 125
@28
top.counter_tb.uut.clk
top.counter_tb.uut.reset
top.counter_tb.uut.enable
top.counter_tb.uut.direction
@200
-
@24
#{top.counter_tb.count_out[7:0]} top.counter_tb.count_out[7] top.counter_tb.count_out[6] top.counter_tb.count_out[5] top.counter_tb.count_out[4] top.counter_tb.count_out[3] top.counter_tb.count_out[2] top.counter_tb.count_out[1] top.counter_tb.count_out[0]
[pattern_trace] 1
[pattern_trace] 0

View file

@ -0,0 +1,71 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity counter_tb is
end counter_tb;
architecture test of counter_tb is
signal clk, reset, enable, direction : std_logic;
signal s_count_out : std_logic_vector(7 downto 0);
signal count_out : unsigned(7 downto 0);
begin
uut: entity work.counter
port map (
clk => clk,
reset => reset,
enable => enable,
direction => direction,
count_out => s_count_out
);
count_out <= unsigned(s_count_out);
simulate: process
begin
clk <= '0';
reset <= '1';
enable <= '0';
wait for 30 ns;
assert count_out = 0;
reset <= '0';
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
assert count_out = 0;
enable <= '1';
direction <= '0';
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
assert count_out = 255;
direction <= '1';
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
assert count_out = 1;
wait for 30 ns;
wait;
end process;
end test;

View file

@ -0,0 +1,76 @@
\documentclass[../../Diplomschrift.tex]{subfiles}
\begin{document}
\part{A short introduction to VHDL}
Designing a processor is a big task, and it's easiest to start very small. With software projects, this is usually in the form of a ``Hello World'' program - we will be designing a hardware equivalent of this.
\section{Prerequisites}
Other than a text editor, the following Free Software packages have to be installed:
\begin{savenotes}
\begin{description}
\item[\icode{ghdl}\cite{ghdl}] to analyze, compile, and simulate the design
\item[\icode{gtkwave}\cite{gtkwave}] to view the simulation waveform files
\item[\icode{yosys}\cite{yosys}] to synthesize the design
\item[\icode{ghdlsynth-beta}\cite{yosys}] to synthesize the design
\item[\icode{nextpnr-xilinx}\cite{nextpnr-xilinx}] to place and route the design
\item[\icode{Project X-Ray}\cite{prjxray}] for FPGA layout data and bitstream tools
\item[\icode{openFPGALoader}\cite{open-fpga-loader}] to load the bitstream onto the FPGA
\end{description}
\end{savenotes}
\section{Creating a design}
A simple starting design is an up/down counter. The following VHDL code describes the device:
\lstinputlisting[style=vhdlstyle,title=\texttt{counter.vhd}]{vhdl/counter.vhd}
In order to test this design, a test bench has to be created:
\lstinputlisting[style=vhdlstyle,title=\texttt{counter_tb.vhd}]{vhdl/counter_tb.vhd}
\section{Simulating a design}
\begin{lstlisting}[style=terminal]
# analyze the design files
ghdl -a --std=08 *.vhd
# elaborate the test bench entity
ghdl -e --std=08 counter_tb
# run the test bench, saving the signal trace to a GHW file
ghdl -r --std=08 counter_tb --wave=counter_tb.ghw
# open the trace with gtkwave (using the view configuration in counter_tb.gtkw)
gtkwave counter_tb.ghw counter_tb.gtkw
\end{lstlisting}
\begin{figure}
\includegraphics[width=\textwidth]{counter_gtkwave.png}
\caption{Screenshot of the resulting waveform in GTKWave}
\end{figure}
\section{Synthesizing a design}
An additional Xilinx Design Constraints (XDC) file is required to assign the signals to pins on the FPGA:
\lstinputlisting[title=\texttt{counter.xdc}]{vhdl/counter.xdc}
\begin{lstlisting}[style=terminal]
# synthesize with yosys
yosys -m ghdl.so -p '
ghdl --std=08 counter.vhd -e counter;
synth_xilinx -flatten;
write_json counter.json'
# place and route the design with nextpnr
nextpnr-xilinx --chipdb xc7a35tcsg324-1.bin --xdc counter.xdc --json counter.json --fasm counter.fasm
# convert the FPGA assembly to frames
fasm2frames.py --part xc7a35tcsg324-1 counter.fasm counter.frames
# convert the frames to a bitstream
xc7frames2bit --part-name xc7a35tcsg324-1 --frm-file counter.frames --output-file counter.bit
# upload the bitstream to the FPGA
openFPGALoader -b arty counter.bit
\end{lstlisting}
The current value of the counter is displayed in binary on the eight LEDs on the board. When switch 0 (enable) is in the high position, the counter can be advanced using button 0, with the direction set by switch 1. Button 1 resets the counter to zero.
\end{document}