
\section{Yosys by example -- Synthesis}

\begin{frame}
\sectionpage
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Typical Phases of a Synthesis Flow}

\begin{frame}{\subsecname}
\begin{itemize}
\item Reading and elaborating the design
\item High-level synthesis and optimization
\begin{itemize}
\item Converting {\tt always}-blocks to logic and registers
\item Perform coarse-grain optimizations (resource sharing, const folding, ...)
\item Handling of memories and other coarse-grain blocks
\item Extracting and optimizing finite state machines
\end{itemize}
\item Convert remaining logic to bit-level logic functions
\item Perform optimizations on bit-level logic functions
\item Map bit-level logic and register to gates from cell library
\item Write results to output file 
\end{itemize}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Reading the design}

\begin{frame}[fragile]{\subsecname}
\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont]
read_verilog file1.v
read_verilog -I include_dir -D enable_foo -D WIDTH=12 file2.v
read_verilog -lib cell_library.v

verilog_defaults -add -I include_dir
read_verilog file3.v
read_verilog file4.v
verilog_defaults -clear

verilog_defaults -push
verilog_defaults -add -I include_dir
read_verilog file5.v
read_verilog file6.v
verilog_defaults -pop
\end{lstlisting}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Design elaboration}

\begin{frame}[fragile]{\subsecname}
During design elaboration Yosys figures out how the modules are hierarchically
connected. It also re-runs the AST parts of the Verilog frontend to create
all needed variations of parametric modules.

\bigskip
\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont]
# simplest form. at least this version should be used after reading all input files
#
hierarchy

# recommended form. fail if parts of the design hierarchy are missing. remove
# everything that is unreachable by the top module. mark the top module.
#
hierarchy -check -top top_module
\end{lstlisting}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{The ``proc'' commands}

\begin{frame}[fragile]{\subsecname}
The Verilog frontend converts {\tt always}-blocks to RTL netlists for the
expressions and ``processes'' for the control- and memory elements.

\medskip
The {\tt proc} command transforms this ``processes'' to netlists of RTL
multiplexer and register cells.

\medskip
The {\tt proc} command is actually a macro-command that calls the following
other commands:

\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont]
proc_clean      # remove empty branches and processes
proc_rmdead     # remove unreachable branches
proc_init       # special handling of "initial" blocks
proc_arst       # identify modeling of async resets
proc_mux        # convert decision trees to multiplexer networks
proc_dff        # extract registers from processes
proc_clean      # if all went fine, this should remove all the processes
\end{lstlisting}

\medskip
Many commands can not operate on modules with ``processes'' in them. Usually
a call to {\tt proc} is the first command in the actual synthesis procedure
after design elaboration.

\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{The ``opt'' commands}

\begin{frame}[fragile]{\subsecname}
The {\tt opt} command implements a series of simple optimizations. It also
is a macro command that calls other commands:

\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont]
opt_const               # const folding
opt_share -nomux        # merging identical cells

do
    opt_muxtree         # remove never-active branches from multiplexer tree
    opt_reduce          # consolidate trees of boolean ops to reduce functions
    opt_share           # merging identical cells
    opt_rmdff           # remove/simplify registers with constant inputs
    opt_clean           # remove unused objects (cells, wires) from design
    opt_const           # const folding
while [changed design]
\end{lstlisting}

The command {\tt clean} can be used as alias for {\tt opt\_clean}. And {\tt ;;}
can be used as shortcut for {\tt clean}. For example:

\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont]
proc; opt; memory; opt_const;; fsm;;
\end{lstlisting}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{When to use ``opt'' or ``clean''}

\begin{frame}{\subsecname}
Usually it does not hurt to call {\tt opt} after each regular command in the
synthesis script. But it increases the synthesis time, so it is favourable
to only call {\tt opt} when an improvement can be archieved.

\bigskip
The designs in {\tt yosys-bigsim} are a good playground for experimenting with
the effects of calling {\tt opt} in various places of the flow.

\bigskip
It generally is a good idea us call {\tt opt} before inherently expensive
commands such as {\tt sat} or {\tt freduce}, as the possible gain is much
higher in this cases as the possible loss.

\bigskip
The {\tt clean} command on the other hand is very fast and many commands leave
a mess (dangling signal wires, etc). For example, most commands do not remove
any wires or cells. They just change the connections and depend on a later
call to clean to get rid of the now unused objects. So the occasional {\tt ;;}
is a good idea in every synthesis script.
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{The ``memory'' commands}

\begin{frame}[fragile]{\subsecname}
In the RTL netlist, memory reads and writes are individual cells. This makes
consolidating the number of ports for a memory easier. The {\tt memory}
transforms memories to an implementation. Per default that is logic for address
decoders and registers. It also is a macro command that calls other commands:

\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont]
# this merges registers into the memory read- and write cells.
memory_dff

# this collects all read and write cells for a memory and transforms them
# into one multi-port memory cell.
memory_collect

# this takes the multi-port memory cells and transforms it to address decoder
# logic and registers. This step is skipped if "memory" is called with -nomap.
memory_map
\end{lstlisting}

\bigskip
Usually it is preferred to use architecture-specific RAM resources for memory.
For example:

\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont]
memory -nomap; techmap -map my_memory_map.v; memory_map
\end{lstlisting}

\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{The ``fsm'' commands}

\begin{frame}{\subsecname}
TBD
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Low-Level Synthesis}

\begin{frame}{\subsecname}
TBD
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{The ``techmap'' command}

\begin{frame}{\subsecname}
TBD
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{The ``abc'' command}

\begin{frame}{\subsecname}
TBD
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Other special-purpose mapping commands}

\begin{frame}{\subsecname}
TBD
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

