aboutsummaryrefslogtreecommitdiffstats
path: root/manual/PRESENTATION_Prog.tex
blob: b85eda89272b0cb1cbb3fd059c55fab22c0588cb (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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
pre { line-height: 125%; margin: 0; }
td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #ffffff; }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of a Qt Solutions component.
**
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
**     the names of its contributors may be used to endorse or promote
**     products derived from this software without specific prior written
**     permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
****************************************************************************/


//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists for the convenience
// of Qt Designer.  This header
// file may change from version to version without notice, or even be removed.
//
// We mean it.
//

#ifndef QTPROPERTYBROWSERUTILS_H
#define QTPROPERTYBROWSERUTILS_H

#include <QtCore/QMap>
#include <QtGui/QIcon>
#include <QWidget>
#include <QtCore/QStringList>

#if QT_VERSION >= 0x040400
QT_BEGIN_NAMESPACE
#endif

class QMouseEvent;
class QCheckBox;
class QLineEdit;

class QtCursorDatabase
{
public:
    QtCursorDatabase();

    QStringList cursorShapeNames() const;
    QMap<int, QIcon> cursorShapeIcons() const;
    QString cursorToShapeName(const QCursor &cursor) const;
    QIcon cursorToShapeIcon(const QCursor &cursor) const;
    int cursorToValue(const QCursor &cursor) const;
#ifndef QT_NO_CURSOR
    QCursor valueToCursor(int value) const;
#endif
private:
    void appendCursor(Qt::CursorShape shape, const QString &name, const QIcon &icon);
    QStringList m_cursorNames;
    QMap<int, QIcon> m_cursorIcons;
    QMap<int, Qt::CursorShape> m_valueToCursorShape;
    QMap<Qt::CursorShape, int> m_cursorShapeToValue;
};

class QtPropertyBrowserUtils
{
public:
    static QPixmap brushValuePixmap(const QBrush &b);
    static QIcon brushValueIcon(const QBrush &b);
    static QString colorValueText(const QColor &c);
    static QPixmap fontValuePixmap(const QFont &pre { line-height: 125%; margin: 0; }
td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #ffffff; }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
\section{Writing Yosys extensions in C++}

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

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

\subsection{Program Components and Data Formats}

\begin{frame}{\subsecname}
\begin{center}
\begin{tikzpicture}[scale=0.6, every node/.style={transform shape}]
	\tikzstyle{process} = [draw, fill=green!10, rectangle, minimum height=3em, minimum width=10em, node distance=15em]
	\tikzstyle{data} = [draw, fill=blue!10, ellipse, minimum height=3em, minimum width=7em, node distance=15em]
	\node[process] (vlog) {Verilog Frontend};
	\node[process, dashed, fill=green!5] (vhdl) [right of=vlog] {VHDL Frontend};
	\node[process] (ilang) [right of=vhdl] {Other Frontends};
	\node[data] (ast) [below of=vlog, node distance=5em, xshift=7.5em] {AST};
	\node[process] (astfe) [below of=ast, node distance=5em] {AST Frontend};
	\node[data] (rtlil) [below of=astfe, node distance=5em, xshift=7.5em] {RTLIL};
	\node[process] (pass) [right of=rtlil, node distance=5em, xshift=7.5em] {Passes};
	\node[process] (vlbe) [below of=rtlil, node distance=7em, xshift=-13em] {Verilog Backend};
	\node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {ILANG Backend};
	\node[process, fill=green!5] (otherbe) [below of=rtlil, node distance=7em, xshift=+13em] {Other Backends};

	\draw[-latex] (vlog) -- (ast);
	\draw[-latex] (vhdl) -- (ast);
	\draw[-latex] (ast) -- (astfe);
	\draw[-latex] (astfe) -- (rtlil);
	\draw[-latex] (ilang) -- (rtlil);
	\draw[latex-latex] (rtlil) -- (pass);
	\draw[-latex] (rtlil) -- (vlbe);
	\draw[-latex] (rtlil) -- (ilangbe);
	\draw[-latex] (rtlil) -- (otherbe);
\end{tikzpicture}
\end{center}
\end{frame}

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

\subsection{Simplified RTLIL Entity-Relationship Diagram}

\begin{frame}{\subsecname}
Between passses and frontends/backends the design is stored in Yosys' internal
RTLIL (RTL Intermediate Language) format. For writing Yosys extensions it is
key to understand this format.

\bigskip
\begin{center}
\begin{tikzpicture}[scale=0.6, every node/.style={transform shape}]
	\tikzstyle{entity} = [draw, fill=gray!10, rectangle, minimum height=3em, minimum width=7em, node distance=5em, font={\ttfamily}]
	\node[entity] (design) {RTLIL::Design};
	\node[entity] (module) [right of=design, node distance=11em] {RTLIL::Module} edge [-latex] node[above] {\tiny 1 \hskip3em N} (design);

	\node[entity] (process) [fill=green!10, right of=module, node distance=10em] {RTLIL::Process} (process.west) edge [-latex] (module);
	\node[entity] (memory) [fill=red!10, below of=process] {RTLIL::Memory} edge [-latex] (module);
	\node[entity] (wire) [fill=blue!10, above of=process] {RTLIL::Wire} (wire.west) edge [-latex] (module);
	\node[entity] (cell) [fill=blue!10, above of=wire] {RTLIL::Cell} (cell.west) edge [-latex] (module);

	\node[entity] (case) [fill=green!10, right of=process, node distance=10em] {RTLIL::CaseRule} edge [latex-latex] (process);
	\node[entity] (sync) [fill=green!10, above of=case] {RTLIL::SyncRule} edge [-latex] (process);
	\node[entity] (switch) [fill=green!10, below of=case] {RTLIL::SwitchRule} edge [-latex] (case);
	\draw[latex-] (switch.east) -- ++(1em,0) |- (case.east);
\end{tikzpicture}
\end{center}
\end{frame}

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

\subsection{RTLIL without memories and processes}

\begin{frame}[fragile]{\subsecname}
After the commands {\tt proc} and {\tt memory} (or {\tt memory -nomap}), we are
left with a much simpler version of RTLIL:

\begin{center}
\begin{tikzpicture}[scale=0.6, every node/.style={transform shape}]
	\tikzstyle{entity} = [draw, fill=gray!10, rectangle, minimum height=3em, minimum width=7em, node distance=5em, font={\ttfamily}]
	\node[entity] (design) {RTLIL::Design};
	\node[entity] (module) [right of=design, node distance=11em] {RTLIL::Module} edge [-latex] node[above] {\tiny 1 \hskip3em N} (design);

	\node[entity] (wire) [fill=blue!10, right of=module, node distance=10em] {RTLIL::Wire} (wire.west) edge [-latex] (module);
	\node[entity] (cell) [fill=blue!10, above of=wire] {RTLIL::Cell} (cell.west) edge [-latex] (module);
\end{tikzpicture}
\end{center}

\bigskip
Many commands simply choose to only work on this simpler version:
\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont]
for (RTLIL::Module *module : design->selected_modules() {
    if (module->has_memories_warn() || module->has_processes_warn())
        continue;
    ....
}
\end{lstlisting}

For simplicity we only discuss this version of RTLIL in this presentation.
\end{frame}

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

\subsection{Using dump and show commands}

\begin{frame}{\subsecname}
\begin{itemize}
\item The {\tt dump} command prints the design (or parts of it) in ILANG format. This is
a text representation of RTLIL.

\bigskip
\item The {\tt show} command visualizes how the components in the design are connected.
\end{itemize}

\bigskip
When trying to understand what a command does, create a small test case and
look at the output of {\tt dump} and {\tt show} before and after the command
has been executed.
\end{frame}

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

\subsection{The RTLIL Data Structures}

\begin{frame}{\subsecname}
The RTLIL data structures are simple structs utilizing {\tt pool<>} and
{\tt dict<>} containers (drop-in replacements for {\tt
std::unordered\_set<>} and {\tt std::unordered\_map<>}).

\bigskip
\begin{itemize}
\item Most operations are performed directly on the RTLIL structs without
setter or getter functions.

\bigskip
\item In debug builds a consistency checker is run over the in-memory design
between commands to make sure that the RTLIL representation is intact.

\bigskip
\item Most RTLIL structs have helper methods that perform the most common operations.
\end{itemize}

\bigskip
See {\tt yosys/kernel/rtlil.h} for details.
\end{frame}

\subsubsection{RTLIL::IdString}

\begin{frame}{\subsubsecname}{}
{\tt RTLIL::IdString} in many ways behave like a {\tt std::string}. It is used
for names of RTLIL objects. Internally a RTLIL::IdString object is only a
single integer.

\medskip
The first character of a {\tt RTLIL::IdString} specifies if the name is {\it public\/} or {\it private\/}:

\medskip
\begin{itemize}
\item {\tt RTLIL::IdString[0] == '\textbackslash\textbackslash'}: \\
This is a public name. Usually this means it is a name that was declared in a Verilog file.

\bigskip
\item {\tt RTLIL::IdString[0] == '\$'}: \\
This is a private name. It was assigned by Yosys.
\end{itemize}

\bigskip
Use the {\tt NEW\_ID} macro to create a new unique private name.
\end{frame}

\subsubsection{RTLIL::Design and RTLIL::Module}

\begin{frame}[t, fragile]{\subsubsecname}
The {\tt RTLIL::Design} and {\tt RTLIL::Module} structs are the top-level RTLIL
data structures. Yosys always operates on one active design, but can hold many designs in memory.

\bigskip
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
struct RTLIL::Design {
    dict<RTLIL::IdString, RTLIL::Module*> modules_;
    ...
};

struct RTLIL::Module {
    RTLIL::IdString name;
    dict<RTLIL::IdString, RTLIL::Wire*> wires_;
    dict<RTLIL::IdString, RTLIL::Cell*> cells_;
    std::vector<RTLIL::SigSig> connections_;
    ...
};
\end{lstlisting}

(Use the various accessor functions instead of directly working with the {\tt *\_} members.)
\end{frame}

\subsubsection{The RTLIL::Wire Structure}

\begin{frame}[t, fragile]{\subsubsecname}
Each wire in the design is represented by a {\tt RTLIL::Wire} struct:

\medskip
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
struct RTLIL::Wire {
    RTLIL::IdString name;
    int width, start_offset, port_id;
    bool port_input, port_output;
    ...
};
\end{lstlisting}

\medskip
\hfil\begin{tabular}{p{3cm}l}
{\tt width} \dotfill & The total number of bits. E.g. 10 for {\tt [9:0]}. \\
{\tt start\_offset} \dotfill & The lowest bit index. E.g. 3 for {\tt [5:3]}. \\
{\tt port\_id} \dotfill & Zero for non-ports. Positive index for ports. \\
{\tt port\_input} \dotfill & True for {\tt input} and {\tt inout} ports. \\
{\tt port\_output} \dotfill & True for {\tt output} and {\tt inout} ports. \\
\end{tabular}
\end{frame}

\subsubsection{RTLIL::State and RTLIL::Const}

\begin{frame}[t, fragile]{\subsubsecname}
The {\tt RTLIL::State} enum represents a simple 1-bit logic level:

\smallskip
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
enum RTLIL::State {
    S0 = 0,
    S1 = 1,
    Sx = 2, // undefined value or conflict
    Sz = 3, // high-impedance / not-connected
    Sa = 4, // don't care (used only in cases)
    Sm = 5  // marker (used internally by some passes)
};
\end{lstlisting}

\bigskip
The {\tt RTLIL::Const} struct represents a constant multi-bit value:

\smallskip
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
struct RTLIL::Const {
    std::vector<RTLIL::State> bits;
    ...
};
\end{lstlisting}

\bigskip
Notice that Yosys is not using special {\tt VCC} or {\tt GND} driver cells to represent constants. Instead
constants are part of the RTLIL representation itself.
\end{frame}

\subsubsection{The RTLIL::SigSpec Structure}

\begin{frame}[t, fragile]{\subsubsecname}
The {\tt RTLIL::SigSpec} struct represents a signal vector. Each bit can either be a bit from a wire
or a constant value.

\bigskip
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
struct RTLIL::SigBit
{
    RTLIL::Wire *wire;
    union {
        RTLIL::State data; // used if wire == NULL
        int offset;        // used if wire != NULL
    };
    ...
};

struct RTLIL::SigSpec {
    std::vector<RTLIL::SigBit> bits_; // LSB at index 0
    ...
};
\end{lstlisting}

\bigskip
The {\tt RTLIL::SigSpec} struct has a ton of additional helper methods to compare, analyze, and
manipulate instances of {\tt RTLIL::SigSpec}.
\end{frame}

\subsubsection{The RTLIL::Cell Structure}

\begin{frame}[t, fragile]{\subsubsecname (1/2)}
The {\tt RTLIL::Cell} struct represents an instance of a module or library cell.

\smallskip
The ports of the cell
are associated with {\tt RTLIL::SigSpec} instances and the parameters are associated with {\tt RTLIL::Const}
instances:

\bigskip
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
struct RTLIL::Cell {
    RTLIL::IdString name, type;
    dict<RTLIL::IdString, RTLIL::SigSpec> connections_;
    dict<RTLIL::IdString, RTLIL::Const> parameters;
    ...
};
\end{lstlisting}

\bigskip
The {\tt type} may refer to another module in the same design, a cell name from a cell library, or a
cell name from the internal cell library:

\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont]
$not $pos $neg $and $or $xor $xnor $reduce_and $reduce_or $reduce_xor $reduce_xnor
$reduce_bool $shl $shr $sshl $sshr $lt $le $eq $ne $eqx $nex $ge $gt $add $sub $mul $div $mod
$pow $logic_not $logic_and $logic_or $mux $pmux $slice $concat $lut $assert $sr $dff
$dffsr $adff $dlatch $dlatchsr $memrd $memwr $mem $fsm $_NOT_ $_AND_ $_OR_ $_XOR_ $_MUX_ $_SR_NN_
$_SR_NP_ $_SR_PN_ $_SR_PP_ $_DFF_N_ $_DFF_P_ $_DFF_NN0_ $_DFF_NN1_ $_DFF_NP0_ $_DFF_NP1_ $_DFF_PN0_
$_DFF_PN1_ $_DFF_PP0_ $_DFF_PP1_ $_DFFSR_NNN_ $_DFFSR_NNP_ $_DFFSR_NPN_ $_DFFSR_NPP_ $_DFFSR_PNN_
$_DFFSR_PNP_ $_DFFSR_PPN_ $_DFFSR_PPP_ $_DLATCH_N_ $_DLATCH_P_ $_DLATCHSR_NNN_ $_DLATCHSR_NNP_
$_DLATCHSR_NPN_ $_DLATCHSR_NPP_ $_DLATCHSR_PNN_ $_DLATCHSR_PNP_ $_DLATCHSR_PPN_ $_DLATCHSR_PPP_
\end{lstlisting}
\end{frame}

\begin{frame}[t, fragile]{\subsubsecname (2/2)}
Simulation models (i.e. {\it documentation\/} :-) for the internal cell library:

\smallskip
\hskip2em {\tt yosys/techlibs/common/simlib.v} and \\
\hskip2em {\tt yosys/techlibs/common/simcells.v}

\bigskip
The lower-case cell types (such as {\tt \$and}) are parameterized cells of variable
width. This so-called {\it RTL Cells\/} are the cells described in {\tt simlib.v}.

\bigskip
The upper-case cell types (such as {\tt \$\_AND\_}) are single-bit cells that are not
parameterized. This so-called {\it Internal Logic Gates} are the cells described
in {\tt simcells.v}.

\bigskip
The consistency checker also checks the interfaces to the internal cell library.
If you want to use private cell types for your own purposes, use the {\tt \$\_\_}-prefix
to avoid name collisions.
\end{frame}

\subsubsection{Connecting wires or constant drivers}

\begin{frame}[t, fragile]{\subsubsecname}
Additional connections between wires or between wires and constants are modelled using
{\tt RTLIL::Module::connections}:

\bigskip
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
typedef std::pair<RTLIL::SigSpec, RTLIL::SigSpec> RTLIL::SigSig;

struct RTLIL::Module {
    ...
    std::vector<RTLIL::SigSig> connections_;
    ...
};
\end{lstlisting}

\bigskip
{\tt RTLIL::SigSig::first} is the driven signal and {\tt RTLIL::SigSig::second} is the driving signal.
Example usage (setting wire {\tt foo} to value {\tt 42}):
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
module->connect(module->wire("\\foo"),
                RTLIL::SigSpec(42, module->wire("\\foo")->width));
\end{lstlisting}
\end{frame}

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

\subsection{Creating modules from scratch}

\begin{frame}[t, fragile]{\subsecname}
Let's create the following module using the RTLIL API:

\smallskip
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog]
module absval(input signed [3:0] a, output [3:0] y);
    assign y = a[3] ? -a : a;
endmodule
\end{lstlisting}

\smallskip
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
RTLIL::Module *module = new RTLIL::Module;
module->name = "\\absval";

RTLIL::Wire *a = module->addWire("\\a", 4);
a->port_input = true;
a->port_id = 1;

RTLIL::Wire *y = module->addWire("\\y", 4);
y->port_output = true;
y->port_id = 2;

RTLIL::Wire *a_inv = module->addWire(NEW_ID, 4);
module->addNeg(NEW_ID, a, a_inv, true);
module->addMux(NEW_ID, a, a_inv, RTLIL::SigSpec(a, 1, 3), y);

module->fixup_ports();
\end{lstlisting}
\end{frame}

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

\subsection{Modifying modules}

\begin{frame}{\subsecname}
Most commands modify existing modules, not create new ones.

When modifying existing modules, stick to the following DOs and DON'Ts:

\begin{itemize}
\item Do not remove wires. Simply disconnect them and let a successive {\tt clean} command worry about removing it.

\item Use {\tt module->fixup\_ports()} after changing the {\tt port\_*} properties of wires.

\item You can safely remove cells or change the {\tt connections} property of a cell, but be careful when
changing the size of the {\tt SigSpec} connected to a cell port.

\item Use the {\tt SigMap} helper class (see next slide) when you need a unique handle for each signal bit.
\end{itemize}
\end{frame}

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

\subsection{Using the SigMap helper class}

\begin{frame}[t, fragile]{\subsecname}
Consider the following module:

\smallskip
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog]
module test(input a, output x, y);
    assign x = a, y = a;
