Commit e29183e2 authored by Synthron's avatar Synthron
Browse files

Update to newest version

update all the files in repo
parent 4e82ec73
File added
......@@ -93,16 +93,16 @@ set_io io_PMOD_9 9
set_io io_PMOD_10 10
### Logic Analyzer Signals
set_io io_LA_0 73
set_io io_LA_1 73
set_io io_LA_1 74
set_io io_LA_2 75
set_io io_LA_3 76
set_io io_LA_4 78
set_io io_LA_5 79
set_io io_LA_6 80
set_io io_LA_7 81
set_io io_LA_8 82
set_io io_LA_9 83
set_io io_LA_1 75
set_io io_LA_1 76
set_io io_LA_1 78
set_io io_LA_1 79
set_io io_LA_1 80
set_io io_LA_1 81
set_io io_LA_1 82
set_io io_LA_1 83
### General Purpose IOs
set_io io_GPIO_11 11
......@@ -122,4 +122,4 @@ set_io io_GPIO_29 29
set_io io_GPIO_31 31
set_io io_GPIO_32 32
set_io io_GPIO_33 33
set_io io_GPIO_34 34
set_io io_GPIO_34 34
\ No newline at end of file
create_clock -name i_Clk -period 40 [get_ports {i_Clk}]
\ No newline at end of file
\chapter{Basis und Struktur}
In VHDL wird nicht eine Zeile Code nach der anderen ausgeführt, sondern der gesamte Code wird in Logik umgesetzt und somit parallel ausgeführt.
Immer auf Verriegelungen achten und Instanzen nutzen, wenn möglich. Dadurch können "known good designs" wiederverwendet werden.
die Hauptstruktur von VHDL besteht aus den includes, der entity und der architecture:
\begin{lstlisting}[caption={Grundstruktur}, language=vhdl, frame=single]
library ieee;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity <Name> is
port (
-- Hier die nach außen geführten Signale definieren
i_input : in std_logic;
o_output : out std_logic
);
-- Wichtig ist das fehlende Semikolon in der letzten Deklaration!
end entity <Name>;
architecture RTL of <Name> is
-- Hier zusätzliche interne Signale definieren
signal w_vector : std_logic_vector (7 downto 0) := (others => '0');
signal w_int : integer range 0 to 128 := 0;
begin
-- code, hier Zuweisung in = out
o_output <= i_input;
end RTL;
\end{lstlisting}
Auf diese Form muss geachtet werden. \par
\textbf{WICHTIG!!!}\\
VHDL ist NICHT Case-Sensitiv! die Variable \begin{lstlisting}[language=vhdl]
i_clk
\end{lstlisting} ist exakt die selbe Variable wie \begin{lstlisting}[language=vhdl]
i_CLK
\end{lstlisting}!!!
\textcolor{blue}{\href{https://www.csee.umbc.edu/portal/help/VHDL/stdpkg.html}{Erklärung zu den einzelnen IEEE-Libraries}}
\ No newline at end of file
\chapter{Two Process Technik}
\section{Übersicht}
Folgend eine schematische Darstellung:
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{pictures/two-process-schema.png}
\caption{Zusammenhang der zwei Prozesse}
\label{img:Zusammenhang der Prozesse}
\end{figure}
Bei der Two-Process Technik enthält jede \textcolor{blue}{architecture} einer \textcolor{blue}{entity} nur zwei Prozesse: einen kombinatorischen und einen sequenziellen Prozess.
Alle Logik ist ausschließlich im kombinatorischen Prozess. Im sequenziellen Prozess wird von der aktuellen Ausgabe des kombinatorischen Prozesses ein 'Snapshot' gemacht, welcher die neue Prozessgrundlage darstellt.
\pagebreak
\section{Aufbau}
\subsection{Records}
Ein Record ist mit einem Struct in C++ zu vergleichen. Es handelt sich dabei um ein Objekt, welches mehrere Variablen zusammenfasst. \\
Sinn davon ist, dass alle Signale und Variablen gesammelt an einem Punkt sind. Auch die Sensitivity List von Prozessen nehmen nur noch diesen Record an (zzgl. eventueller anderer Signale), wodurch diese stets alle Signale zur Verfügung hat.
Der Aufbau eines Records kann zum Beispiel wie folgt aussehen:
\begin{lstlisting}[caption={Record-Struct}, language=vhdl, frame=single]
type reg_type is record
irq : standard_logic;
addr : std_logic_vector (15 downto 0);
data : std_logic_vector (7 downto 0);
end record;
-- instanzieren der records
signal r, rin : reg_type;
\end{lstlisting}
\subsection{Sequenzieller Prozess}
Der sequenzielle Prozess ist der synchrone Prozess und sieht \textbf{immer} folgend aus:
\begin{lstlisting}[caption={Sequenzieller Prozess}, language=vhdl, frame=single]
seq : process (i_Clk) is
begin
if rising_edge(i_Clk) then
r <= rin;
end if;
end process seq;
\end{lstlisting}
Es werden lediglich die im kombinatorischen Prozess berechneten Werte vom Output-Register in das Arbeitsregister übertragen.
\pagebreak
\subsection{Kombinatorischer Prozess}
Der Kombinatorische Prozess ist immer der asynchrone Prozess und enthält alle Berechnungen und Verknüpfungen. In ihm wird alles über die Structs erledigt. Dabei wird der r-Record in einen Zwischenspeicher v gelegt. Ausgabe erfolgt ausschließlich über den rin-Record.
\begin{lstlisting}[caption={Kombinatorischer Prozess}, language=vhdl, frame=single]
comb : process (r)
variable v : reg_type;
signal tmp : unsinged (15 downto 0);
begin
-- Snapshot in Arbeits-Struct speichern
v := r;
-- ab hier die Logik
v.irq := '0';
tmp <= unsigned(r.addr) + 1;
v.addr := std_logic_vector(tmp);
v.data := X"DE";
-- Übergabe an zukünftigen "Snapshot"
rin <= v;
end process;
\end{lstlisting}
\chapter{Syntax}
\section{Literale}
Literale sind Ausdrücke und beziehen sie sich auf die Definition und Zuweisung.
\begin{lstlisting}[caption={Literale}, language=vhdl, frame=single]
-- Mit Dezimalpunkt reell, ohne Ganzzahl
constant tmp1 : integer := 32;
constant tmp2 : real := 32.0;
-- Eine Basis kann mit #-Zeichen angegeben werden
-- Längere Zahlen können mit _ besser lesbar geschrieben werden
A_int <= 16#FF#;
B_int <= 2#1010_1101#;
Clocks <= 1_000_000.0;
-- Reelle Zahlen als Exponetial
Factor := 2.2E-6;
-- Zeitliche Literale brauchen eine Einheit (mit Abstand)
constant del1 : time := 10 ns;
constant del2 : time := 2.27 us;
-- Zuweisungen können explizit oder Identifier sein
type My_Logic is ('X', '0', '1', 'Z');
type t_state is (IDLE, READ, END_CYC);
signal CLK : My_Logic := '0';
signal STATE : t_state := IDLE;
-- Literale für Arrays werden in Anführungszeichen geschrieben
constant FLAG : bit_vector(7 downto 0) := "11111111";
constant MSG : string := "Hello World";
-- Vektoren können in jeder Basis beschrieben werden
8bit_Bus <= B"1111_1111";
9bit_Bus <= O"353";
16bit_bus <= X"FC";
-- Befehlszeichen in Strings können eingefügt werden
constant text : string := "Hello" & CR & "World";
\end{lstlisting}
\pagebreak
\section{Operatoren}
Drei Operatoren sind wichtig:
\begin{itemize}
\item :=
\item $<=$ bzw $=>$
\item :
\end{itemize}
Ersterer (:=) wird für Initialisierungen benutzt und um variables zuzuweisen.
Zweiteres sind Mapping-Operatoren, die Signale zuweisen.
Letzteres wird für Deklarationen benutzt.
\section{Verknüpfungen}
\subsection{Logische Verknüpfungen}
\begin{tabular}{p{1.5cm}l}
\textcolor{blue}{and} & Logisches UND \\
\textcolor{blue}{or} & Logisches ODER \\
\textcolor{blue}{not} & Logisches NICHT (Inverter) \\
\textcolor{blue}{nand} & Logisches NICHT-UND \\
\textcolor{blue}{nor} & Logisches NICHT-ODER \\
\textcolor{blue}{xor} & Logisches EXKLUSIV-ODER \\
\textcolor{blue}{xnor} & Logisches EXKLUSIV-NICHT-ODER
\end{tabular}
\subsection{Vergleichende Verknüpfungen}
\begin{tabular}{p{1.5cm}l}
\textcolor{blue}{=} & Gleich \\
\textcolor{blue}{/=} & Ungleich \\
\textcolor{blue}{$<$} & Kleiner als \\
\textcolor{blue}{$<=$} & Kleiner gleich \\
\textcolor{blue}{$>$} & Größer als \\
\textcolor{blue}{$>=$} & Größer gleich
\end{tabular}
\section{Sonstiges}
\subsection{Zusammenhängen}
Um eine Concatenation (Verbindung, Aneinanderhängen) zu erreichen, gibt es den Operator \textcolor{blue}{\&}.
\subsection{Rising Edge}
Der Operator \textcolor{blue}{rising\_edge()} ist \textbf{ausschließlich} für das Clock$-$Signal zu verwenden.
\chapter{Umrechnungen}
Da man manchmal zwischen einzelnen Datentypen umrechnen muss, wird hier beschrieben wie man das macht.
\section{Mit use\ numeric\_std.all}
\subsection{Von integer}
\subsubsection{Nach signed}
\begin{lstlisting}[caption={Von integer nach signed},language=vhdl, frame=single]
signal input : integer;
signal output : signed(3 downto 0);
output <= to_signed(input, output'length);
\end{lstlisting}
\subsubsection{Nach std\_logic\_vector}
\begin{lstlisting}[caption={Von integer nach std\_logic\_vector},language=vhdl, frame=single]
signal input : integer;
signal output_a : std_logic_vector(3 downto 0);
signal output_b : std_logic_vector(3 downto 0);
-- Konvertierung ohne Vorzeichen
output_a <= std_logic_vector(to_unsigned(input, output_a'length));
-- Konvertierung mit Vorzeichen
output_b <= std_logic_vector(to_signed(input, output_b'length));
\end{lstlisting}
\subsubsection{nach unsigned}
\begin{lstlisting}[caption={Von integer nach unsigned},language=vhdl, frame=single]
signal input : integer;
signal output : unsigned(3 downto 0);
output <= to_unsigned(input, output'length);
\end{lstlisting}
\subsection{Von std\_logic\_vector}
\subsubsection{Nach integer}
\begin{lstlisting}[caption={Von std\_logic\_vector nach integer},language=vhdl, frame=single]
signal input : std_logic_vector(3 downto 0);
signal output_a : integer;
signal output_b : integer;
-- Ohne Vorzeichen
output_a <= to_integer(unsigned(input));
-- mit Vorzeichen
output_b <= to_integer(signed(input));
\end{lstlisting}
\subsubsection{Nach signed}
\begin{lstlisting}[caption={Von std\_logic\_vector nach signed},language=vhdl, frame=single]
signal input : std_logic_vector(3 downto 0);
signal output : signed(3 downto 0);
output <= signed(input);
\end{lstlisting}
\subsubsection{Nach unsigned}
\begin{lstlisting}[caption={Von std\_logic\_vector nach unsigned},language=vhdl, frame=single]
signal input : std_logic_vector(3 downto 0);
signal output : unsigned(3 downto 0);
output <= unsigned(input);
\end{lstlisting}
\pagebreak
\subsection{Von signed}
\subsubsection{Nach integer}
\begin{lstlisting}[caption={Von signed nach integer},language=vhdl, frame=single]
signal input : signed(3 downto 0);
signal output : integer;
output <= to_integer(input);
\end{lstlisting}
\subsubsection{Nach std\_logic\_vector}
\begin{lstlisting}[caption={Von signed nach std\_logic\_vector},language=vhdl, frame=single]
signal input : signed(3 downto 0);
signal output : std_logic_vector(3 downto 0);
output <= std_logic_vector(input);
\end{lstlisting}
\subsubsection{Nach unsigned}
\begin{lstlisting}[caption={Von signed nach unsigned},language=vhdl, frame=single]
signal input : signed(3 downto 0);
signal output : unsigned(3 downto 0);
output <= unsigned(input);
\end{lstlisting}
\pagebreak
\subsection{Von unsigned}
\subsubsection{Nach integer}
\begin{lstlisting}[caption={Von unsigned nach integer},language=vhdl, frame=single]
signal input : unsigned(3 downto 0);
signal output : integer;
output <= to_integer(input);
\end{lstlisting}
\subsubsection{Nach signed}
\begin{lstlisting}[caption={Von unsigned nach signed},language=vhdl, frame=single]
signal input : unsigned(3 downto 0);
signal output : signed(3 downto 0);
output <= signed(input);
\end{lstlisting}
\subsubsection{Nach std\_logic\_vector}
\begin{lstlisting}[caption={Von unsigned nach std\_logic\_vector},language=vhdl, frame=single]
signal input : unsigned(3 downto 0);
signal output : std_logic_vector(3 downto 0);
output <= std_logic_vector(input);
\end{lstlisting}
\pagebreak
\section{Mit use std\_logic\_arith.all}
\subsection{Von integer}
\subsubsection{Nach signed}
\begin{lstlisting}[caption={Von integer nach signed},language=vhdl, frame=single]
signal input : integer;
signal output : signed(3 downto 0);
output <= conv_signed(input, output'length);
\end{lstlisting}
\subsubsection{Nach std\_logic\_vector}
\begin{lstlisting}[caption={Von integer nach std\_logic\_vector},language=vhdl, frame=single]
signal input : integer;
signal output : std_logic_vector(3 downto 0);
output <= conv_std_logic_vector(input, output'length);
\end{lstlisting}
\subsubsection{nach unsigned}
\begin{lstlisting}[caption={Von integer nach unsigned},language=vhdl, frame=single]
signal input : integer;
signal output : unsigned(3 downto 0);
output <= conv_unsigned(input, output'length);
\end{lstlisting}
\pagebreak
\subsection{Von std\_logic\_vector}
\subsubsection{Nach integer}
\begin{lstlisting}[caption={Von std\_logic\_vector nach integer},language=vhdl, frame=single]
signal input : std_logic_vector(3 downto 0);
signal output_a : integer;
signal output_b : integer;
-- ohne Vorzeichen
output_a <= conv_integer(unsigned(input));
-- mit Vorzeichen
output_b <= conv_integer(signed(input));
\end{lstlisting}
\subsubsection{Nach signed}
\begin{lstlisting}[caption={Von std\_logic\_vector nach signed},language=vhdl, frame=single]
signal input : std_logic_vector(3 downto 0);
signal output : signed(3 downto 0);
output <= signed(input);
\end{lstlisting}
\subsubsection{Nach unsigned}
\begin{lstlisting}[caption={Von std\_logic\_vector nach unsigned},language=vhdl, frame=single]
signal input : std_logic_vector(3 downto 0);
signal output : unsigned(3 downto 0);
output <= unsigned(input);
\end{lstlisting}
\pagebreak
\subsection{Von signed}
\subsubsection{Nach integer}
\begin{lstlisting}[caption={Von signed nach integer},language=vhdl, frame=single]
signal input : signed(3 downto 0);
signal output : integer;
output <= conv_integer(input);
\end{lstlisting}
\subsubsection{Nach std\_logic\_vector}
\begin{lstlisting}[caption={Von signed nach std\_logic\_vector},language=vhdl, frame=single]
signal input : signed(3 downto 0);
signal output : std_logic_vector(3 downto 0);
output <= std_logic_vector(input);
\end{lstlisting}
\subsubsection{Nach unsigned}
\begin{lstlisting}[caption={Von signed nach unsigned},language=vhdl, frame=single]
signal input : signed(3 downto 0);
signal output : unsigned(3 downto 0);
output <= unsigned(input);
\end{lstlisting}
\pagebreak
\subsection{Von unsigned}
\subsubsection{Nach integer}
\begin{lstlisting}[caption={Von unsigned nach integer},language=vhdl, frame=single]
signal input : unsigned(3 downto 0);
signal output : integer;
output <= conv_integer(input);
\end{lstlisting}
\subsubsection{Nach signed}
\begin{lstlisting}[caption={Von unsigned nach signed},language=vhdl, frame=single]
signal input : unsigned(3 downto 0);
signal output : signed(3 downto 0);
output <= signed(input);
\end{lstlisting}
\subsubsection{Nach std\_logic\_vector}
\begin{lstlisting}[caption={Von unsigned nach std\_logic\_vector},language=vhdl, frame=single]
signal input : unsigned(3 downto 0);
signal output : std_logic_vector(3 downto 0);
output <= std_logic_vector(input);
\end{lstlisting}
\ No newline at end of file
\chapter{Prozesse}
Alles, was Kombinatorik enthält und nicht nur boolsche Algebra ist, muss in einen Prozess. Prozesse werden in der architecture definiert und folgen dabei folgendem Prinzip:
\begin{lstlisting}[caption={Beispielprozess}, language=vhdl, frame=single]
<p_Name> : process (Sensitivity List)is
begin
if (param1 = param2) then
-- some code
end if;
end process <p_Name>;
\end{lstlisting}
\section{Sensitivity List}
Die Sensitivity List dient dem definieren, welche Signale den Prozess zum Laufen bringen. Alle Signale, die in einem Prozess gelesen werden, müssen in der Sensitivity List angegeben sein.
Ein Beispiel anhand eines D-Flip-Flops:
\begin{lstlisting}[caption={D-FF-Prozess}, language=vhdl, frame=single]
DFF : process (CLK,RST)
begin
if RST = '1'
then Q <= '0';
elsif (CLK'event) and (CLK = '1') --steigende Flanke
then Q <= D;
end if;
end process DFF;
\end{lstlisting}
Sowohl das RST-Signal, als auch das CLK-Signal lösen eine Aktion aus und müssen demnach in der Sensitivity List aufgeführt sein.
\ No newline at end of file
\chapter{if und case}
\section{if}
\subsection{Struktur}
\begin{lstlisting}[caption={If-Beispiel}, language=vhdl, frame=single]
if condition_1 then
-- code
elsif condition2 then
-- code
else
-- code
end if;
\end{lstlisting}
\subsection{Überlappung}
Bedingungen dürfen sich überlappen, es wird aber immer NUR DIE ERSTE Bedingung ausgeführt.
\begin{lstlisting}[caption={Überlappung in If-Schleifen}, language=vhdl, frame=single]
if (X = 5) and (Y = 9) then
Z <= A;
elsif (X >= 5) then
Z <= B;
else
Z <= C;
end if;
\end{lstlisting}
Hier im Beispiel wird bei $X = 5$ nur das if ausgeführt, nicht das elsif.
\pagebreak
\section{case}
\subsection{Struktur}
\begin{lstlisting}[caption={Case-Beispiel}, language=vhdl, frame=single]
case <expression> is
when choice =>
-- code
when choice =>
-- code
end case;
\end{lstlisting}
\subsection{Vollständigkeit}
Alle Möglichkeiten müssen immer aufgeführt sein. Um das abzukürzen, kann das keyword 'others' benutzt werden:
\begin{lstlisting}[caption={Case Vollständigkeit}, language=vhdl, frame=single]
case SEL is
when "01" => Z <= A;
when "10" => Z <= B;
when others => Z <= 'X';
end case;
\end{lstlisting}
\subsection{Bereiche}
Im Statement können auch Bereiche angegeben werden:
\begin{lstlisting}[caption={Case Bereiche}, language=vhdl, frame=single]
case INT_A is
when 0 => Z <= A;
when 1 to 3 => Z <= B;
when 4|6|8 => Z <= C;
when others => Z <= 'X';
end case;
\end{lstlisting}
\subsection{Überlappungen}
Es dürfen keine Überlappungen auftreten:
\begin{lstlisting}[caption={Case Überlappungen}, language=vhdl, frame=single]
case INT_A is
when 0 => Z <= A;
when 1 to 3 => Z <= B;
when 2|6|8 => Z <= C; -- illegal
when others => Z <= 'X';
end case;
\end{lstlisting}
\pagebreak
\subsection{Beschränkung}
Bei Vektoren (\textcolor{blue}{std\_logic\_vector}) dürfen KEINE Bereiche angegeben werden:
\begin{lstlisting}[caption={Case Beschränkung}, language=vhdl, frame=single]
case VEC is
when "000" to "010"
=> Z <= A; -- illegal
when "111" => Z <= B;
when others => Z <= 'X';
end case;
\end{lstlisting}
\subsection{Anwendungen}
Mit case kann man einfach eine State-Machine realisieren:
\begin{lstlisting}[caption={Case State-Machine}, language=vhdl, frame=single]
case READ_CPU_STATE is
when WAITING =>
if CPU_DATA_VALID = '1' then
CPU_DATA_READ <= '1';
READ_CPU_STATE <= DATA1;
end if;
when DATA1 =>
-- etc.
end case;
\end{lstlisting}
\ No newline at end of file
\chapter{Decoding}
\section{7-Segment}
Um einfach eine 7Segment-Anzeige zu decodieren, kann man einem Vektor Hex-Werte zuweisen und diese bitweise auf die Segmente aufteilen:
\begin{lstlisting}[caption={7-Segment Hex-Decoding}, language=vhdl, frame=single]
-- Innerhalt eines Prozesses wird eine integer hochgezählt
case r_IntA is
when 0 => -- 0
w_decode <= X"7E";
when 1 => -- 1
w_decode <= X"30";
when 2 => -- 2
w_decode <= X"6D";
when 3 => -- 3
w_decode <= X"79";
when 4 => -- 4
w_decode <= X"33";
when 5 => -- 5
w_decode <= X"5B";
when 6 => -- 6
w_decode <= X"5F";
when 7 => -- 7
w_decode <= X"70";
when 8 => -- 8
w_decode <= X"7F";
when 9 => -- 9
w_decode <= X"7B";
when 10 => -- A
w_decode <= X"77";
when 11 => -- b
w_decode <= X"1F";
when 12 => -- C
w_decode <= X"4E";
when 13 => -- d
w_decode <= X"3D";
when 14 => -- E
w_decode <= X"4F";
when 15 => -- F
w_decode <= X"47";
end case;
-- Prozess beenden, Zuweisung muss nicht innerhalb des Prozesses sein
\end{lstlisting}
Außerhalb des Prozessen können nun die Signale den Segmenten zugeordnet werden:
\begin{lstlisting}[caption={7-Segment Signalzuweisung}, language=vhdl, frame=single]
o_Segment1_A <= w_decode(6);
o_Segment1_B <= w_decode(5);
o_Segment1_C <= w_decode(4);
o_Segment1_D <= w_decode(3);
o_Segment1_E <= w_decode(2);
o_Segment1_F <= w_decode(1);
o_Segment1_G <= w_decode(0);
\end{lstlisting}
\ No newline at end of file