1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
\section{Testing}
To simulate a digial circuit it is possible to write test benches using VHDL.
The code in this section may no longer be synthetisable, and is usually
written by a \emph{test designer}.
\subsection{Simulator}
VHDL simulates digital systems using \emph{delta cycles}.
%% TODO: notes on how delta cycles work, read
%% https://stackoverflow.com/questions/43652630/delta-cycles-and-waveforms
\subsection{Transport delay}
To model a time delay of a signal there are two ways:
\begin{lstlisting}[language=vhdl]
y <= transport `\reqph{expression}` after `\reqph{time}`;
y <= inertial `\reqph{expression}` after `\reqph{time}`;
\end{lstlisting}
When \vhdl{transport} is used, the output changes only exactly after the
specified time, the simulator simply waits. With \vhdl{inertial}, the output is
also delayed, but only if the input lasts more than the specified time. This
means that for example with a time of \vhdl{10 ns} a pulse of \vhdl{5 ns} will
be ignored. This is much more typical and realistic, thus when unspecified,
\vhdl{after} is interpreted as \vhdl{inertial ... after}.
\begin{lstlisting}[language=vhdl]
y <= `\reqph{expression}` after `\reqph{time}`;
\end{lstlisting}
%% TODO: tikz timing diagram
\subsection{Generate stimuli}
Simple stimuli (signals) are generated using processes. For example a clock
signal done in three ways:
\begin{lstlisting}[language=vhdl]
-- declaration
constant f : integer := 1000;
constant T : time := 1 sec/f;
signal clk0, clk1, clk2 : std_ulogic;
\end{lstlisting}
\begin{lstlisting}[language=vhdl]
-- concurrent
clock0: process
begin
clk <= '1'; wait for (T/2);
clk <= '0'; wait for (T/2);
end process;
clock1: process
begin
clk1 <= '1';
loop
wait for (T/2);
clk1 <= not clk1;
end loop;
end process;
-- lazy way
clock2: clk2 <= not clk2 after (T/2);
\end{lstlisting}
One time stimuli can be modelled using the following expression. Note that the
time is absolute.
\begin{lstlisting}[language=vhdl]
tb_sig <= '0',
'1' after 20 ns,
'0' after 30 ns, -- 10 ns later
`\reqph{value}` after `\reqph{time}`;
\end{lstlisting}
Repeating sequences can be created using processes.
\begin{lstlisting}[language=vhdl]
sequence: process
begin
tb_sig <= '0';
wait for 20 ns;
tb_sig <= '1';
wait for 10 ns;
...
end process;
\end{lstlisting}
For loops are also available, and can be synthesised if they run over a finite
range.
\begin{lstlisting}[language=vhdl]
`\optionalph{label}:` for `\reqph{parameter}` in `\reqph{range}` loop
-- sequential statements
end loop `\optionalph{label}`;
\end{lstlisting}
A concrete example:
\begin{lstlisting}[language=vhdl]
-- declaration
constant n : integer := 3;
signal a, b : std_ulogic_vector(n-1 downto 0);
\end{lstlisting}
\begin{lstlisting}[language=vhdl]
-- sequential
for i in 0 to 2**n -1 loop
a <= std_ulogic_vector(
to_unsigned(i, n));
for k in 0 to 2**n -1 loop
b <= std_ulogic_vector(
to_unsigned(k, n));
end loop;
end loop;
\end{lstlisting}
\subsection{Assertions}
Assertions are used write tests to check that a signal is in the correct state.
\begin{lstlisting}[language=vhdl]
`\optionalph{label}`: assert `\reqph{condition}` report `\reqph{string}` severity `\reqph{severity}`;
\end{lstlisting}
The \vhdl{report} and \vhdl{severity} are optional but strongly advised. The
severity can take one of 4 values: \vhdl{note}, \vhdl{warning}, \vhdl{error},
\vhdl{failure}. Simulations can be configured to stop in when an error of the
desired severity occurrs. An example:
\begin{lstlisting}[language=vhdl]
assert (tb_y = '0') report "error at vector 11" severity error;
\end{lstlisting}
% \subsection{A simple but complete Test Bench}
% \begin{lstlisting}[language=vhdl]
% \end{lstlisting}
|