2 \section{Writing Yosys extensions in C++
}
8 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 \subsection{Program Components and Data Formats
}
12 \begin{frame
}{\subsecname}
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
] {RTLIL Backend
};
26 \node[process, fill=green!
5] (otherbe)
[below of=rtlil, node distance=
7em, xshift=+
13em
] {Other Backends
};
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);
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 \subsection{Simplified RTLIL Entity-Relationship Diagram
}
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.
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);
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);
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);
70 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72 \subsection{RTLIL without memories and processes
}
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:
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);
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);
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())
99 For simplicity we only discuss this version of RTLIL in this presentation.
102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
104 \subsection{Using dump and show commands
}
106 \begin{frame
}{\subsecname}
108 \item The
{\tt dump
} command prints the design (or parts of it) in the text representation of RTLIL.
111 \item The
{\tt show
} command visualizes how the components in the design are connected.
115 When trying to understand what a command does, create a small test case and
116 look at the output of
{\tt dump
} and
{\tt show
} before and after the command
120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122 \subsection{The RTLIL Data Structures
}
124 \begin{frame
}{\subsecname}
125 The RTLIL data structures are simple structs utilizing
{\tt pool<>
} and
126 {\tt dict<>
} containers (drop-in replacements for
{\tt
127 std::unordered
\_set<>
} and
{\tt std::unordered
\_map<>
}).
131 \item Most operations are performed directly on the RTLIL structs without
132 setter or getter functions.
135 \item In debug builds a consistency checker is run over the in-memory design
136 between commands to make sure that the RTLIL representation is intact.
139 \item Most RTLIL structs have helper methods that perform the most common operations.
143 See
{\tt yosys/kernel/rtlil.h
} for details.
146 \subsubsection{RTLIL::IdString
}
148 \begin{frame
}{\subsubsecname}{}
149 {\tt RTLIL::IdString
} in many ways behave like a
{\tt std::string
}. It is used
150 for names of RTLIL objects. Internally a RTLIL::IdString object is only a
154 The first character of a
{\tt RTLIL::IdString
} specifies if the name is
{\it public\/
} or
{\it private\/
}:
158 \item {\tt RTLIL::IdString
[0] == '
\textbackslash\textbackslash'
}: \\
159 This is a public name. Usually this means it is a name that was declared in a Verilog file.
162 \item {\tt RTLIL::IdString
[0] == '\$'
}: \\
163 This is a private name. It was assigned by Yosys.
167 Use the
{\tt NEW
\_ID} macro to create a new unique private name.
170 \subsubsection{RTLIL::Design and RTLIL::Module
}
172 \begin{frame
}[t, fragile
]{\subsubsecname}
173 The
{\tt RTLIL::Design
} and
{\tt RTLIL::Module
} structs are the top-level RTLIL
174 data structures. Yosys always operates on one active design, but can hold many designs in memory.
177 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
178 struct RTLIL::Design
{
179 dict<RTLIL::IdString, RTLIL::Module*> modules_;
183 struct RTLIL::Module
{
184 RTLIL::IdString name;
185 dict<RTLIL::IdString, RTLIL::Wire*> wires_;
186 dict<RTLIL::IdString, RTLIL::Cell*> cells_;
187 std::vector<RTLIL::SigSig> connections_;
192 (Use the various accessor functions instead of directly working with the
{\tt *
\_} members.)
195 \subsubsection{The RTLIL::Wire Structure
}
197 \begin{frame
}[t, fragile
]{\subsubsecname}
198 Each wire in the design is represented by a
{\tt RTLIL::Wire
} struct:
201 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
203 RTLIL::IdString name;
204 int width, start_offset, port_id;
205 bool port_input, port_output;
211 \hfil\begin{tabular
}{p
{3cm
}l
}
212 {\tt width
} \dotfill & The total number of bits. E.g.
10 for
{\tt [9:
0]}. \\
213 {\tt start
\_offset} \dotfill & The lowest bit index. E.g.
3 for
{\tt [5:
3]}. \\
214 {\tt port
\_id} \dotfill & Zero for non-ports. Positive index for ports. \\
215 {\tt port
\_input} \dotfill & True for
{\tt input
} and
{\tt inout
} ports. \\
216 {\tt port
\_output} \dotfill & True for
{\tt output
} and
{\tt inout
} ports. \\
220 \subsubsection{RTLIL::State and RTLIL::Const
}
222 \begin{frame
}[t, fragile
]{\subsubsecname}
223 The
{\tt RTLIL::State
} enum represents a simple
1-bit logic level:
226 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
230 Sx =
2, // undefined value or conflict
231 Sz =
3, // high-impedance / not-connected
232 Sa =
4, // don't care (used only in cases)
233 Sm =
5 // marker (used internally by some passes)
238 The
{\tt RTLIL::Const
} struct represents a constant multi-bit value:
241 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
242 struct RTLIL::Const
{
243 std::vector<RTLIL::State> bits;
249 Notice that Yosys is not using special
{\tt VCC
} or
{\tt GND
} driver cells to represent constants. Instead
250 constants are part of the RTLIL representation itself.
253 \subsubsection{The RTLIL::SigSpec Structure
}
255 \begin{frame
}[t, fragile
]{\subsubsecname}
256 The
{\tt RTLIL::SigSpec
} struct represents a signal vector. Each bit can either be a bit from a wire
260 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
265 RTLIL::State data; // used if wire == NULL
266 int offset; // used if wire != NULL
271 struct RTLIL::SigSpec
{
272 std::vector<RTLIL::SigBit> bits_; // LSB at index
0
278 The
{\tt RTLIL::SigSpec
} struct has a ton of additional helper methods to compare, analyze, and
279 manipulate instances of
{\tt RTLIL::SigSpec
}.
282 \subsubsection{The RTLIL::Cell Structure
}
284 \begin{frame
}[t, fragile
]{\subsubsecname (
1/
2)
}
285 The
{\tt RTLIL::Cell
} struct represents an instance of a module or library cell.
288 The ports of the cell
289 are associated with
{\tt RTLIL::SigSpec
} instances and the parameters are associated with
{\tt RTLIL::Const
}
293 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
295 RTLIL::IdString name, type;
296 dict<RTLIL::IdString, RTLIL::SigSpec> connections_;
297 dict<RTLIL::IdString, RTLIL::Const> parameters;
303 The
{\tt type
} may refer to another module in the same design, a cell name from a cell library, or a
304 cell name from the internal cell library:
306 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{6pt
}{7pt
}\selectfont]
307 $not $pos $neg $and $or $xor $xnor $reduce_and $reduce_or $reduce_xor $reduce_xnor
308 $reduce_bool $shl $shr $sshl $sshr $lt $le $eq $ne $eqx $nex $ge $gt $add $sub $mul $div $mod
309 $divfloor $modfloor $pow $logic_not $logic_and $logic_or $mux $pmux $slice $concat $lut $assert $sr $dff
310 $dffsr $adff $dlatch $dlatchsr $memrd $memwr $mem $fsm $_NOT_ $_AND_ $_OR_ $_XOR_ $_MUX_ $_SR_NN_
311 $_SR_NP_ $_SR_PN_ $_SR_PP_ $_DFF_N_ $_DFF_P_ $_DFF_NN0_ $_DFF_NN1_ $_DFF_NP0_ $_DFF_NP1_ $_DFF_PN0_
312 $_DFF_PN1_ $_DFF_PP0_ $_DFF_PP1_ $_DFFSR_NNN_ $_DFFSR_NNP_ $_DFFSR_NPN_ $_DFFSR_NPP_ $_DFFSR_PNN_
313 $_DFFSR_PNP_ $_DFFSR_PPN_ $_DFFSR_PPP_ $_DLATCH_N_ $_DLATCH_P_ $_DLATCHSR_NNN_ $_DLATCHSR_NNP_
314 $_DLATCHSR_NPN_ $_DLATCHSR_NPP_ $_DLATCHSR_PNN_ $_DLATCHSR_PNP_ $_DLATCHSR_PPN_ $_DLATCHSR_PPP_
318 \begin{frame
}[t, fragile
]{\subsubsecname (
2/
2)
}
319 Simulation models (i.e.
{\it documentation\/
} :-) for the internal cell library:
322 \hskip2em {\tt yosys/techlibs/common/simlib.v
} and \\
323 \hskip2em {\tt yosys/techlibs/common/simcells.v
}
326 The lower-case cell types (such as
{\tt \$and
}) are parameterized cells of variable
327 width. This so-called
{\it RTL Cells\/
} are the cells described in
{\tt simlib.v
}.
330 The upper-case cell types (such as
{\tt \$
\_AND\_}) are single-bit cells that are not
331 parameterized. This so-called
{\it Internal Logic Gates
} are the cells described
335 The consistency checker also checks the interfaces to the internal cell library.
336 If you want to use private cell types for your own purposes, use the
{\tt \$
\_\_}-prefix
337 to avoid name collisions.
340 \subsubsection{Connecting wires or constant drivers
}
342 \begin{frame
}[t, fragile
]{\subsubsecname}
343 Additional connections between wires or between wires and constants are modelled using
344 {\tt RTLIL::Module::connections
}:
347 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
348 typedef std::pair<RTLIL::SigSpec, RTLIL::SigSpec> RTLIL::SigSig;
350 struct RTLIL::Module
{
352 std::vector<RTLIL::SigSig> connections_;
358 {\tt RTLIL::SigSig::first
} is the driven signal and
{\tt RTLIL::SigSig::second
} is the driving signal.
359 Example usage (setting wire
{\tt foo
} to value
{\tt 42}):
360 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
361 module->connect(module->wire("\
\foo"),
362 RTLIL::SigSpec(
42, module->wire("\
\foo")->width));
366 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
368 \subsection{Creating modules from scratch
}
370 \begin{frame
}[t, fragile
]{\subsecname}
371 Let's create the following module using the RTLIL API:
374 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=Verilog
]
375 module absval(input signed
[3:
0] a, output
[3:
0] y);
376 assign y = a
[3] ? -a : a;
381 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
382 RTLIL::Module *module = new RTLIL::Module;
383 module->name = "\
\absval";
385 RTLIL::Wire *a = module->addWire("\
\a",
4);
386 a->port_input = true;
389 RTLIL::Wire *y = module->addWire("\
\y",
4);
390 y->port_output = true;
393 RTLIL::Wire *a_inv = module->addWire(NEW_ID,
4);
394 module->addNeg(NEW_ID, a, a_inv, true);
395 module->addMux(NEW_ID, a, a_inv, RTLIL::SigSpec(a,
1,
3), y);
397 module->fixup_ports();
401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
403 \subsection{Modifying modules
}
405 \begin{frame
}{\subsecname}
406 Most commands modify existing modules, not create new ones.
408 When modifying existing modules, stick to the following DOs and DON'Ts:
411 \item Do not remove wires. Simply disconnect them and let a successive
{\tt clean
} command worry about removing it.
413 \item Use
{\tt module->fixup
\_ports()
} after changing the
{\tt port
\_*
} properties of wires.
415 \item You can safely remove cells or change the
{\tt connections
} property of a cell, but be careful when
416 changing the size of the
{\tt SigSpec
} connected to a cell port.
418 \item Use the
{\tt SigMap
} helper class (see next slide) when you need a unique handle for each signal bit.
422 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
424 \subsection{Using the SigMap helper class
}
426 \begin{frame
}[t, fragile
]{\subsecname}
427 Consider the following module:
430 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=Verilog
]
431 module test(input a, output x, y);
436 In this case
{\tt a
},
{\tt x
}, and
{\tt y
} are all different names for the same signal. However:
439 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
440 RTLIL::SigSpec a(module->wire("\
\a")), x(module->wire("\
\x")),
441 y(module->wire("\
\y"));
442 log("
%d %d %d\n", a == x, x == y, y == a); // will print "0 0 0"
445 The
{\tt SigMap
} helper class can be used to map all such aliasing signals to a
446 unique signal from the group (usually the wire that is directly driven by a cell or port).
449 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
450 SigMap sigmap(module);
451 log("
%d %d %d\n", sigmap(a) == sigmap(x), sigmap(x) == sigmap(y),
452 sigmap(y) == sigmap(a)); // will print "
1 1 1"
456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
458 \subsection{Printing log messages
}
460 \begin{frame
}[t, fragile
]{\subsecname}
461 The
{\tt log()
} function is a
{\tt printf()
}-like function that can be used to create log messages.
464 Use
{\tt log
\_signal()
} to create a C-string for a SigSpec object
\footnote[frame
]{The pointer returned
465 by
{\tt log
\_signal()
} is automatically freed by the log framework at a later time.
}:
466 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
467 log("Mapped signal x:
%s\n", log_signal(sigmap(x)));
471 Use
{\tt log
\_id()
} to create a C-string for an
{\tt RTLIL::IdString
}:
472 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
473 log("Name of this module:
%s\n", log_id(module->name));
477 Use
{\tt log
\_header()
} and
{\tt log
\_push()
}/
{\tt log
\_pop()
} to structure log messages:
478 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
479 log_header(design, "Doing important stuff!
\n");
481 for (int i =
0; i <
10; i++)
482 log("Log message #
%d.\n", i);
487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
489 \subsection{Error handling
}
491 \begin{frame
}[t, fragile
]{\subsecname}
492 Use
{\tt log
\_error()
} to
report a non-recoverable error:
495 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
496 if (design->modules.count(module->name) !=
0)
497 log_error("A module with the name
%s already exists!\n",
498 RTLIL::id2cstr(module->name));
502 Use
{\tt log
\_cmd\_error()
} to
report a recoverable error:
503 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
504 if (design->selection_stack.back().empty())
505 log_cmd_error("This command can't operator on an empty selection!
\n");
509 Use
{\tt log
\_assert()
} and
{\tt log
\_abort()
} instead of
{\tt assert()
} and
{\tt abort()
}.
512 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
514 \subsection{Creating a command
}
516 \begin{frame
}[t, fragile
]{\subsecname}
517 Simply create a global instance of a class derived from
{\tt Pass
} to create
521 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
522 #include "kernel/yosys.h"
523 USING_YOSYS_NAMESPACE
525 struct MyPass : public Pass
{
526 MyPass() : Pass("my_cmd", "just a simple test")
{ }
527 virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
529 log("Arguments to my_cmd:
\n");
530 for (auto &arg : args)
531 log("
%s\n", arg.c_str());
533 log("Modules in current design:
\n");
534 for (auto mod : design->modules())
535 log("
%s (%d wires, %d cells)\n", log_id(mod),
536 GetSize(mod->wires()), GetSize(mod->cells()));
542 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
544 \subsection{Creating a plugin
}
546 \begin{frame
}[fragile
]{\subsecname}
547 Yosys can be extended by adding additional C++ code to the Yosys code base, or
548 by loading plugins into Yosys.
551 Use the following command to compile a Yosys plugin:
552 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont]
553 yosys-config --exec --cxx --cxxflags --ldflags \
554 -o my_cmd.so -shared my_cmd.cc --ldlibs
559 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont]
560 yosys-config --build my_cmd.so my_cmd.cc
564 Load the plugin using the yosys
{\tt -m
} option:
565 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont]
566 yosys -m ./my_cmd.so -p 'my_cmd foo bar'
570 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
574 \begin{frame
}{\subsecname}
576 \item Writing Yosys extensions is very straight-forward.
577 \item \dots and even simpler if you don't need RTLIL::Memory or RTLIL::Process objects.
580 \item Writing synthesis software? Consider learning the Yosys API and make your work
581 part of the Yosys framework.
593 \url{http://www.clifford.at/yosys/
}