Merge pull request #3310 from robinsonb5-PRs/master
[yosys.git] / guidelines / GettingStarted
1 Getting Started
2 ===============
3
4
5 Outline of a Yosys command
6 --------------------------
7
8 Here is a the C++ code for a "hello_world" Yosys command (hello.cc):
9
10 #include "kernel/yosys.h"
11
12 USING_YOSYS_NAMESPACE
13 PRIVATE_NAMESPACE_BEGIN
14
15 struct HelloWorldPass : public Pass {
16 HelloWorldPass() : Pass("hello_world") { }
17 void execute(vector<string>, Design*) override {
18 log("Hello World!\n");
19 }
20 } HelloWorldPass;
21
22 PRIVATE_NAMESPACE_END
23
24 This can be built into a Yosys module using the following command:
25
26 yosys-config --exec --cxx --cxxflags --ldflags -o hello.so -shared hello.cc --ldlibs
27
28 Or short:
29
30 yosys-config --build hello.so hello.cc
31
32 And then executed using the following command:
33
34 yosys -m hello.so -p hello_world
35
36
37 Yosys Data Structures
38 ---------------------
39
40 Here is a short list of data structures that you should make yourself familiar
41 with before you write C++ code for Yosys. The following data structures are all
42 defined when "kernel/yosys.h" is included and USING_YOSYS_NAMESPACE is used.
43
44 1. Yosys Container Classes
45
46 Yosys uses dict<K, T> and pool<T> as main container classes. dict<K, T> is
47 essentially a replacement for std::unordered_map<K, T> and pool<T> is a
48 replacement for std::unordered_set<T>. The main characteristics are:
49
50 - dict<K, T> and pool<T> are about 2x faster than the std containers
51
52 - references to elements in a dict<K, T> or pool<T> are invalidated by
53 insert and remove operations (similar to std::vector<T> on push_back()).
54
55 - some iterators are invalidated by erase(). specifically, iterators
56 that have not passed the erased element yet are invalidated. (erase()
57 itself returns valid iterator to the next element.)
58
59 - no iterators are invalidated by insert(). elements are inserted at
60 begin(). i.e. only a new iterator that starts at begin() will see the
61 inserted elements.
62
63 - the method .count(key, iterator) is like .count(key) but only
64 considers elements that can be reached via the iterator.
65
66 - iterators can be compared. it1 < it2 means that the position of t2
67 can be reached via t1 but not vice versa.
68
69 - the method .sort() can be used to sort the elements in the container
70 the container stays sorted until elements are added or removed.
71
72 - dict<K, T> and pool<T> will have the same order of iteration across
73 all compilers, standard libraries and architectures.
74
75 In addition to dict<K, T> and pool<T> there is also an idict<K> that
76 creates a bijective map from K to the integers. For example:
77
78 idict<string, 42> si;
79 log("%d\n", si("hello")); // will print 42
80 log("%d\n", si("world")); // will print 43
81 log("%d\n", si.at("world")); // will print 43
82 log("%d\n", si.at("dummy")); // will throw exception
83 log("%s\n", si[42].c_str())); // will print hello
84 log("%s\n", si[43].c_str())); // will print world
85 log("%s\n", si[44].c_str())); // will throw exception
86
87 It is not possible to remove elements from an idict.
88
89 Finally mfp<K> implements a merge-find set data structure (aka. disjoint-set or
90 union-find) over the type K ("mfp" = merge-find-promote).
91
92 2. Standard STL data types
93
94 In Yosys we use std::vector<T> and std::string whenever applicable. When
95 dict<K, T> and pool<T> are not suitable then std::map<K, T> and std::set<T>
96 are used instead.
97
98 The types std::vector<T> and std::string are also available as vector<T>
99 and string in the Yosys namespace.
100
101 3. RTLIL objects
102
103 The current design (essentially a collection of modules, each defined by a
104 netlist) is stored in memory using RTLIL object (declared in kernel/rtlil.h,
105 automatically included by kernel/yosys.h). You should glance over at least
106 the declarations for the following types in kernel/rtlil.h:
107
108 RTLIL::IdString
109 This is a handle for an identifier (e.g. cell or wire name).
110 It feels a lot like a std::string, but is only a single int
111 in size. (The actual string is stored in a global lookup
112 table.)
113
114 RTLIL::SigBit
115 A single signal bit. I.e. either a constant state (0, 1,
116 x, z) or a single bit from a wire.
117
118 RTLIL::SigSpec
119 Essentially a vector of SigBits.
120
121 RTLIL::Wire
122 RTLIL::Cell
123 The building blocks of the netlist in a module.
124
125 RTLIL::Module
126 RTLIL::Design
127 The module is a container with connected cells and wires
128 in it. The design is a container with modules in it.
129
130 All this types are also available without the RTLIL:: prefix in the Yosys
131 namespace.
132
133 4. SigMap and other Helper Classes
134
135 There are a couple of additional helper classes that are in wide use
136 in Yosys. Most importantly there is SigMap (declared in kernel/sigtools.h).
137
138 When a design has many wires in it that are connected to each other, then a
139 single signal bit can have multiple valid names. The SigMap object can be used
140 to map SigSpecs or SigBits to unique SigSpecs and SigBits that consistently
141 only use one wire from such a group of connected wires. For example:
142
143 SigBit a = module->addWire(NEW_ID);
144 SigBit b = module->addWire(NEW_ID);
145 module->connect(a, b);
146
147 log("%d\n", a == b); // will print 0
148
149 SigMap sigmap(module);
150 log("%d\n", sigmap(a) == sigmap(b)); // will print 1
151
152
153 Using the RTLIL Netlist Format
154 ------------------------------
155
156 In the RTLIL netlist format the cell ports contain SigSpecs that point to the
157 Wires. There are no references in the other direction. This has two direct
158 consequences:
159
160 (1) It is very easy to go from cells to wires but hard to go in the other way.
161
162 (2) There is no danger in removing cells from the netlists, but removing wires
163 can break the netlist format when there are still references to the wire
164 somewhere in the netlist.
165
166 The solution to (1) is easy: Create custom indexes that allow you to make fast
167 lookups for the wire-to-cell direction. You can either use existing generic
168 index structures to do that (such as the ModIndex class) or write your own
169 index. For many application it is simplest to construct a custom index. For
170 example:
171
172 SigMap sigmap(module);
173 dict<SigBit, Cell*> sigbit_to_driver_index;
174
175 for (auto cell : module->cells())
176 for (auto &conn : cell->connections())
177 if (cell->output(conn.first))
178 for (auto bit : sigmap(conn.second))
179 sigbit_to_driver_index[bit] = cell;
180
181 Regarding (2): There is a general theme in Yosys that you don't remove wires
182 from the design. You can rename them, unconnect them, but you do not actually remove
183 the Wire object from the module. Instead you let the "clean" command take care
184 of the dangling wires. On the other hand it is safe to remove cells (as long as
185 you make sure this does not invalidate a custom index you are using in your code).
186
187
188 Example Code
189 ------------
190
191 The following yosys commands are a good starting point if you are looking for examples
192 of how to use the Yosys API:
193
194 manual/CHAPTER_Prog/stubnets.cc
195 manual/PRESENTATION_Prog/my_cmd.cc
196
197
198 Script Passes
199 -------------
200
201 The ScriptPass base class can be used to implement passes that just call other passes,
202 like a script. Examples for such passes are:
203
204 techlibs/common/prep.cc
205 techlibs/common/synth.cc
206
207 In some cases it is easier to implement such a pass as regular pass, for example when
208 ScriptPass doesn't provide the type of flow control desired. (But many of the
209 script passes in Yosys that don't use ScriptPass simply predate the ScriptPass base
210 class.) Examples for such passes are:
211
212 passes/opt/opt.cc
213 passes/proc/proc.cc
214
215 Whether they use the ScriptPass base-class or not, a pass should always either
216 call other passes without doing any non-trivial work itself, or should implement
217 a non-trivial algorithm but not call any other passes. The reason for this is that
218 this helps containing complexity in individual passes and simplifies debugging the
219 entire system.
220
221 Exceptions to this rule should be rare and limited to cases where calling other
222 passes is optional and only happens when requested by the user (such as for
223 example `techmap -autoproc`), or where it is about commands that are "top-level
224 commands" in their own right, not components to be used in regular synthesis
225 flows (such as the `bugpoint` command).
226
227 A pass that would "naturally" call other passes and also do some work itself
228 should be re-written in one of two ways:
229
230 1) It could be re-written as script pass with the parts that are not calls
231 to other passes factored out into individual new passes. Usually in those
232 cases the new sub passes share the same prefix as the top-level script pass.
233
234 2) It could be re-written so that it already expects the design in a certain
235 state, expecting the calling script to set up this state before calling the
236 pass in questions.
237
238 Many back-ends are examples for the 2nd approach. For example, `write_aiger`
239 does not convert the design into AIG representation, but expects the design
240 to be already in this form, and prints an `Unsupported cell type` error
241 message otherwise.
242
243
244 Notes on the existing codebase
245 ------------------------------
246
247 For historical reasons not all parts of Yosys adhere to the current coding
248 style. When adding code to existing parts of the system, adhere to this guide
249 for the new code instead of trying to mimic the style of the surrounding code.