diff options
author | Clifford Wolf <clifford@clifford.at> | 2014-06-22 12:50:29 +0200 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2014-06-22 12:50:29 +0200 |
commit | a7aea179599045feafcaf26f5ed334a7318a69b4 (patch) | |
tree | 2033072706700930a5150c04814851ded086ecc0 /manual | |
parent | 3345fa0bab5d343a9cd5a9dde6486e4e876fe8da (diff) | |
download | yosys-a7aea179599045feafcaf26f5ed334a7318a69b4.tar.gz yosys-a7aea179599045feafcaf26f5ed334a7318a69b4.tar.bz2 yosys-a7aea179599045feafcaf26f5ed334a7318a69b4.zip |
Progress in presentation
Diffstat (limited to 'manual')
-rw-r--r-- | manual/PRESENTATION_Prog.tex | 440 | ||||
-rw-r--r-- | manual/PRESENTATION_Prog/.gitignore | 1 | ||||
-rw-r--r-- | manual/PRESENTATION_Prog/Makefile | 18 | ||||
-rw-r--r-- | manual/PRESENTATION_Prog/absval_ref.v | 3 | ||||
-rw-r--r-- | manual/PRESENTATION_Prog/my_cmd.cc | 78 | ||||
-rw-r--r-- | manual/PRESENTATION_Prog/sigmap_test.v | 3 | ||||
-rwxr-xr-x | manual/presentation.sh | 2 |
7 files changed, 503 insertions, 42 deletions
diff --git a/manual/PRESENTATION_Prog.tex b/manual/PRESENTATION_Prog.tex index 45f0cb0c6..1e7f697b1 100644 --- a/manual/PRESENTATION_Prog.tex +++ b/manual/PRESENTATION_Prog.tex @@ -7,14 +7,6 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\subsection{Why writing Yosys extensions?} - -\begin{frame}{\subsecname} -TBD -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - \subsection{Program Components and Data Formats} \begin{frame}{\subsecname} @@ -109,55 +101,293 @@ For simplicity we only discuss this version of RTLIL in this presentation. \subsection{Using dump and show commands} \begin{frame}{\subsecname} -TBD +\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::Const Structure} +\subsection{The RTLIL Data Structures} \begin{frame}{\subsecname} -TBD +The RTLIL data structures are simple structs utilizing C++ {\tt std::} +containers. + +\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} -\subsection{The RTLIL::SigSpec Structure} +\begin{frame}{\subsubsecname}{} +{\tt RTLIL::IdString} is a simple wrapper for {\tt std::string}. It is used for names of RTLIL objects. -\begin{frame}{\subsecname} -TBD +\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} -\subsection{RTLIL::Design, RTLIL::Module} +\begin{frame}[t, fragile]{\subsubsecname} +The {\tt RTLIL::Design} and {\tt RTLIL::Module} structs are the top-level RTLIL +data structures. -\begin{frame}{\subsecname} -TBD +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 { + std::map<RTLIL::IdString, RTLIL::Module*> modules; + ... +}; + +struct RTLIL::Module { + RTLIL::IdString name; + std::map<RTLIL::IdString, RTLIL::Wire*> wires; + std::map<RTLIL::IdString, RTLIL::Cell*> cells; + std::vector<RTLIL::SigSig> connections; + ... +}; +\end{lstlisting} \end{frame} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsubsection{The RTLIL::Wire Structure} -\subsection{RTLIL::Wire and connections} +\begin{frame}[t, fragile]{\subsubsecname} +Each wire in the design is represented by a {\tt RTLIL::Wire} struct: -\begin{frame}{\subsecname} -TBD +\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} -\subsection{RTLIL::Cell} +\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} -\begin{frame}{\subsecname} -TBD +\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. Consecutive bits from a wire or consecutive constant bits are consolidated into +a {\tt RTLIL::SigChunk}: + +\bigskip +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +struct RTLIL::SigChunk { + RTLIL::Wire *wire; + RTLIL::Const data; // only used if wire == NULL, LSB at index 0 + int width, offset; + ... +}; + +struct RTLIL::SigSpec { + std::vector<RTLIL::SigChunk> chunks; // LSB at index 0 + int width; + ... +}; +\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} strcut 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; + std::map<RTLIL::IdString, RTLIL::SigSpec> connections; + std::map<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 $bu0 $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 $safe_pmux $lut $assert $sr $dff +$dffsr $adff $dlatch $dlatchsr $memrd $memwr $mem $fsm $_INV_ $_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\_}) 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->connections.push_back(RTLIL::SigSig(module->wires.at("\\foo"), + RTLIL::SigSpec(42, module->wires.at("\\foo")->width))); +\end{lstlisting} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Creating modules from scratch} -\begin{frame}{\subsecname} -TBD +\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->new_wire(4, "\\a"); +a->port_input = true; +a->port_id = 1; + +RTLIL::Wire *y = module->new_wire(4, "\\y"); +y->port_output = true; +y->port_id = 2; + +RTLIL::Wire *a_inv = module->new_wire(4, NEW_ID); +module->addNeg(NEW_ID, a, a_inv, true); +module->addMux(NEW_ID, a, a_inv, RTLIL::SigSpec(a, 1, 3), y); +\end{lstlisting} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -165,39 +395,163 @@ TBD \subsection{Modifying modules} \begin{frame}{\subsecname} -TBD +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 connetions} 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}{\subsecname} -TBD +\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->wires.at("\\a")), x(module->wires.at("\\x")), + y(module->wires.at("\\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}{\subsecname} -TBD +\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 RTLIL::id2cstr()} 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", RTLIL::id2cstr(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("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}{\subsecname} -TBD +\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/rtlil.h" +#include "kernel/register.h" +#include "kernel/log.h" + +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 (%zd wires, %zd cells)\n", RTLIL::id2cstr(mod.first), + mod.second->wires.size(), mod.second->cells.size()); + } +} MyPass; +\end{lstlisting} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Creating a plugin} -\begin{frame}{\subsecname} -TBD +\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 +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} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -206,10 +560,12 @@ TBD \begin{frame}{\subsecname} \begin{itemize} -\item TBD -\item TBD -\item TBD -\item TBD +\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 stuff +part of the Yosys framework. \end{itemize} \bigskip diff --git a/manual/PRESENTATION_Prog/.gitignore b/manual/PRESENTATION_Prog/.gitignore new file mode 100644 index 000000000..7fd560762 --- /dev/null +++ b/manual/PRESENTATION_Prog/.gitignore @@ -0,0 +1 @@ +my_cmd.so diff --git a/manual/PRESENTATION_Prog/Makefile b/manual/PRESENTATION_Prog/Makefile new file mode 100644 index 000000000..8da6bcd63 --- /dev/null +++ b/manual/PRESENTATION_Prog/Makefile @@ -0,0 +1,18 @@ + +all: test0.log test1.log test2.log + +my_cmd.so: my_cmd.cc + ../../yosys-config --exec --cxx --cxxflags --ldflags -o my_cmd.so -shared my_cmd.cc --ldlibs + +test0.log: my_cmd.so + ../../yosys -l test0.log_new -m ./my_cmd.so -p 'my_cmd foo bar' absval_ref.v + mv test0.log_new test0.log + +test1.log: my_cmd.so + ../../yosys -l test1.log_new -m ./my_cmd.so -p 'clean; test1; dump' absval_ref.v + mv test1.log_new test1.log + +test2.log: my_cmd.so + ../../yosys -l test2.log_new -m ./my_cmd.so -p 'test2' sigmap_test.v + mv test2.log_new test2.log + diff --git a/manual/PRESENTATION_Prog/absval_ref.v b/manual/PRESENTATION_Prog/absval_ref.v new file mode 100644 index 000000000..ca0a115a0 --- /dev/null +++ b/manual/PRESENTATION_Prog/absval_ref.v @@ -0,0 +1,3 @@ +module absval_ref(input signed [3:0] a, output [3:0] y); + assign y = a[3] ? -a : a; +endmodule diff --git a/manual/PRESENTATION_Prog/my_cmd.cc b/manual/PRESENTATION_Prog/my_cmd.cc new file mode 100644 index 000000000..cf8a4add8 --- /dev/null +++ b/manual/PRESENTATION_Prog/my_cmd.cc @@ -0,0 +1,78 @@ +#include "kernel/rtlil.h" +#include "kernel/register.h" +#include "kernel/log.h" +#include "kernel/sigtools.h" + +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 (%zd wires, %zd cells)\n", RTLIL::id2cstr(mod.first), + mod.second->wires.size(), mod.second->cells.size()); + } +} MyPass; + + +struct Test1Pass : public Pass { + Test1Pass() : Pass("test1", "creating the absval module") { } + virtual void execute(std::vector<std::string>, RTLIL::Design *design) + { + RTLIL::Module *module = new RTLIL::Module; + module->name = "\\absval"; + + RTLIL::Wire *a = module->new_wire(4, "\\a"); + a->port_input = true; + a->port_id = 1; + + RTLIL::Wire *y = module->new_wire(4, "\\y"); + y->port_output = true; + y->port_id = 2; + + RTLIL::Wire *a_inv = module->new_wire(4, NEW_ID); + module->addNeg(NEW_ID, a, a_inv, true); + module->addMux(NEW_ID, a, a_inv, RTLIL::SigSpec(a, 1, 3), y); + + log("Name of this module: %s\n", RTLIL::id2cstr(module->name)); + + if (design->modules.count(module->name) != 0) + log_error("A module with the name %s already exists!\n", + RTLIL::id2cstr(module->name)); + + design->modules[module->name] = module; + } +} Test1Pass; + + +struct Test2Pass : public Pass { + Test2Pass() : Pass("test2", "demonstrating sigmap on test module") { } + virtual void execute(std::vector<std::string>, RTLIL::Design *design) + { + if (design->selection_stack.back().empty()) + log_cmd_error("This command can't operator on an empty selection!\n"); + + RTLIL::Module *module = design->modules.at("\\test"); + + RTLIL::SigSpec a(module->wires.at("\\a")), x(module->wires.at("\\x")), + y(module->wires.at("\\y")); + log("%d %d %d\n", a == x, x == y, y == a); // will print "0 0 0" + + 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" + + log("Mapped signal x: %s\n", log_signal(sigmap(x))); + + log_header("Doing important stuff!\n"); + log_push(); + for (int i = 0; i < 10; i++) + log("Log message #%d.\n", i); + log_pop(); + } +} Test2Pass; + diff --git a/manual/PRESENTATION_Prog/sigmap_test.v b/manual/PRESENTATION_Prog/sigmap_test.v new file mode 100644 index 000000000..18dcf5eb7 --- /dev/null +++ b/manual/PRESENTATION_Prog/sigmap_test.v @@ -0,0 +1,3 @@ +module test(input a, output x, y); +assign x = a, y = a; +endmodule diff --git a/manual/presentation.sh b/manual/presentation.sh index 6771ba7c9..980e17723 100755 --- a/manual/presentation.sh +++ b/manual/presentation.sh @@ -29,6 +29,8 @@ if ! $fast_mode; then make -C PRESENTATION_Intro make -C PRESENTATION_ExSyn make -C PRESENTATION_ExAdv + make -C PRESENTATION_ExOth + make -C PRESENTATION_Prog fi set -ex |