endmodule
\end{lstlisting}

In this case {\tt a}, {\tt x}, and {\tt y} are all different names for the same signal. However:

\smallskip
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
RTLIL::SigSpec a(module->wire("\\a")), x(module->wire("\\x")),
                                       y(module->wire("\\y"));
log("%d %d %d\n", a == x, x == y, y == a); // will print "0 0 0"
\end{lstlisting}

The {\tt SigMap} helper class can be used to map all such aliasing signals to a
unique signal from the group (usually the wire that is directly driven by a cell or port).

\smallskip
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
SigMap sigmap(module);
log("%d %d %d\n", sigmap(a) == sigmap(x), sigmap(x) == sigmap(y),
                  sigmap(y) == sigmap(a)); // will print "1 1 1"
\end{lstlisting}
\end{frame}

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

\subsection{Printing log messages}

\begin{frame}[t, fragile]{\subsecname}
The {\tt log()} function is a {\tt printf()}-like function that can be used to create log messages.

\medskip
Use {\tt log\_signal()} to create a C-string for a SigSpec object\footnote[frame]{The pointer returned
by {\tt log\_signal()} is automatically freed by the log framework at a later time.}:
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
log("Mapped signal x: %s\n", log_signal(sigmap(x)));
\end{lstlisting}

\medskip
Use {\tt log\_id()} to create a C-string for an {\tt RTLIL::IdString}:
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
log("Name of this module: %s\n", log_id(module->name));
\end{lstlisting}

