3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-22 16:45:32 +00:00

Moved presentation_prog

This commit is contained in:
Krystine Sherwin 2023-08-03 09:20:29 +12:00
parent 045c04096e
commit cd6e63e1a9
No known key found for this signature in database
11 changed files with 257 additions and 621 deletions

View 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}

View file

@ -0,0 +1,2 @@
my_cmd.so
my_cmd.d

View 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

View file

@ -0,0 +1,3 @@
module absval_ref(input signed [3:0] a, output [3:0] y);
assign y = a[3] ? -a : a;
endmodule

View 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

View file

@ -0,0 +1,3 @@
module test(input a, output x, y);
assign x = a, y = a;
endmodule

View file

@ -3,4 +3,4 @@ Selections
See :doc:`/cmd/select`
Also :doc:`/cmd/show`
Also :doc:`/cmd/show` and :doc:`/cmd/dump`

View file

@ -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'

View file

@ -5,7 +5,7 @@ Internal formats
:maxdepth: 2
overview
rtlil
rtlil_rep
rtlil_text
cell_library