aboutsummaryrefslogtreecommitdiffstats
path: root/tex/statemachines.tex
blob: 1e1546f9077a4ce12e4984e6787d7ae63400f31c (plain)
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
\section{State Machines}
\begin{figure}[h]
  \centering
  \ttfamily
  \begin{tikzpicture}[
      node distance = 3mm,
      box/.style = {
        draw = black, thick, fill = gray!20!white,
        minimum width = 20mm, minimum height = 8mm,
      }
    ]

    % mealey
    \begin{scope}
      \node[box] (G) {\large G};
      \node[box, above = of G] (F) {\large F};
      \node[box, below = of G] (Z) {\large Z};

      \node[above = of F] {\large Mealey};

      \draw[very thick, ->, hsr-blue] (F.east) -- ++(1,0) node[right] {oup};
      \draw[very thick, ->, hsr-lakegreen] (G.east) -- ++(.5,0) |- (Z.east);
      \draw[very thick, ->] (Z.west) -- ++(-.5,0) |- ($(G.west) - (0,.25)$);
      \draw[very thick, ->] (G.west) ++ (-.5,-.25) |- ($(F.west) + (0,.25)$);

      \draw[very thick, ->, hsr-mauve] ($(G.west) + (-1.5,.25)$)
        node[left] {inp} -- ++(1.5,0);
      \draw[very thick, ->, hsr-mauve] ($(G.west) + (-1,.25)$) |- ($(F.west) - (0,.25)$);
    \end{scope}

    % moore
    \begin{scope}[yshift = -42mm]
      \node[box] (G) {\large G};
      \node[box, above = of G] (F) {\large F};
      \node[box, below = of G] (Z) {\large Z};

      \node[above = of F] {\large Moore};

      \draw[very thick, ->, hsr-blue] (F.east) -- ++(1,0) node[right] {oup};
      \draw[very thick, ->, hsr-lakegreen] (G.east) -- ++(.5,0) |- (Z.east);
      \draw[very thick, ->] (Z.west) -- ++(-.5,0) |- ($(G.west) - (0,.25)$);
      \draw[very thick, ->] (G.west) ++ (-.5,-.25) |- (F.west);

      \draw[very thick, ->, hsr-mauve] ($(G.west) + (-1.5,.25)$)
        node[left] {inp} -- ++(1.5,0);
    \end{scope}

    % Medwedjew
    \begin{scope}[yshift = -80mm]
      \node[box] (G) {\large G};
      \node[box, below = of G] (Z) {\large Z};

      \node[above = of G, yshift = 3mm] {\large Medwedjew};

      \draw[very thick, ->, hsr-lakegreen] (G.east) -- ++(.5,0) |- (Z.east);
      \draw[very thick, ->, hsr-blue] (Z.west) -- ++(-.5,0) |- ($(G.west) - (0,.25)$);
      \draw[very thick, ->, hsr-blue] (G.west) ++ (-.5,-.25) |- ($(G.east) + (1,.75)$)
        node[right] {oup};

      \draw[very thick, ->, hsr-mauve] ($(G.west) + (-1.5,.25)$)
        node[left] {inp} -- ++(1.5,0);
    \end{scope}
  \end{tikzpicture}
\end{figure}

\subsection{Encoding the state} \label{sec:fsm:encode}
For Mealey and Moore machines it is typical to write:
\begin{lstlisting}[language=vhdl]
type state_type is (st_rst, st_a, st_b, st_c, ...);
signal present_state, next_state : state_type;
\end{lstlisting}
The encoding of the state is left to the synthesizer or can be configured in
the graphical interface of the tool.  If a custom encoding is required
(Medwedjew), adding the following generates a custom encoding.
\begin{lstlisting}[language=vhdl]
attribute enum_encoding : string;
attribute enum_encoding of state_type:
  type is "0001 0010 0100 ...";
\end{lstlisting}
Or an equivalent approach is to use a vector subtype and constants.
\begin{lstlisting}[language=vhdl]
subtype state_type is bit_vector(3 downto 0);

constant st_rst : state_type := "0001";
constant st_a   : state_type := "0010";
constant st_b   : state_type := "0100";
...

signal present_state, next_state : state_type;
\end{lstlisting}

\subsection{Updating the state register (\texttt{Z})}
\begin{lstlisting}[language=vhdl]
register_logic: process (clk, rst)
begin
  -- asynchronous reset
  if rst = '1' then
    present_state <= st_rst;

  -- clock
  elsif rising_edge(clk) then
    present_state <= next_state;
  end if;
end process;
\end{lstlisting}

\subsection{Updating the state (\texttt{G})}
\begin{lstlisting}[language=vhdl]
next_state_logic:
process (present_state, `\optionalph{inputs}`)
begin
  -- default value
  next_state <= state_rst;

  case present_state is
    when st_rst =>
      -- reset state logic
      next_state <= `\reqph{state}`;

    when st_a =>
      -- logic using inputs
      next_state <= `\reqph{state}`;

    ...
    when others => null;
  end case;
end process;
\end{lstlisting}

\subsection{Updating the output (\texttt{F})}
Mealey
\begin{lstlisting}[language=vhdl]
output_logic:
process (present_state, `\reqph{inputs}`)
begin
  -- logic with state and inputs
  `\reqph{output}` <= `\reqph{expression}`;
end process;
\end{lstlisting}
Moore
\begin{lstlisting}[language=vhdl]
output_logic: process (present_state)
begin
  case present_state is
    when st_rst =>
      `\reqph{output}` <= `\reqph{value}`;

    ...
  end case;
end process;
\end{lstlisting}
Medwedjew
\begin{lstlisting}[language=vhdl]
output_logic: `\reqph{output}` <= present_state;
\end{lstlisting}