\medskip
Use {\tt log\_header()} and {\tt log\_push()}/{\tt log\_pop()} to structure log messages:
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
log_header(design, "Doing important stuff!\n");
log_push();
for (int i = 0; i < 10; i++)
    log("Log message #%d.\n", i);
log_pop();
\end{lstlisting}
\end{frame}

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

\subsection{Error handling}

\begin{frame}[t, fragile]{\subsecname}
Use {\tt log\_error()} to report a non-recoverable error:

\medskip
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
if (design->modules.count(module->name) != 0)
    log_error("A module with the name %s already exists!\n",
            RTLIL::id2cstr(module->name));
\end{lstlisting}

\bigskip
Use {\tt log\_cmd\_error()} to report a recoverable error:
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
if (design->selection_stack.back().empty())
    log_cmd_error("This command can't operator on an empty selection!\n");
\end{lstlisting}

\bigskip
Use {\tt log\_assert()} and {\tt log\_abort()} instead of {\tt assert()} and {\tt abort()}.
\end{frame}

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

\subsection{Creating a command}

\begin{frame}[t, fragile]{\subsecname}
Simply create a global instance of a class derived from {\tt Pass} to create
a new yosys command:

\bigskip
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
#include "kernel/yosys.h"
USING_YOSYS_NAMESPACE

