2020-03-22 18:54:41 +01:00
\documentclass [../../Diplomschrift.tex] { subfiles}
2019-12-10 15:32:02 +01:00
\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}
2020-03-22 18:54:41 +01:00
\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
2020-03-27 12:49:50 +01:00
\item [\icode{ghdlsynth-beta}\cite{ghdlsynth-beta}] to synthesize the design
2020-03-22 18:54:41 +01:00
\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
2019-12-10 15:32:02 +01:00
\end { description}
\end { savenotes}
\section { Creating a design}
2020-03-06 18:34:45 +01:00
A simple starting design is an up/down counter. The following VHDL code describes the device:
2019-12-10 15:32:02 +01:00
2020-03-27 14:20:22 +01:00
\lstinputlisting [
style=vhdlstyle,
label={ lst:counter} ,
caption={ Counter entity} ,
title=\texttt { counter.vhd} ,
]{ vhdl/counter.vhd}
2019-12-10 15:32:02 +01:00
In order to test this design, a test bench has to be created:
2020-03-27 14:20:22 +01:00
\lstinputlisting [
style=vhdlstyle,
label={ lst:counter-tb} ,
caption={ Counter test bench entity} ,
title=\texttt { counter_ tb.vhd} ,
]{ vhdl/counter_ tb.vhd}
2019-12-10 15:32:02 +01:00
\section { Simulating a design}
2020-03-27 14:20:22 +01:00
\begin { lstlisting} [
style=terminal,
label={ lst:counter-sim-commands} ,
caption={ Commands required to simulate the counter design} ]
2019-12-10 15:32:02 +01:00
# analyze the design files
2020-03-06 18:34:45 +01:00
ghdl -a --std=08 *.vhd
2019-12-10 15:32:02 +01:00
# elaborate the test bench entity
2020-03-06 18:34:45 +01:00
ghdl -e --std=08 counter_ tb
2019-12-10 15:32:02 +01:00
# run the test bench, saving the signal trace to a GHW file
2020-03-06 18:34:45 +01:00
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
2019-12-10 15:32:02 +01:00
\end { lstlisting}
2020-03-21 14:32:43 +01:00
\begin { figure}
2020-03-06 18:34:45 +01:00
\includegraphics [width=\textwidth] { counter_ gtkwave.png}
2020-03-29 18:05:21 +02:00
\caption { Screenshot of the counter test bench waveform in GTKWave}
2020-03-21 14:32:43 +01:00
\end { figure}
2020-03-06 18:34:45 +01:00
\section { Synthesizing a design}
An additional Xilinx Design Constraints (XDC) file is required to assign the signals to pins on the FPGA:
2020-03-27 14:20:22 +01:00
\lstinputlisting [
label={ lst:counter-constraints} ,
caption={ Counter design constraints file} ,
title=\texttt { counter.xdc} ,
]{ vhdl/counter.xdc}
2020-03-06 18:34:45 +01:00
2020-03-27 14:20:22 +01:00
\begin { lstlisting} [
style=terminal,
label={ lst:counter-synth-commands} ,
caption={ Commands required to synthesize the counter design} ]
2020-03-06 18:34:45 +01:00
# 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
2020-03-22 18:54:41 +01:00
openFPGALoader -b arty counter.bit
2020-03-06 18:34:45 +01:00
\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.
2019-12-10 15:32:02 +01:00
\end { document}