Merge branch 'SergeyDegtyar/ecp5' of https://github.com/SergeyDegtyar/yosys into...
[yosys.git] / CodingReadme
1
2 This file contains some very brief documentation on things like programming APIs.
3 Also consult the Yosys manual and the section about programming in the presentation.
4 (Both can be downloaded as PDF from the yosys webpage.)
5
6
7 --snip-- only the lines below this mark are included in the yosys manual --snip--
8 Getting Started
9 ===============
10
11
12 Outline of a Yosys command
13 --------------------------
14
15 Here is a the C++ code for a "hello_world" Yosys command (hello.cc):
16
17 #include "kernel/yosys.h"
18
19 USING_YOSYS_NAMESPACE
20 PRIVATE_NAMESPACE_BEGIN
21
22 struct HelloWorldPass : public Pass {
23 HelloWorldPass() : Pass("hello_world") { }
24 void execute(vector<string>, Design*) override {
25 log("Hello World!\n");
26 }
27 } HelloWorldPass;
28
29 PRIVATE_NAMESPACE_END
30
31 This can be built into a Yosys module using the following command:
32
33 yosys-config --exec --cxx --cxxflags --ldflags -o hello.so -shared hello.cc --ldlibs
34
35 Or short:
36
37 yosys-config --build hello.so hello.cc
38
39 And then executed using the following command:
40
41 yosys -m hello.so -p hello_world
42
43
44 Yosys Data Structures
45 ---------------------
46
47 Here is a short list of data structures that you should make yourself familiar
48 with before you write C++ code for Yosys. The following data structures are all
49 defined when "kernel/yosys.h" is included and USING_YOSYS_NAMESPACE is used.
50
51 1. Yosys Container Classes
52
53 Yosys uses dict<K, T> and pool<T> as main container classes. dict<K, T> is
54 essentially a replacement for std::unordered_map<K, T> and pool<T> is a
55 replacement for std::unordered_set<T>. The main characteristics are:
56
57 - dict<K, T> and pool<T> are about 2x faster than the std containers
58
59 - references to elements in a dict<K, T> or pool<T> are invalidated by
60 insert and remove operations (similar to std::vector<T> on push_back()).
61
62 - some iterators are invalidated by erase(). specifically, iterators
63 that have not passed the erased element yet are invalidated. (erase()
64 itself returns valid iterator to the next element.)
65
66 - no iterators are invalidated by insert(). elements are inserted at
67 begin(). i.e. only a new iterator that starts at begin() will see the
68 inserted elements.
69
70 - the method .count(key, iterator) is like .count(key) but only
71 considers elements that can be reached via the iterator.
72
73 - iterators can be compared. it1 < it2 means that the position of t2
74 can be reached via t1 but not vice versa.
75
76 - the method .sort() can be used to sort the elements in the container
77 the container stays sorted until elements are added or removed.
78
79 - dict<K, T> and pool<T> will have the same order of iteration across
80 all compilers, standard libraries and architectures.
81
82 In addition to dict<K, T> and pool<T> there is also an idict<K> that
83 creates a bijective map from K to the integers. For example:
84
85 idict<string, 42> si;
86 log("%d\n", si("hello")); // will print 42
87 log("%d\n", si("world")); // will print 43
88 log("%d\n", si.at("world")); // will print 43
89 log("%d\n", si.at("dummy")); // will throw exception
90 log("%s\n", si[42].c_str())); // will print hello
91 log("%s\n", si[43].c_str())); // will print world
92 log("%s\n", si[44].c_str())); // will throw exception
93
94 It is not possible to remove elements from an idict.
95
96 Finally mfp<K> implements a merge-find set data structure (aka. disjoint-set or
97 union-find) over the type K ("mfp" = merge-find-promote).
98
99 2. Standard STL data types
100
101 In Yosys we use std::vector<T> and std::string whenever applicable. When
102 dict<K, T> and pool<T> are not suitable then std::map<K, T> and std::set<T>
103 are used instead.
104
105 The types std::vector<T> and std::string are also available as vector<T>
106 and string in the Yosys namespace.
107
108 3. RTLIL objects
109
110 The current design (essentially a collection of modules, each defined by a
111 netlist) is stored in memory using RTLIL object (declared in kernel/rtlil.h,
112 automatically included by kernel/yosys.h). You should glance over at least
113 the declarations for the following types in kernel/rtlil.h:
114
115 RTLIL::IdString
116 This is a handle for an identifier (e.g. cell or wire name).
117 It feels a lot like a std::string, but is only a single int
118 in size. (The actual string is stored in a global lookup
119 table.)
120
121 RTLIL::SigBit
122 A single signal bit. I.e. either a constant state (0, 1,
123 x, z) or a single bit from a wire.
124
125 RTLIL::SigSpec
126 Essentially a vector of SigBits.
127
128 RTLIL::Wire
129 RTLIL::Cell
130 The building blocks of the netlist in a module.
131
132 RTLIL::Module
133 RTLIL::Design
134 The module is a container with connected cells and wires
135 in it. The design is a container with modules in it.
136
137 All this types are also available without the RTLIL:: prefix in the Yosys
138 namespace.
139
140 4. SigMap and other Helper Classes
141
142 There are a couple of additional helper classes that are in wide use
143 in Yosys. Most importantly there is SigMap (declared in kernel/sigtools.h).
144
145 When a design has many wires in it that are connected to each other, then a
146 single signal bit can have multiple valid names. The SigMap object can be used
147 to map SigSpecs or SigBits to unique SigSpecs and SigBits that consistently
148 only use one wire from such a group of connected wires. For example:
149
150 SigBit a = module->addWire(NEW_ID);
151 SigBit b = module->addWire(NEW_ID);
152 module->connect(a, b);
153
154 log("%d\n", a == b); // will print 0
155
156 SigMap sigmap(module);
157 log("%d\n", sigmap(a) == sigmap(b)); // will print 1
158
159
160 Using the RTLIL Netlist Format
161 ------------------------------
162
163 In the RTLIL netlist format the cell ports contain SigSpecs that point to the
164 Wires. There are no references in the other direction. This has two direct
165 consequences:
166
167 (1) It is very easy to go from cells to wires but hard to go in the other way.
168
169 (2) There is no danger in removing cells from the netlists, but removing wires
170 can break the netlist format when there are still references to the wire
171 somewhere in the netlist.
172
173 The solution to (1) is easy: Create custom indexes that allow you to make fast
174 lookups for the wire-to-cell direction. You can either use existing generic
175 index structures to do that (such as the ModIndex class) or write your own
176 index. For many application it is simplest to construct a custom index. For
177 example:
178
179 SigMap sigmap(module);
180 dict<SigBit, Cell*> sigbit_to_driver_index;
181
182 for (auto cell : module->cells())
183 for (auto &conn : cell->connections())
184 if (cell->output(conn.first))
185 for (auto bit : sigmap(conn.second))
186 sigbit_to_driver_index[bit] = cell;
187
188 Regarding (2): There is a general theme in Yosys that you don't remove wires
189 from the design. You can rename them, unconnect them, but you do not actually remove
190 the Wire object from the module. Instead you let the "clean" command take care
191 of the dangling wires. On the other hand it is safe to remove cells (as long as
192 you make sure this does not invalidate a custom index you are using in your code).
193
194
195 Example Code
196 ------------
197
198 The following yosys commands are a good starting point if you are looking for examples
199 of how to use the Yosys API:
200
201 manual/CHAPTER_Prog/stubnets.cc
202 manual/PRESENTATION_Prog/my_cmd.cc
203
204
205 Notes on the existing codebase
206 ------------------------------
207
208 For historical reasons not all parts of Yosys adhere to the current coding
209 style. When adding code to existing parts of the system, adhere to this guide
210 for the new code instead of trying to mimic the style of the surrounding code.
211
212
213
214 Coding Style
215 ============
216
217
218 Formatting of code
219 ------------------
220
221 - Yosys code is using tabs for indentation. Tabs are 8 characters.
222
223 - A continuation of a statement in the following line is indented by
224 two additional tabs.
225
226 - Lines are as long as you want them to be. A good rule of thumb is
227 to break lines at about column 150.
228
229 - Opening braces can be put on the same or next line as the statement
230 opening the block (if, switch, for, while, do). Put the opening brace
231 on its own line for larger blocks, especially blocks that contains
232 blank lines.
233
234 - Otherwise stick to the Linux Kernel Coding Style:
235 https://www.kernel.org/doc/Documentation/CodingStyle
236
237
238 C++ Language
239 -------------
240
241 Yosys is written in C++11. At the moment only constructs supported by
242 gcc 4.8 are allowed in Yosys code. This will change in future releases.
243
244 In general Yosys uses "int" instead of "size_t". To avoid compiler
245 warnings for implicit type casts, always use "GetSize(foobar)" instead
246 of "foobar.size()". (GetSize() is defined in kernel/yosys.h)
247
248 Use range-based for loops whenever applicable.
249
250
251 --snap-- only the lines above this mark are included in the yosys manual --snap--
252
253
254 Creating the Visual Studio Template Project
255 ===========================================
256
257 1. Create an empty Visual C++ Win32 Console App project
258
259 Microsoft Visual Studio Express 2013 for Windows Desktop
260 Open New Project Wizard (File -> New Project..)
261
262 Project Name: YosysVS
263 Solution Name: YosysVS
264 [X] Create directory for solution
265 [ ] Add to source control
266
267 [X] Console applications
268 [X] Empty Project
269 [ ] SDL checks
270
271 2. Open YosysVS Project Properties
272
273 Select Configuration: All Configurations
274
275 C/C++ -> General -> Additional Include Directories
276 Add: ..\yosys
277
278 C/C++ -> Preprocessor -> Preprocessor Definitions
279 Add: _YOSYS_;_CRT_SECURE_NO_WARNINGS
280
281 3. Resulting file system tree:
282
283 YosysVS/
284 YosysVS/YosysVS
285 YosysVS/YosysVS/YosysVS.vcxproj
286 YosysVS/YosysVS/YosysVS.vcxproj.filters
287 YosysVS/YosysVS.sdf
288 YosysVS/YosysVS.sln
289 YosysVS/YosysVS.v12.suo
290
291 4. Zip YosysVS as YosysVS-Tpl-v1.zip
292
293
294
295 Checklist for adding internal cell types
296 ========================================
297
298 Things to do right away:
299
300 - Add to kernel/celltypes.h (incl. eval() handling for non-mem cells)
301 - Add to InternalCellChecker::check() in kernel/rtlil.cc
302 - Add to techlibs/common/simlib.v
303 - Add to techlibs/common/techmap.v
304
305 Things to do after finalizing the cell interface:
306
307 - Add support to kernel/satgen.h for the new cell type
308 - Add to manual/CHAPTER_CellLib.tex (or just add a fixme to the bottom)
309 - Maybe add support to the Verilog backend for dumping such cells as expression
310
311
312
313 Checklist for creating Yosys releases
314 =====================================
315
316 Update the CHANGELOG file:
317
318 cd ~yosys
319 gitk &
320 vi CHANGELOG
321
322
323 Update and check documentation:
324
325 cd ~yosys
326 make update-manual
327 make manual
328 - sanity check the figures in the appnotes and presentation
329 - if there are any odd things -> investigate
330 - make cosmetic changes to the .tex files if necessary
331
332 cd ~yosys
333 vi README CodingReadme
334 - is the information provided in those file still up to date
335
336
337 Then with default config setting:
338
339 cd ~yosys
340 make vgtest
341
342 cd ~yosys
343 ./yosys -p 'proc; show' tests/simple/fiedler-cooley.v
344 ./yosys -p 'proc; opt; show' tests/simple/fiedler-cooley.v
345 ./yosys -p 'synth; show' tests/simple/fiedler-cooley.v
346 ./yosys -p 'synth_xilinx -top up3down5; show' tests/simple/fiedler-cooley.v
347
348 cd ~yosys/examples/cmos
349 bash testbench.sh
350
351 cd ~yosys/examples/basys3
352 bash run.sh
353
354
355 Test building plugins with various of the standard passes:
356
357 yosys-config --build test.so equiv_simple.cc
358 - also check the code examples in CodingReadme
359
360
361 And if a version of the verific library is currently available:
362
363 cd ~yosys
364 cat frontends/verific/build_amd64.txt
365 - follow instructions
366
367 cd frontends/verific
368 ../../yosys test_navre.ys
369
370
371 Finally run all tests with "make config-{clang,gcc,gcc-4.8}":
372
373 cd ~yosys
374 make clean
375 make test
376 make ystests
377 make vloghtb
378 make install
379
380 cd ~yosys-bigsim
381 make clean
382 make full
383
384 cd ~vloghammer
385 make purge gen_issues gen_samples
386 make SYN_LIST="yosys" SIM_LIST="icarus yosim verilator" REPORT_FULL=1 world
387 chromium-browser report.html
388
389
390 Release:
391
392 - set YOSYS_VER to x.y.z in Makefile
393 - remove "bumpversion" target from Makefile
394 - update version string in CHANGELOG
395 git commit -am "Yosys x.y.z"
396
397 - push tag to github
398 - post changelog on github
399 - post short release note on reddit
400
401
402 Updating the website:
403
404 cd ~yosys
405 make manual
406 make install
407
408 - update pdf files on the website
409
410 cd ~yosys-web
411 make update_cmd
412 make update_show
413 git commit -am update
414 make push
415
416
417
418 Cross-Building for Windows with MXE
419 ===================================
420
421 Check http://mxe.cc/#requirements and install all missing requirements.
422
423 As root (or other user with write access to /usr/local/src):
424
425 cd /usr/local/src
426 git clone https://github.com/mxe/mxe.git
427 cd mxe
428
429 make -j$(nproc) MXE_PLUGIN_DIRS="plugins/tcl.tk" \
430 MXE_TARGETS="i686-w64-mingw32.static" \
431 gcc tcl readline
432
433 Then as regular user in some directory where you build stuff:
434
435 git clone https://github.com/cliffordwolf/yosys.git yosys-win32
436 cd yosys-win32
437 make config-mxe
438 make -j$(nproc) mxebin
439
440
441
442 How to add unit test
443 ====================
444
445 Unit test brings some advantages, briefly, we can list some of them (reference
446 [1](https://en.wikipedia.org/wiki/Unit_testing)):
447
448 * Tests reduce bugs in new features;
449 * Tests reduce bugs in existing features;
450 * Tests are good documentation;
451 * Tests reduce the cost of change;
452 * Tests allow refactoring;
453
454 With those advantages in mind, it was required to choose a framework which fits
455 well with C/C++ code. Hence, it was chosen (google test)
456 [https://github.com/google/googletest], because it is largely used and it is
457 relatively easy learn.
458
459 Install and configure google test (manually)
460 --------------------------------------------
461
462 In this section, you will see a brief description of how to install google
463 test. However, it is strongly recommended that you take a look to the official
464 repository (https://github.com/google/googletest) and refers to that if you
465 have any problem to install it. Follow the steps below:
466
467 * Install: cmake and pthread
468 * Clone google test project from: https://github.com/google/googletest and
469 enter in the project directory
470 * Inside project directory, type:
471
472 ```
473 cmake -DBUILD_SHARED_LIBS=ON .
474 make
475 ```
476
477 * After compilation, copy all "*.so" inside directory "googlemock" and
478 "googlemock/gtest" to "/usr/lib/"
479 * Done! Now you can compile your tests.
480
481 If you have any problem, go to the official repository to find help.
482
483 Ps.: Some distros already have googletest packed. If your distro supports it,
484 you can use it instead of compile.
485
486 Create new unit test
487 --------------------
488
489 If you want to add new unit tests for Yosys, just follow the steps below:
490
491 * Go to directory "yosys/test/unit/"
492 * In this directory you can find something similar Yosys's directory structure.
493 To create your unit test file you have to follow this pattern:
494 fileNameToImplementUnitTest + Test.cc. E.g.: if you want to implement the
495 unit test for kernel/celledges.cc, you will need to create a file like this:
496 tests/unit/kernel/celledgesTest.cc;
497 * Implement your unit test
498
499 Run unit test
500 -------------
501
502 To compile and run all unit tests, just go to yosys root directory and type:
503 ```
504 make unit-test
505 ```
506
507 If you want to remove all unit test files, type:
508 ```
509 make clean-unit-test
510 ```