mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-22 16:45:32 +00:00
Moved presentation_prog
This commit is contained in:
parent
045c04096e
commit
cd6e63e1a9
11 changed files with 257 additions and 621 deletions
20
docs/images/simplified_rtlil.tex
Normal file
20
docs/images/simplified_rtlil.tex
Normal file
|
@ -0,0 +1,20 @@
|
|||
\documentclass[12pt,tikz]{standalone}
|
||||
\pdfinfoomitdate 1
|
||||
\pdfsuppressptexinfo 1
|
||||
\pdftrailerid{}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage{amsmath}
|
||||
\usepackage{pgfplots}
|
||||
\usepackage{tikz}
|
||||
\pagestyle{empty}
|
||||
|
||||
\begin{document}
|
||||
\begin{tikzpicture}[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{document}
|
2
docs/resources/PRESENTATION_Prog/.gitignore
vendored
Normal file
2
docs/resources/PRESENTATION_Prog/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
my_cmd.so
|
||||
my_cmd.d
|
21
docs/resources/PRESENTATION_Prog/Makefile
Normal file
21
docs/resources/PRESENTATION_Prog/Makefile
Normal file
|
@ -0,0 +1,21 @@
|
|||
|
||||
all: test0.log test1.log test2.log
|
||||
|
||||
CXXFLAGS=$(shell ../../yosys-config --cxxflags)
|
||||
DATDIR=$(shell ../../yosys-config --datdir)
|
||||
|
||||
my_cmd.so: my_cmd.cc
|
||||
../../yosys-config --exec --cxx $(subst $(DATDIR),../../share,$(CXXFLAGS)) --ldflags -o my_cmd.so -shared my_cmd.cc --ldlibs
|
||||
|
||||
test0.log: my_cmd.so
|
||||
../../yosys -Ql 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 -Ql 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 -Ql test2.log_new -m ./my_cmd.so -p 'hierarchy -top test; test2' sigmap_test.v
|
||||
mv test2.log_new test2.log
|
||||
|
3
docs/resources/PRESENTATION_Prog/absval_ref.v
Normal file
3
docs/resources/PRESENTATION_Prog/absval_ref.v
Normal file
|
@ -0,0 +1,3 @@
|
|||
module absval_ref(input signed [3:0] a, output [3:0] y);
|
||||
assign y = a[3] ? -a : a;
|
||||
endmodule
|
76
docs/resources/PRESENTATION_Prog/my_cmd.cc
Normal file
76
docs/resources/PRESENTATION_Prog/my_cmd.cc
Normal file
|
@ -0,0 +1,76 @@
|
|||
#include "kernel/yosys.h"
|
||||
#include "kernel/sigtools.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
struct MyPass : public Pass {
|
||||
MyPass() : Pass("my_cmd", "just a simple test") { }
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
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", log_id(mod),
|
||||
GetSize(mod->wires()), GetSize(mod->cells()));
|
||||
}
|
||||
} MyPass;
|
||||
|
||||
|
||||
struct Test1Pass : public Pass {
|
||||
Test1Pass() : Pass("test1", "creating the absval module") { }
|
||||
void execute(std::vector<std::string>, RTLIL::Design *design) override
|
||||
{
|
||||
if (design->has("\\absval") != 0)
|
||||
log_error("A module with the name absval already exists!\n");
|
||||
|
||||
RTLIL::Module *module = design->addModule("\\absval");
|
||||
log("Name of this module: %s\n", log_id(module));
|
||||
|
||||
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, 3), y);
|
||||
|
||||
module->fixup_ports();
|
||||
}
|
||||
} Test1Pass;
|
||||
|
||||
|
||||
struct Test2Pass : public Pass {
|
||||
Test2Pass() : Pass("test2", "demonstrating sigmap on test module") { }
|
||||
void execute(std::vector<std::string>, RTLIL::Design *design) override
|
||||
{
|
||||
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->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"
|
||||
|
||||
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(design, "Doing important stuff!\n");
|
||||
log_push();
|
||||
for (int i = 0; i < 10; i++)
|
||||
log("Log message #%d.\n", i);
|
||||
log_pop();
|
||||
}
|
||||
} Test2Pass;
|
||||
|
||||
PRIVATE_NAMESPACE_END
|
3
docs/resources/PRESENTATION_Prog/sigmap_test.v
Normal file
3
docs/resources/PRESENTATION_Prog/sigmap_test.v
Normal file
|
@ -0,0 +1,3 @@
|
|||
module test(input a, output x, y);
|
||||
assign x = a, y = a;
|
||||
endmodule
|
|
@ -3,4 +3,4 @@ Selections
|
|||
|
||||
See :doc:`/cmd/select`
|
||||
|
||||
Also :doc:`/cmd/show`
|
||||
Also :doc:`/cmd/show` and :doc:`/cmd/dump`
|
||||
|
|
|
@ -5,44 +5,256 @@ Writing extensions
|
|||
|
||||
.. TODO: copypaste
|
||||
|
||||
This chapter contains some bits and pieces of information about
|
||||
programming yosys extensions. Also consult the section on programming in
|
||||
the "Yosys Presentation" (can be downloaded from the Yosys website as
|
||||
PDF) and don't be afraid to ask questions on the YosysHQ Slack.
|
||||
This chapter contains some bits and pieces of information about programming
|
||||
yosys extensions. Don't be afraid to ask questions on the YosysHQ Slack.
|
||||
|
||||
Guidelines
|
||||
----------
|
||||
|
||||
The guidelines directory contains notes on various aspects of Yosys
|
||||
development. The files GettingStarted and CodingStyle may be of
|
||||
particular interest, and are reproduced here.
|
||||
The guidelines directory contains notes on various aspects of Yosys development.
|
||||
The files GettingStarted and CodingStyle may be of particular interest, and are
|
||||
reproduced here.
|
||||
|
||||
.. literalinclude:: ../temp/GettingStarted
|
||||
:language: none
|
||||
:caption: guidelines/GettingStarted
|
||||
:language: none
|
||||
:caption: guidelines/GettingStarted
|
||||
|
||||
.. literalinclude:: ../temp/CodingStyle
|
||||
:language: none
|
||||
:caption: guidelines/CodingStyle
|
||||
:language: none
|
||||
:caption: guidelines/CodingStyle
|
||||
|
||||
The "stubsnets" example module
|
||||
------------------------------
|
||||
|
||||
The following is the complete code of the "stubsnets" example module. It
|
||||
is included in the Yosys source distribution as
|
||||
docs/source/CHAPTER_Prog/stubnets.cc.
|
||||
The following is the complete code of the "stubsnets" example module. It is
|
||||
included in the Yosys source distribution as
|
||||
``docs/source/CHAPTER_Prog/stubnets.cc``.
|
||||
|
||||
.. literalinclude:: ../CHAPTER_Prog/stubnets.cc
|
||||
:language: c++
|
||||
:linenos:
|
||||
:caption: docs/source/CHAPTER_Prog/stubnets.cc
|
||||
:language: c++
|
||||
:linenos:
|
||||
:caption: docs/source/CHAPTER_Prog/stubnets.cc
|
||||
|
||||
.. literalinclude:: ../CHAPTER_Prog/Makefile
|
||||
:language: makefile
|
||||
:linenos:
|
||||
:caption: docs/source/CHAPTER_Prog/Makefile
|
||||
:language: makefile
|
||||
:linenos:
|
||||
:caption: docs/source/CHAPTER_Prog/Makefile
|
||||
|
||||
.. literalinclude:: ../CHAPTER_Prog/test.v
|
||||
:language: verilog
|
||||
:linenos:
|
||||
:caption: docs/source/CHAPTER_Prog/test.v
|
||||
:language: verilog
|
||||
:linenos:
|
||||
:caption: docs/source/CHAPTER_Prog/test.v
|
||||
|
||||
Quick guide
|
||||
-----------
|
||||
|
||||
See also: ``docs/resources/PRESENTATION_Prog/*``.
|
||||
|
||||
Program components and data formats
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
See :doc:`/yosys_internals/formats/rtlil_rep` document for more information
|
||||
about the internal data storage format used in Yosys and the classes that it
|
||||
provides.
|
||||
|
||||
This document will focus on the much simpler version of RTLIL left after the
|
||||
commands ``proc`` and ``memory`` (or ``memory -nomap``):
|
||||
|
||||
.. figure:: ../../images/simplified_rtlil.*
|
||||
:class: width-helper
|
||||
:name: fig:Simplified_RTLIL
|
||||
|
||||
Simplified RTLIL entity-relationship diagram without memories and processes
|
||||
|
||||
It is possible to only work on this simpler version:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
for (RTLIL::Module *module : design->selected_modules() {
|
||||
if (module->has_memories_warn() || module->has_processes_warn())
|
||||
continue;
|
||||
....
|
||||
}
|
||||
|
||||
When trying to understand what a command does, creating a small test case to
|
||||
look at the output of ``dump`` and ``show`` before and after the command has
|
||||
been executed can be helpful. The :doc:`/using_yosys/selections` document has
|
||||
more information on using these commands.
|
||||
|
||||
.. TODO: copypaste
|
||||
|
||||
Creating modules from scratch
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Let's create the following module using the RTLIL API:
|
||||
|
||||
.. code:: Verilog
|
||||
|
||||
module absval(input signed [3:0] a, output [3:0] y);
|
||||
assign y = a[3] ? -a : a;
|
||||
endmodule
|
||||
|
||||
.. code:: 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();
|
||||
|
||||
Modifying modules
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Most commands modify existing modules, not create new ones.
|
||||
|
||||
When modifying existing modules, stick to the following DOs and DON'Ts:
|
||||
|
||||
- Do not remove wires. Simply disconnect them and let a successive ``clean``
|
||||
command worry about removing it.
|
||||
- Use ``module->fixup_ports()`` after changing the ``port_*`` properties of
|
||||
wires.
|
||||
- You can safely remove cells or change the ``connections`` property of a cell,
|
||||
but be careful when changing the size of the ``SigSpec`` connected to a cell
|
||||
port.
|
||||
|
||||
- Use the ``SigMap`` helper class (see next slide) when you need a unique handle for each signal bit.
|
||||
|
||||
Using the SigMap helper class
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Consider the following module:
|
||||
|
||||
.. code:: Verilog
|
||||
|
||||
module test(input a, output x, y);
|
||||
assign x = a, y = a;
|
||||
endmodule
|
||||
|
||||
In this case ``a``, ``x``, and ``y`` are all different names for the same signal. However:
|
||||
|
||||
.. code:: 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"
|
||||
|
||||
The ``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).
|
||||
|
||||
.. code:: 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"
|
||||
|
||||
Printing log messages
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``log()`` function is a ``printf()``-like function that can be used to create log messages.
|
||||
|
||||
Use ``log_signal()`` to create a C-string for a SigSpec object:
|
||||
|
||||
.. code:: C++
|
||||
|
||||
log("Mapped signal x: %s\n", log_signal(sigmap(x)));
|
||||
|
||||
The pointer returned by ``log_signal()`` is automatically freed by the log
|
||||
framework at a later time.
|
||||
|
||||
Use ``log_id()`` to create a C-string for an ``RTLIL::IdString``:
|
||||
|
||||
.. code:: C++
|
||||
|
||||
log("Name of this module: %s\n", log_id(module->name));
|
||||
|
||||
Use ``log_header()`` and ``log_push()``/``log_pop()`` to structure log messages:
|
||||
|
||||
.. code:: 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();
|
||||
|
||||
Error handling
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Use ``log_error()`` to report a non-recoverable error:
|
||||
|
||||
.. code:: C++
|
||||
|
||||
if (design->modules.count(module->name) != 0)
|
||||
log_error("A module with the name %s already exists!\n",
|
||||
RTLIL::id2cstr(module->name));
|
||||
|
||||
Use ``log_cmd_error()`` to report a recoverable error:
|
||||
|
||||
.. code:: C++
|
||||
|
||||
if (design->selection_stack.back().empty())
|
||||
log_cmd_error("This command can't operator on an empty selection!\n");
|
||||
|
||||
Use ``log_assert()`` and ``log_abort()`` instead of ``assert()`` and ``abort()``.
|
||||
|
||||
Creating a command
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Simply create a global instance of a class derived from ``Pass`` to create
|
||||
a new yosys command:
|
||||
|
||||
.. code:: 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;
|
||||
|
||||
Creating a plugin
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Yosys can be extended by adding additional C++ code to the Yosys code base, or
|
||||
by loading plugins into Yosys.
|
||||
|
||||
Use the following command to compile a Yosys plugin:
|
||||
|
||||
.. code::
|
||||
|
||||
yosys-config --exec --cxx --cxxflags --ldflags \
|
||||
-o my_cmd.so -shared my_cmd.cc --ldlibs
|
||||
|
||||
Or shorter:
|
||||
|
||||
.. code::
|
||||
|
||||
yosys-config --build my_cmd.so my_cmd.cc
|
||||
|
||||
Load the plugin using the yosys ``-m`` option:
|
||||
|
||||
.. code::
|
||||
|
||||
yosys -m ./my_cmd.so -p 'my_cmd foo bar'
|
||||
|
|
|
@ -5,7 +5,7 @@ Internal formats
|
|||
:maxdepth: 2
|
||||
|
||||
overview
|
||||
rtlil
|
||||
rtlil_rep
|
||||
rtlil_text
|
||||
cell_library
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue