File: GettingStarted

package info (click to toggle)
yosys 0.52-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 69,796 kB
  • sloc: ansic: 696,955; cpp: 239,736; python: 14,617; yacc: 3,529; sh: 2,175; makefile: 1,945; lex: 697; perl: 445; javascript: 323; tcl: 162; vhdl: 115
file content (207 lines) | stat: -rw-r--r-- 7,199 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
Getting Started
===============


Outline of a Yosys command
--------------------------

Here is a the C++ code for a "hello_world" Yosys command (hello.cc):

	#include "kernel/yosys.h"

	USING_YOSYS_NAMESPACE
	PRIVATE_NAMESPACE_BEGIN

	struct HelloWorldPass : public Pass {
		HelloWorldPass() : Pass("hello_world") { }
		void execute(vector<string>, Design*) override {
			log("Hello World!\n");
		}
	} HelloWorldPass;

	PRIVATE_NAMESPACE_END

This can be built into a Yosys module using the following command:

	yosys-config --exec --cxx --cxxflags --ldflags -o hello.so -shared hello.cc --ldlibs

Or short:

	yosys-config --build hello.so hello.cc

And then executed using the following command:

	yosys -m hello.so -p hello_world


Yosys Data Structures
---------------------

  1. Container classes based on hashing

Yosys heavily relies on custom container data structures such as dict or pool
defined in kernel/hashlib.h.
dict<K, T> is essentially a replacement for std::unordered_map<K, T>
and pool<T> is a replacement for std::unordered_set<T>. Please refer to
docs/source/yosys_internals/hashing.rst for more information on those.

Otherwise, Yosys makes use of the following:

  2. Standard STL data types

In Yosys we use std::vector<T> and std::string whenever applicable. When
dict<K, T> and pool<T> are not suitable then std::map<K, T> and std::set<T>
are used instead.

The types std::vector<T> and std::string are also available as vector<T>
and string in the Yosys namespace.

  3. RTLIL objects

The current design (essentially a collection of modules, each defined by a
netlist) is stored in memory using RTLIL object (declared in kernel/rtlil.h,
automatically included by kernel/yosys.h). You should glance over at least
the declarations for the following types in kernel/rtlil.h:

	RTLIL::IdString
		This is a handle for an identifier (e.g. cell or wire name).
		It feels a lot like a std::string, but is only a single int
		in size. (The actual string is stored in a global lookup
		table.)

	RTLIL::SigBit
		A single signal bit. I.e. either a constant state (0, 1,
		x, z) or a single bit from a wire.

	RTLIL::SigSpec
		Essentially a vector of SigBits.

	RTLIL::Wire
	RTLIL::Cell
		The building blocks of the netlist in a module.

	RTLIL::Module
	RTLIL::Design
		The module is a container with connected cells and wires
		in it. The design is a container with modules in it.

All this types are also available without the RTLIL:: prefix in the Yosys
namespace.

  4. SigMap and other Helper Classes

There are a couple of additional helper classes that are in wide use
in Yosys. Most importantly there is SigMap (declared in kernel/sigtools.h).

When a design has many wires in it that are connected to each other, then a
single signal bit can have multiple valid names. The SigMap object can be used
to map SigSpecs or SigBits to unique SigSpecs and SigBits that consistently
only use one wire from such a group of connected wires. For example:

	SigBit a = module->addWire(NEW_ID);
	SigBit b = module->addWire(NEW_ID);
	module->connect(a, b);

	log("%d\n", a == b); // will print 0

	SigMap sigmap(module);
	log("%d\n", sigmap(a) == sigmap(b)); // will print 1


Using the RTLIL Netlist Format
------------------------------

In the RTLIL netlist format the cell ports contain SigSpecs that point to the
Wires. There are no references in the other direction. This has two direct
consequences:

(1) It is very easy to go from cells to wires but hard to go in the other way.

(2) There is no danger in removing cells from the netlists, but removing wires
can break the netlist format when there are still references to the wire
somewhere in the netlist.

The solution to (1) is easy: Create custom indexes that allow you to make fast
lookups for the wire-to-cell direction. You can either use existing generic
index structures to do that (such as the ModIndex class) or write your own
index. For many application it is simplest to construct a custom index. For
example:

	SigMap sigmap(module);
	dict<SigBit, Cell*> sigbit_to_driver_index;

	for (auto cell : module->cells())
		for (auto &conn : cell->connections())
			if (cell->output(conn.first))
				for (auto bit : sigmap(conn.second))
					sigbit_to_driver_index[bit] = cell;

Regarding (2): There is a general theme in Yosys that you don't remove wires
from the design. You can rename them, unconnect them, but you do not actually remove
the Wire object from the module. Instead you let the "clean" command take care
of the dangling wires. On the other hand it is safe to remove cells (as long as
you make sure this does not invalidate a custom index you are using in your code).


Example Code
------------

The following yosys commands are a good starting point if you are looking for examples
of how to use the Yosys API:

	docs/source/code_examples/stubnets/stubnets.cc
	docs/resources/PRESENTATION_Prog/my_cmd.cc


Script Passes
-------------

The ScriptPass base class can be used to implement passes that just call other passes,
like a script. Examples for such passes are:

	techlibs/common/prep.cc
	techlibs/common/synth.cc

In some cases it is easier to implement such a pass as regular pass, for example when
ScriptPass doesn't provide the type of flow control desired. (But many of the
script passes in Yosys that don't use ScriptPass simply predate the ScriptPass base
class.) Examples for such passes are:

	passes/opt/opt.cc
	passes/proc/proc.cc

Whether they use the ScriptPass base-class or not, a pass should always either
call other passes without doing any non-trivial work itself, or should implement
a non-trivial algorithm but not call any other passes. The reason for this is that
this helps containing complexity in individual passes and simplifies debugging the
entire system.

Exceptions to this rule should be rare and limited to cases where calling other
passes is optional and only happens when requested by the user (such as for
example `techmap -autoproc`), or where it is about commands that are "top-level
commands" in their own right, not components to be used in regular synthesis
flows (such as the `bugpoint` command).

A pass that would "naturally" call other passes and also do some work itself
should be re-written in one of two ways:

1) It could be re-written as script pass with the parts that are not calls
to other passes factored out into individual new passes. Usually in those
cases the new sub passes share the same prefix as the top-level script pass.

2) It could be re-written so that it already expects the design in a certain
state, expecting the calling script to set up this state before calling the
pass in questions.

Many back-ends are examples for the 2nd approach. For example, `write_aiger`
does not convert the design into AIG representation, but expects the design
to be already in this form, and prints an `Unsupported cell type` error
message otherwise.


Notes on the existing codebase
------------------------------

For historical reasons not all parts of Yosys adhere to the current coding
style. When adding code to existing parts of the system, adhere to this guide
for the new code instead of trying to mimic the style of the surrounding code.