struct MyPass : public Pass {
    MyPass() : Pass("my_cmd", "just a simple test") { }
    virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
    {
        log("Arguments to my_cmd:\n");
        for (auto &arg : args)
            log("  %s\n", arg.c_str());

        log("Modules in current design:\n");
        for (auto mod : design->modules())
            log("  %s (%d wires, %d cells)\n", log_id(mod),
                    GetSize(mod->wires()), GetSize(mod->cells()));
    }
} MyPass;
\end{lstlisting}
\end{frame}

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

\subsection{Creating a plugin}

\begin{frame}[fragile]{\subsecname}
Yosys can be extended by adding additional C++ code to the Yosys code base, or
by loading plugins into Yosys.

\bigskip
Use the following command to compile a Yosys plugin:
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont]
yosys-config --exec --cxx --cxxflags --ldflags \
             -o my_cmd.so -shared my_cmd.cc --ldlibs
\end{lstlisting}

\bigskip
Or shorter:
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont]
yosys-config --build my_cmd.so my_cmd.cc
\end{lstlisting}

\bigskip
Load the plugin using the yosys {\tt -m} option:
\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont]
yosys -m ./my_cmd.so -p 'my_cmd foo bar'
\end{lstlisting}
\end{frame}

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

\subsection{Summary}

\begin{frame}{\subsecname}
\begin{itemize}
\item Writing Yosys extensions is very straight-forward.
\item \dots and even simpler if you don't need RTLIL::Memory or RTLIL::Process objects.

\bigskip
\item Writing synthesis software? Consider learning the Yosys API and make your work
part of the Yosys framework.
\end{itemize}

\bigskip
\bigskip
\begin{center}
Questions?
\end{center}

\bigskip
\bigskip
\begin{center}
\url{http://www.clifford.at/yosys/}
\end{center}
\end{frame}