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
] {ILANG 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 ILANG format. This is
109 a text representation of RTLIL.
112 \item The
{\tt show
} command visualizes how the components in the design are connected.
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
121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123 \subsection{The RTLIL Data Structures
}
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<>
}).
132 \item Most operations are performed directly on the RTLIL structs without
133 setter or getter functions.
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.
140 \item Most RTLIL structs have helper methods that perform the most common operations.
144 See
{\tt yosys/kernel/rtlil.h
} for details.
147 \subsubsection{RTLIL::IdString
}
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
155 The first character of a
{\tt RTLIL::IdString
} specifies if the name is
{\it public\/
} or
{\it private\/
}:
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.
163 \item {\tt RTLIL::IdString
[0] == '\$'
}: \\
164 This is a private name. It was assigned by Yosys.
168 Use the
{\tt NEW
\_ID} macro to create a new unique private name.
171 \subsubsection{RTLIL::Design and RTLIL::Module
}
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.
178 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
179 struct RTLIL::Design
{
180 dict<RTLIL::IdString, RTLIL::Module*> modules_;
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_;
193 (Use the various accessor functions instead of directly working with the
{\tt *
\_} members.)
196 \subsubsection{The RTLIL::Wire Structure
}
198 \begin{frame
}[t, fragile
]{\subsubsecname}
199 Each wire in the design is represented by a
{\tt RTLIL::Wire
} struct:
202 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
204 RTLIL::IdString name;
205 int width, start_offset, port_id;
206 bool port_input, port_output;
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. \\
221 \subsubsection{RTLIL::State and RTLIL::Const
}
223 \begin{frame
}[t, fragile
]{\subsubsecname}
224 The
{\tt RTLIL::State
} enum represents a simple
1-bit logic level:
227 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
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)
239 The
{\tt RTLIL::Const
} struct represents a constant multi-bit value:
242 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
243 struct RTLIL::Const
{
244 std::vector<RTLIL::State> bits;
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.
254 \subsubsection{The RTLIL::SigSpec Structure
}
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
261 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
266 RTLIL::State data; // used if wire == NULL
267 int offset; // used if wire != NULL
272 struct RTLIL::SigSpec
{
273 std::vector<RTLIL::SigBit> bits_; // LSB at index
0
279 The
{\tt RTLIL::SigSpec
} struct has a ton of additional helper methods to compare, analyze, and
280 manipulate instances of
{\tt RTLIL::SigSpec
}.
283 \subsubsection{The RTLIL::Cell Structure
}
285 \begin{frame
}[t, fragile
]{\subsubsecname (
1/
2)
}
286 The
{\tt RTLIL::Cell
} struct represents an instance of a module or library cell.
289 The ports of the cell
290 are associated with
{\tt RTLIL::SigSpec
} instances and the parameters are associated with
{\tt RTLIL::Const
}
294 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
296 RTLIL::IdString name, type;
297 dict<RTLIL::IdString, RTLIL::SigSpec> connections_;
298 dict<RTLIL::IdString, RTLIL::Const> parameters;
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:
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_
319 \begin{frame
}[t, fragile
]{\subsubsecname (
2/
2)
}
320 Simulation models (i.e.
{\it documentation\/
} :-) for the internal cell library:
323 \hskip2em {\tt yosys/techlibs/common/simlib.v
} and \\
324 \hskip2em {\tt yosys/techlibs/common/simcells.v
}
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
}.
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
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.
341 \subsubsection{Connecting wires or constant drivers
}
343 \begin{frame
}[t, fragile
]{\subsubsecname}
344 Additional connections between wires or between wires and constants are modelled using
345 {\tt RTLIL::Module::connections
}:
348 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
349 typedef std::pair<RTLIL::SigSpec, RTLIL::SigSpec> RTLIL::SigSig;
351 struct RTLIL::Module
{
353 std::vector<RTLIL::SigSig> connections_;
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));
367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
369 \subsection{Creating modules from scratch
}
371 \begin{frame
}[t, fragile
]{\subsecname}
372 Let's create the following module using the RTLIL API:
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;
382 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
383 RTLIL::Module *module = new RTLIL::Module;
384 module->name = "\
\absval";
386 RTLIL::Wire *a = module->addWire("\
\a",
4);
387 a->port_input = true;
390 RTLIL::Wire *y = module->addWire("\
\y",
4);
391 y->port_output = true;
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);
398 module->fixup_ports();
402 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
404 \subsection{Modifying modules
}
406 \begin{frame
}{\subsecname}
407 Most commands modify existing modules, not create new ones.
409 When modifying existing modules, stick to the following DOs and DON'Ts:
412 \item Do not remove wires. Simply disconnect them and let a successive
{\tt clean
} command worry about removing it.
414 \item Use
{\tt module->fixup
\_ports()
} after changing the
{\tt port
\_*
} properties of wires.
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.
419 \item Use the
{\tt SigMap
} helper class (see next slide) when you need a unique handle for each signal bit.
423 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
425 \subsection{Using the SigMap helper class
}
427 \begin{frame
}[t, fragile
]{\subsecname}
428 Consider the following module:
431 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=Verilog
]
432 module test(input a, output x, y);
437 In this case
{\tt a
},
{\tt x
}, and
{\tt y
} are all different names for the same signal. However:
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"
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).
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"
457 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
459 \subsection{Printing log messages
}
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.
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)));
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));
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");
482 for (int i =
0; i <
10; i++)
483 log("Log message #
%d.\n", i);
488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
490 \subsection{Error handling
}
492 \begin{frame
}[t, fragile
]{\subsecname}
493 Use
{\tt log
\_error()
} to
report a non-recoverable error:
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));
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");
510 Use
{\tt log
\_assert()
} and
{\tt log
\_abort()
} instead of
{\tt assert()
} and
{\tt abort()
}.
513 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
515 \subsection{Creating a command
}
517 \begin{frame
}[t, fragile
]{\subsecname}
518 Simply create a global instance of a class derived from
{\tt Pass
} to create
522 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont, language=C++
]
523 #include "kernel/yosys.h"
524 USING_YOSYS_NAMESPACE
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)
530 log("Arguments to my_cmd:
\n");
531 for (auto &arg : args)
532 log("
%s\n", arg.c_str());
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()));
543 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
545 \subsection{Creating a plugin
}
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.
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
560 \begin{lstlisting
}[xleftmargin=
1cm, basicstyle=
\ttfamily\fontsize{8pt
}{10pt
}\selectfont]
561 yosys-config --build my_cmd.so my_cmd.cc
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'
571 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
575 \begin{frame
}{\subsecname}
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.
581 \item Writing synthesis software? Consider learning the Yosys API and make your work
582 part of the Yosys framework.
594 \url{http://www.clifford.at/yosys/
}