Merge pull request #946 from YosysHQ/clifford/specify
[yosys.git] / manual / PRESENTATION_Prog.tex
1
2 \section{Writing Yosys extensions in C++}
3
4 \begin{frame}
5 \sectionpage
6 \end{frame}
7
8 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9
10 \subsection{Program Components and Data Formats}
11
12 \begin{frame}{\subsecname}
13 \begin{center}
14 \begin{tikzpicture}[scale=0.6, every node/.style={transform shape}]
15 \tikzstyle{process} = [draw, fill=green!10, rectangle, minimum height=3em, minimum width=10em, node distance=15em]
16 \tikzstyle{data} = [draw, fill=blue!10, ellipse, minimum height=3em, minimum width=7em, node distance=15em]
17 \node[process] (vlog) {Verilog Frontend};
18 \node[process, dashed, fill=green!5] (vhdl) [right of=vlog] {VHDL Frontend};
19 \node[process] (ilang) [right of=vhdl] {Other Frontends};
20 \node[data] (ast) [below of=vlog, node distance=5em, xshift=7.5em] {AST};
21 \node[process] (astfe) [below of=ast, node distance=5em] {AST Frontend};
22 \node[data] (rtlil) [below of=astfe, node distance=5em, xshift=7.5em] {RTLIL};
23 \node[process] (pass) [right of=rtlil, node distance=5em, xshift=7.5em] {Passes};
24 \node[process] (vlbe) [below of=rtlil, node distance=7em, xshift=-13em] {Verilog Backend};
25 \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {ILANG Backend};
26 \node[process, fill=green!5] (otherbe) [below of=rtlil, node distance=7em, xshift=+13em] {Other Backends};
27
28 \draw[-latex] (vlog) -- (ast);
29 \draw[-latex] (vhdl) -- (ast);
30 \draw[-latex] (ast) -- (astfe);
31 \draw[-latex] (astfe) -- (rtlil);
32 \draw[-latex] (ilang) -- (rtlil);
33 \draw[latex-latex] (rtlil) -- (pass);
34 \draw[-latex] (rtlil) -- (vlbe);
35 \draw[-latex] (rtlil) -- (ilangbe);
36 \draw[-latex] (rtlil) -- (otherbe);
37 \end{tikzpicture}
38 \end{center}
39 \end{frame}
40
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42
43 \subsection{Simplified RTLIL Entity-Relationship Diagram}
44
45 \begin{frame}{\subsecname}
46 Between passses and frontends/backends the design is stored in Yosys' internal
47 RTLIL (RTL Intermediate Language) format. For writing Yosys extensions it is
48 key to understand this format.
49
50 \bigskip
51 \begin{center}
52 \begin{tikzpicture}[scale=0.6, every node/.style={transform shape}]
53 \tikzstyle{entity} = [draw, fill=gray!10, rectangle, minimum height=3em, minimum width=7em, node distance=5em, font={\ttfamily}]
54 \node[entity] (design) {RTLIL::Design};
55 \node[entity] (module) [right of=design, node distance=11em] {RTLIL::Module} edge [-latex] node[above] {\tiny 1 \hskip3em N} (design);
56
57 \node[entity] (process) [fill=green!10, right of=module, node distance=10em] {RTLIL::Process} (process.west) edge [-latex] (module);
58 \node[entity] (memory) [fill=red!10, below of=process] {RTLIL::Memory} edge [-latex] (module);
59 \node[entity] (wire) [fill=blue!10, above of=process] {RTLIL::Wire} (wire.west) edge [-latex] (module);
60 \node[entity] (cell) [fill=blue!10, above of=wire] {RTLIL::Cell} (cell.west) edge [-latex] (module);
61
62 \node[entity] (case) [fill=green!10, right of=process, node distance=10em] {RTLIL::CaseRule} edge [latex-latex] (process);
63 \node[entity] (sync) [fill=green!10, above of=case] {RTLIL::SyncRule} edge [-latex] (process);
64 \node[entity] (switch) [fill=green!10, below of=case] {RTLIL::SwitchRule} edge [-latex] (case);
65 \draw[latex-] (switch.east) -- ++(1em,0) |- (case.east);
66 \end{tikzpicture}
67 \end{center}
68 \end{frame}
69
70 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71
72 \subsection{RTLIL without memories and processes}
73
74 \begin{frame}[fragile]{\subsecname}
75 After the commands {\tt proc} and {\tt memory} (or {\tt memory -nomap}), we are
76 left with a much simpler version of RTLIL:
77
78 \begin{center}
79 \begin{tikzpicture}[scale=0.6, every node/.style={transform shape}]
80 \tikzstyle{entity} = [draw, fill=gray!10, rectangle, minimum height=3em, minimum width=7em, node distance=5em, font={\ttfamily}]
81 \node[entity] (design) {RTLIL::Design};
82 \node[entity] (module) [right of=design, node distance=11em] {RTLIL::Module} edge [-latex] node[above] {\tiny 1 \hskip3em N} (design);
83
84 \node[entity] (wire) [fill=blue!10, right of=module, node distance=10em] {RTLIL::Wire} (wire.west) edge [-latex] (module);
85 \node[entity] (cell) [fill=blue!10, above of=wire] {RTLIL::Cell} (cell.west) edge [-latex] (module);
86 \end{tikzpicture}
87 \end{center}
88
89 \bigskip
90 Many commands simply choose to only work on this simpler version:
91 \begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont]
92 for (RTLIL::Module *module : design->selected_modules() {
93 if (module->has_memories_warn() || module->has_processes_warn())
94 continue;
95 ....
96 }
97 \end{lstlisting}
98
99 For simplicity we only discuss this version of RTLIL in this presentation.
100 \end{frame}
101
102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
103
104 \subsection{Using dump and show commands}
105
106 \begin{frame}{\subsecname}
107 \begin{itemize}
108 \item The {\tt dump} command prints the design (or parts of it) in ILANG format. This is
109 a text representation of RTLIL.
110
111 \bigskip
112 \item The {\tt show} command visualizes how the components in the design are connected.
113 \end{itemize}
114
115 \bigskip
116 When trying to understand what a command does, create a small test case and
117 look at the output of {\tt dump} and {\tt show} before and after the command
118 has been executed.
119 \end{frame}
120
121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122
123 \subsection{The RTLIL Data Structures}
124
125 \begin{frame}{\subsecname}
126 The RTLIL data structures are simple structs utilizing {\tt pool<>} and
127 {\tt dict<>} containers (drop-in replacements for {\tt
128 std::unordered\_set<>} and {\tt std::unordered\_map<>}).
129
130 \bigskip
131 \begin{itemize}
132 \item Most operations are performed directly on the RTLIL structs without
133 setter or getter functions.
134
135 \bigskip
136 \item In debug builds a consistency checker is run over the in-memory design
137 between commands to make sure that the RTLIL representation is intact.
138
139 \bigskip
140 \item Most RTLIL structs have helper methods that perform the most common operations.
141 \end{itemize}
142
143 \bigskip
144 See {\tt yosys/kernel/rtlil.h} for details.
145 \end{frame}
146
147 \subsubsection{RTLIL::IdString}
148
149 \begin{frame}{\subsubsecname}{}
150 {\tt RTLIL::IdString} in many ways behave like a {\tt std::string}. It is used
151 for names of RTLIL objects. Internally a RTLIL::IdString object is only a
152 single integer.
153
154 \medskip
155 The first character of a {\tt RTLIL::IdString} specifies if the name is {\it public\/} or {\it private\/}:
156
157 \medskip
158 \begin{itemize}
159 \item {\tt RTLIL::IdString[0] == '\textbackslash\textbackslash'}: \\
160 This is a public name. Usually this means it is a name that was declared in a Verilog file.
161
162 \bigskip
163 \item {\tt RTLIL::IdString[0] == '\$'}: \\
164 This is a private name. It was assigned by Yosys.
165 \end{itemize}
166
167 \bigskip
168 Use the {\tt NEW\_ID} macro to create a new unique private name.
169 \end{frame}
170
171 \subsubsection{RTLIL::Design and RTLIL::Module}
172
173 \begin{frame}[t, fragile]{\subsubsecname}
174 The {\tt RTLIL::Design} and {\tt RTLIL::Module} structs are the top-level RTLIL
175 data structures. Yosys always operates on one active design, but can hold many designs in memory.
176
177 \bigskip
178 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
179 struct RTLIL::Design {
180 dict<RTLIL::IdString, RTLIL::Module*> modules_;
181 ...
182 };
183
184 struct RTLIL::Module {
185 RTLIL::IdString name;
186 dict<RTLIL::IdString, RTLIL::Wire*> wires_;
187 dict<RTLIL::IdString, RTLIL::Cell*> cells_;
188 std::vector<RTLIL::SigSig> connections_;
189 ...
190 };
191 \end{lstlisting}
192
193 (Use the various accessor functions instead of directly working with the {\tt *\_} members.)
194 \end{frame}
195
196 \subsubsection{The RTLIL::Wire Structure}
197
198 \begin{frame}[t, fragile]{\subsubsecname}
199 Each wire in the design is represented by a {\tt RTLIL::Wire} struct:
200
201 \medskip
202 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
203 struct RTLIL::Wire {
204 RTLIL::IdString name;
205 int width, start_offset, port_id;
206 bool port_input, port_output;
207 ...
208 };
209 \end{lstlisting}
210
211 \medskip
212 \hfil\begin{tabular}{p{3cm}l}
213 {\tt width} \dotfill & The total number of bits. E.g. 10 for {\tt [9:0]}. \\
214 {\tt start\_offset} \dotfill & The lowest bit index. E.g. 3 for {\tt [5:3]}. \\
215 {\tt port\_id} \dotfill & Zero for non-ports. Positive index for ports. \\
216 {\tt port\_input} \dotfill & True for {\tt input} and {\tt inout} ports. \\
217 {\tt port\_output} \dotfill & True for {\tt output} and {\tt inout} ports. \\
218 \end{tabular}
219 \end{frame}
220
221 \subsubsection{RTLIL::State and RTLIL::Const}
222
223 \begin{frame}[t, fragile]{\subsubsecname}
224 The {\tt RTLIL::State} enum represents a simple 1-bit logic level:
225
226 \smallskip
227 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
228 enum RTLIL::State {
229 S0 = 0,
230 S1 = 1,
231 Sx = 2, // undefined value or conflict
232 Sz = 3, // high-impedance / not-connected
233 Sa = 4, // don't care (used only in cases)
234 Sm = 5 // marker (used internally by some passes)
235 };
236 \end{lstlisting}
237
238 \bigskip
239 The {\tt RTLIL::Const} struct represents a constant multi-bit value:
240
241 \smallskip
242 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
243 struct RTLIL::Const {
244 std::vector<RTLIL::State> bits;
245 ...
246 };
247 \end{lstlisting}
248
249 \bigskip
250 Notice that Yosys is not using special {\tt VCC} or {\tt GND} driver cells to represent constants. Instead
251 constants are part of the RTLIL representation itself.
252 \end{frame}
253
254 \subsubsection{The RTLIL::SigSpec Structure}
255
256 \begin{frame}[t, fragile]{\subsubsecname}
257 The {\tt RTLIL::SigSpec} struct represents a signal vector. Each bit can either be a bit from a wire
258 or a constant value.
259
260 \bigskip
261 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
262 struct RTLIL::SigBit
263 {
264 RTLIL::Wire *wire;
265 union {
266 RTLIL::State data; // used if wire == NULL
267 int offset; // used if wire != NULL
268 };
269 ...
270 };
271
272 struct RTLIL::SigSpec {
273 std::vector<RTLIL::SigBit> bits_; // LSB at index 0
274 ...
275 };
276 \end{lstlisting}
277
278 \bigskip
279 The {\tt RTLIL::SigSpec} struct has a ton of additional helper methods to compare, analyze, and
280 manipulate instances of {\tt RTLIL::SigSpec}.
281 \end{frame}
282
283 \subsubsection{The RTLIL::Cell Structure}
284
285 \begin{frame}[t, fragile]{\subsubsecname (1/2)}
286 The {\tt RTLIL::Cell} struct represents an instance of a module or library cell.
287
288 \smallskip
289 The ports of the cell
290 are associated with {\tt RTLIL::SigSpec} instances and the parameters are associated with {\tt RTLIL::Const}
291 instances:
292
293 \bigskip
294 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
295 struct RTLIL::Cell {
296 RTLIL::IdString name, type;
297 dict<RTLIL::IdString, RTLIL::SigSpec> connections_;
298 dict<RTLIL::IdString, RTLIL::Const> parameters;
299 ...
300 };
301 \end{lstlisting}
302
303 \bigskip
304 The {\tt type} may refer to another module in the same design, a cell name from a cell library, or a
305 cell name from the internal cell library:
306
307 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont]
308 $not $pos $neg $and $or $xor $xnor $reduce_and $reduce_or $reduce_xor $reduce_xnor
309 $reduce_bool $shl $shr $sshl $sshr $lt $le $eq $ne $eqx $nex $ge $gt $add $sub $mul $div $mod
310 $pow $logic_not $logic_and $logic_or $mux $pmux $slice $concat $lut $assert $sr $dff
311 $dffsr $adff $dlatch $dlatchsr $memrd $memwr $mem $fsm $_NOT_ $_AND_ $_OR_ $_XOR_ $_MUX_ $_SR_NN_
312 $_SR_NP_ $_SR_PN_ $_SR_PP_ $_DFF_N_ $_DFF_P_ $_DFF_NN0_ $_DFF_NN1_ $_DFF_NP0_ $_DFF_NP1_ $_DFF_PN0_
313 $_DFF_PN1_ $_DFF_PP0_ $_DFF_PP1_ $_DFFSR_NNN_ $_DFFSR_NNP_ $_DFFSR_NPN_ $_DFFSR_NPP_ $_DFFSR_PNN_
314 $_DFFSR_PNP_ $_DFFSR_PPN_ $_DFFSR_PPP_ $_DLATCH_N_ $_DLATCH_P_ $_DLATCHSR_NNN_ $_DLATCHSR_NNP_
315 $_DLATCHSR_NPN_ $_DLATCHSR_NPP_ $_DLATCHSR_PNN_ $_DLATCHSR_PNP_ $_DLATCHSR_PPN_ $_DLATCHSR_PPP_
316 \end{lstlisting}
317 \end{frame}
318
319 \begin{frame}[t, fragile]{\subsubsecname (2/2)}
320 Simulation models (i.e. {\it documentation\/} :-) for the internal cell library:
321
322 \smallskip
323 \hskip2em {\tt yosys/techlibs/common/simlib.v} and \\
324 \hskip2em {\tt yosys/techlibs/common/simcells.v}
325
326 \bigskip
327 The lower-case cell types (such as {\tt \$and}) are parameterized cells of variable
328 width. This so-called {\it RTL Cells\/} are the cells described in {\tt simlib.v}.
329
330 \bigskip
331 The upper-case cell types (such as {\tt \$\_AND\_}) are single-bit cells that are not
332 parameterized. This so-called {\it Internal Logic Gates} are the cells described
333 in {\tt simcells.v}.
334
335 \bigskip
336 The consistency checker also checks the interfaces to the internal cell library.
337 If you want to use private cell types for your own purposes, use the {\tt \$\_\_}-prefix
338 to avoid name collisions.
339 \end{frame}
340
341 \subsubsection{Connecting wires or constant drivers}
342
343 \begin{frame}[t, fragile]{\subsubsecname}
344 Additional connections between wires or between wires and constants are modelled using
345 {\tt RTLIL::Module::connections}:
346
347 \bigskip
348 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
349 typedef std::pair<RTLIL::SigSpec, RTLIL::SigSpec> RTLIL::SigSig;
350
351 struct RTLIL::Module {
352 ...
353 std::vector<RTLIL::SigSig> connections_;
354 ...
355 };
356 \end{lstlisting}
357
358 \bigskip
359 {\tt RTLIL::SigSig::first} is the driven signal and {\tt RTLIL::SigSig::second} is the driving signal.
360 Example usage (setting wire {\tt foo} to value {\tt 42}):
361 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
362 module->connect(module->wire("\\foo"),
363 RTLIL::SigSpec(42, module->wire("\\foo")->width));
364 \end{lstlisting}
365 \end{frame}
366
367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
368
369 \subsection{Creating modules from scratch}
370
371 \begin{frame}[t, fragile]{\subsecname}
372 Let's create the following module using the RTLIL API:
373
374 \smallskip
375 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog]
376 module absval(input signed [3:0] a, output [3:0] y);
377 assign y = a[3] ? -a : a;
378 endmodule
379 \end{lstlisting}
380
381 \smallskip
382 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
383 RTLIL::Module *module = new RTLIL::Module;
384 module->name = "\\absval";
385
386 RTLIL::Wire *a = module->addWire("\\a", 4);
387 a->port_input = true;
388 a->port_id = 1;
389
390 RTLIL::Wire *y = module->addWire("\\y", 4);
391 y->port_output = true;
392 y->port_id = 2;
393
394 RTLIL::Wire *a_inv = module->addWire(NEW_ID, 4);
395 module->addNeg(NEW_ID, a, a_inv, true);
396 module->addMux(NEW_ID, a, a_inv, RTLIL::SigSpec(a, 1, 3), y);
397
398 module->fixup_ports();
399 \end{lstlisting}
400 \end{frame}
401
402 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
403
404 \subsection{Modifying modules}
405
406 \begin{frame}{\subsecname}
407 Most commands modify existing modules, not create new ones.
408
409 When modifying existing modules, stick to the following DOs and DON'Ts:
410
411 \begin{itemize}
412 \item Do not remove wires. Simply disconnect them and let a successive {\tt clean} command worry about removing it.
413
414 \item Use {\tt module->fixup\_ports()} after changing the {\tt port\_*} properties of wires.
415
416 \item You can safely remove cells or change the {\tt connections} property of a cell, but be careful when
417 changing the size of the {\tt SigSpec} connected to a cell port.
418
419 \item Use the {\tt SigMap} helper class (see next slide) when you need a unique handle for each signal bit.
420 \end{itemize}
421 \end{frame}
422
423 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
424
425 \subsection{Using the SigMap helper class}
426
427 \begin{frame}[t, fragile]{\subsecname}
428 Consider the following module:
429
430 \smallskip
431 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog]
432 module test(input a, output x, y);
433 assign x = a, y = a;
434 endmodule
435 \end{lstlisting}
436
437 In this case {\tt a}, {\tt x}, and {\tt y} are all different names for the same signal. However:
438
439 \smallskip
440 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
441 RTLIL::SigSpec a(module->wire("\\a")), x(module->wire("\\x")),
442 y(module->wire("\\y"));
443 log("%d %d %d\n", a == x, x == y, y == a); // will print "0 0 0"
444 \end{lstlisting}
445
446 The {\tt SigMap} helper class can be used to map all such aliasing signals to a
447 unique signal from the group (usually the wire that is directly driven by a cell or port).
448
449 \smallskip
450 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
451 SigMap sigmap(module);
452 log("%d %d %d\n", sigmap(a) == sigmap(x), sigmap(x) == sigmap(y),
453 sigmap(y) == sigmap(a)); // will print "1 1 1"
454 \end{lstlisting}
455 \end{frame}
456
457 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
458
459 \subsection{Printing log messages}
460
461 \begin{frame}[t, fragile]{\subsecname}
462 The {\tt log()} function is a {\tt printf()}-like function that can be used to create log messages.
463
464 \medskip
465 Use {\tt log\_signal()} to create a C-string for a SigSpec object\footnote[frame]{The pointer returned
466 by {\tt log\_signal()} is automatically freed by the log framework at a later time.}:
467 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
468 log("Mapped signal x: %s\n", log_signal(sigmap(x)));
469 \end{lstlisting}
470
471 \medskip
472 Use {\tt log\_id()} to create a C-string for an {\tt RTLIL::IdString}:
473 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
474 log("Name of this module: %s\n", log_id(module->name));
475 \end{lstlisting}
476
477 \medskip
478 Use {\tt log\_header()} and {\tt log\_push()}/{\tt log\_pop()} to structure log messages:
479 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
480 log_header(design, "Doing important stuff!\n");
481 log_push();
482 for (int i = 0; i < 10; i++)
483 log("Log message #%d.\n", i);
484 log_pop();
485 \end{lstlisting}
486 \end{frame}
487
488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
489
490 \subsection{Error handling}
491
492 \begin{frame}[t, fragile]{\subsecname}
493 Use {\tt log\_error()} to report a non-recoverable error:
494
495 \medskip
496 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
497 if (design->modules.count(module->name) != 0)
498 log_error("A module with the name %s already exists!\n",
499 RTLIL::id2cstr(module->name));
500 \end{lstlisting}
501
502 \bigskip
503 Use {\tt log\_cmd\_error()} to report a recoverable error:
504 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
505 if (design->selection_stack.back().empty())
506 log_cmd_error("This command can't operator on an empty selection!\n");
507 \end{lstlisting}
508
509 \bigskip
510 Use {\tt log\_assert()} and {\tt log\_abort()} instead of {\tt assert()} and {\tt abort()}.
511 \end{frame}
512
513 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
514
515 \subsection{Creating a command}
516
517 \begin{frame}[t, fragile]{\subsecname}
518 Simply create a global instance of a class derived from {\tt Pass} to create
519 a new yosys command:
520
521 \bigskip
522 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++]
523 #include "kernel/yosys.h"
524 USING_YOSYS_NAMESPACE
525
526 struct MyPass : public Pass {
527 MyPass() : Pass("my_cmd", "just a simple test") { }
528 virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
529 {
530 log("Arguments to my_cmd:\n");
531 for (auto &arg : args)
532 log(" %s\n", arg.c_str());
533
534 log("Modules in current design:\n");
535 for (auto mod : design->modules())
536 log(" %s (%d wires, %d cells)\n", log_id(mod),
537 GetSize(mod->wires()), GetSize(mod->cells()));
538 }
539 } MyPass;
540 \end{lstlisting}
541 \end{frame}
542
543 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
544
545 \subsection{Creating a plugin}
546
547 \begin{frame}[fragile]{\subsecname}
548 Yosys can be extended by adding additional C++ code to the Yosys code base, or
549 by loading plugins into Yosys.
550
551 \bigskip
552 Use the following command to compile a Yosys plugin:
553 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont]
554 yosys-config --exec --cxx --cxxflags --ldflags \
555 -o my_cmd.so -shared my_cmd.cc --ldlibs
556 \end{lstlisting}
557
558 \bigskip
559 Or shorter:
560 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont]
561 yosys-config --build my_cmd.so my_cmd.cc
562 \end{lstlisting}
563
564 \bigskip
565 Load the plugin using the yosys {\tt -m} option:
566 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont]
567 yosys -m ./my_cmd.so -p 'my_cmd foo bar'
568 \end{lstlisting}
569 \end{frame}
570
571 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
572
573 \subsection{Summary}
574
575 \begin{frame}{\subsecname}
576 \begin{itemize}
577 \item Writing Yosys extensions is very straight-forward.
578 \item \dots and even simpler if you don't need RTLIL::Memory or RTLIL::Process objects.
579
580 \bigskip
581 \item Writing synthesis software? Consider learning the Yosys API and make your work
582 part of the Yosys framework.
583 \end{itemize}
584
585 \bigskip
586 \bigskip
587 \begin{center}
588 Questions?
589 \end{center}
590
591 \bigskip
592 \bigskip
593 \begin{center}
594 \url{http://www.clifford.at/yosys/}
595 \end{center}
596 \end{frame}
597