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.)
7 --snip-- only the lines below this mark are included in the yosys manual --snip--
12 Outline of a Yosys command
13 --------------------------
15 Here is a the C++ code for a "hello_world" Yosys command (hello.cc):
17 #include "kernel/yosys.h"
20 PRIVATE_NAMESPACE_BEGIN
22 struct HelloWorldPass : public Pass {
23 HelloWorldPass() : Pass("hello_world") { }
24 void execute(vector<string>, Design*) override {
25 log("Hello World!\n");
31 This can be built into a Yosys module using the following command:
33 yosys-config --exec --cxx --cxxflags --ldflags -o hello.so -shared hello.cc --ldlibs
37 yosys-config --build hello.so hello.cc
39 And then executed using the following command:
41 yosys -m hello.so -p hello_world
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.
51 1. Yosys Container Classes
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:
57 - dict<K, T> and pool<T> are about 2x faster than the std containers
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()).
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.)
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
70 - the method .count(key, iterator) is like .count(key) but only
71 considers elements that can be reached via the iterator.
73 - iterators can be compared. it1 < it2 means that the position of t2
74 can be reached via t1 but not vice versa.
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.
79 - dict<K, T> and pool<T> will have the same order of iteration across
80 all compilers, standard libraries and architectures.
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:
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
94 It is not possible to remove elements from an idict.
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).
99 2. Standard STL data types
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>
105 The types std::vector<T> and std::string are also available as vector<T>
106 and string in the Yosys namespace.
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:
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
122 A single signal bit. I.e. either a constant state (0, 1,
123 x, z) or a single bit from a wire.
126 Essentially a vector of SigBits.
130 The building blocks of the netlist in a module.
134 The module is a container with connected cells and wires
135 in it. The design is a container with modules in it.
137 All this types are also available without the RTLIL:: prefix in the Yosys
140 4. SigMap and other Helper Classes
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).
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:
150 SigBit a = module->addWire(NEW_ID);
151 SigBit b = module->addWire(NEW_ID);
152 module->connect(a, b);
154 log("%d\n", a == b); // will print 0
156 SigMap sigmap(module);
157 log("%d\n", sigmap(a) == sigmap(b)); // will print 1
160 Using the RTLIL Netlist Format
161 ------------------------------
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
167 (1) It is very easy to go from cells to wires but hard to go in the other way.
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.
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
179 SigMap sigmap(module);
180 dict<SigBit, Cell*> sigbit_to_driver_index;
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;
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).
198 The following yosys commands are a good starting point if you are looking for examples
199 of how to use the Yosys API:
201 manual/CHAPTER_Prog/stubnets.cc
202 manual/PRESENTATION_Prog/my_cmd.cc
208 The ScriptPass base class can be used to implement passes that just call other passes,
209 like a script. Examples for such passes are:
211 techlibs/common/prep.cc
212 techlibs/common/synth.cc
214 In some cases it is easier to implement such a pass as regular pass, for example when
215 ScriptPass doesn't provide the type of flow control desired. (But many of the
216 script passes in Yosys that don't use ScriptPass simply predate the ScriptPass base
217 class.) Examples for such passes are:
222 Whether they use the ScriptPass base-class or not, a pass should always either
223 call other passes without doing any non-trivial work itself, or should implement
224 a non-trivial algorithm but not call any other passes. The reason for this is that
225 this helps containing complexity in individual passes and simplifies debugging the
228 Exceptions to this rule should be rare and limited to cases where calling other
229 passes is optional and only happens when requested by the user (such as for
230 example `techmap -autoproc`), or where it is about commands that are "top-level
231 commands" in their own right, not components to be used in regular synthesis
232 flows (such as the `bugpoint` command).
234 A pass that would "naturally" call other passes and also do some work itself
235 should be re-written in one of two ways:
237 1) It could be re-written as script pass with the parts that are not calls
238 to other passes factored out into individual new passes. Usually in those
239 cases the new sub passes share the same prefix as the top-level script pass.
241 2) It could be re-written so that it already expects the design in a certain
242 state, expecting the calling script to set up this state before calling the
245 Many back-ends are examples for the 2nd approach. For example, `write_aiger`
246 does not convert the design into AIG representation, but expects the design
247 to be already in this form, and prints an `Unsupported cell type` error
251 Notes on the existing codebase
252 ------------------------------
254 For historical reasons not all parts of Yosys adhere to the current coding
255 style. When adding code to existing parts of the system, adhere to this guide
256 for the new code instead of trying to mimic the style of the surrounding code.
267 - Yosys code is using tabs for indentation. Tabs are 8 characters.
269 - A continuation of a statement in the following line is indented by
272 - Lines are as long as you want them to be. A good rule of thumb is
273 to break lines at about column 150.
275 - Opening braces can be put on the same or next line as the statement
276 opening the block (if, switch, for, while, do). Put the opening brace
277 on its own line for larger blocks, especially blocks that contains
280 - Otherwise stick to the Linux Kernel Coding Style:
281 https://www.kernel.org/doc/Documentation/CodingStyle
287 Yosys is written in C++11. At the moment only constructs supported by
288 gcc 4.8 are allowed in Yosys code. This will change in future releases.
290 In general Yosys uses "int" instead of "size_t". To avoid compiler
291 warnings for implicit type casts, always use "GetSize(foobar)" instead
292 of "foobar.size()". (GetSize() is defined in kernel/yosys.h)
294 Use range-based for loops whenever applicable.
297 --snap-- only the lines above this mark are included in the yosys manual --snap--
300 Creating the Visual Studio Template Project
301 ===========================================
303 1. Create an empty Visual C++ Win32 Console App project
305 Microsoft Visual Studio Express 2013 for Windows Desktop
306 Open New Project Wizard (File -> New Project..)
308 Project Name: YosysVS
309 Solution Name: YosysVS
310 [X] Create directory for solution
311 [ ] Add to source control
313 [X] Console applications
317 2. Open YosysVS Project Properties
319 Select Configuration: All Configurations
321 C/C++ -> General -> Additional Include Directories
324 C/C++ -> Preprocessor -> Preprocessor Definitions
325 Add: _YOSYS_;_CRT_SECURE_NO_WARNINGS
327 3. Resulting file system tree:
331 YosysVS/YosysVS/YosysVS.vcxproj
332 YosysVS/YosysVS/YosysVS.vcxproj.filters
335 YosysVS/YosysVS.v12.suo
337 4. Zip YosysVS as YosysVS-Tpl-v1.zip
341 Checklist for adding internal cell types
342 ========================================
344 Things to do right away:
346 - Add to kernel/celltypes.h (incl. eval() handling for non-mem cells)
347 - Add to InternalCellChecker::check() in kernel/rtlil.cc
348 - Add to techlibs/common/simlib.v
349 - Add to techlibs/common/techmap.v
351 Things to do after finalizing the cell interface:
353 - Add support to kernel/satgen.h for the new cell type
354 - Add to manual/CHAPTER_CellLib.tex (or just add a fixme to the bottom)
355 - Maybe add support to the Verilog backend for dumping such cells as expression
359 Checklist for creating Yosys releases
360 =====================================
362 Update the CHANGELOG file:
369 Update and check documentation:
374 - sanity check the figures in the appnotes and presentation
375 - if there are any odd things -> investigate
376 - make cosmetic changes to the .tex files if necessary
379 vi README CodingReadme
380 - is the information provided in those file still up to date
383 Then with default config setting:
389 ./yosys -p 'proc; show' tests/simple/fiedler-cooley.v
390 ./yosys -p 'proc; opt; show' tests/simple/fiedler-cooley.v
391 ./yosys -p 'synth; show' tests/simple/fiedler-cooley.v
392 ./yosys -p 'synth_xilinx -top up3down5; show' tests/simple/fiedler-cooley.v
394 cd ~yosys/examples/cmos
397 cd ~yosys/examples/basys3
401 Test building plugins with various of the standard passes:
403 yosys-config --build test.so equiv_simple.cc
404 - also check the code examples in CodingReadme
407 And if a version of the verific library is currently available:
410 cat frontends/verific/build_amd64.txt
411 - follow instructions
414 ../../yosys test_navre.ys
417 Finally run all tests with "make config-{clang,gcc,gcc-4.8}":
431 make purge gen_issues gen_samples
432 make SYN_LIST="yosys" SIM_LIST="icarus yosim verilator" REPORT_FULL=1 world
433 chromium-browser report.html
438 - set YOSYS_VER to x.y.z in Makefile
439 - remove "bumpversion" target from Makefile
440 - update version string in CHANGELOG
441 git commit -am "Yosys x.y.z"
444 - post changelog on github
445 - post short release note on reddit
448 Updating the website:
454 - update pdf files on the website
459 git commit -am update
464 Cross-Building for Windows with MXE
465 ===================================
467 Check http://mxe.cc/#requirements and install all missing requirements.
469 As root (or other user with write access to /usr/local/src):
472 git clone https://github.com/mxe/mxe.git
475 make -j$(nproc) MXE_PLUGIN_DIRS="plugins/tcl.tk" \
476 MXE_TARGETS="i686-w64-mingw32.static" \
479 Then as regular user in some directory where you build stuff:
481 git clone https://github.com/cliffordwolf/yosys.git yosys-win32
484 make -j$(nproc) mxebin
491 Unit test brings some advantages, briefly, we can list some of them (reference
492 [1](https://en.wikipedia.org/wiki/Unit_testing)):
494 * Tests reduce bugs in new features;
495 * Tests reduce bugs in existing features;
496 * Tests are good documentation;
497 * Tests reduce the cost of change;
498 * Tests allow refactoring;
500 With those advantages in mind, it was required to choose a framework which fits
501 well with C/C++ code. Hence, it was chosen (google test)
502 [https://github.com/google/googletest], because it is largely used and it is
503 relatively easy learn.
505 Install and configure google test (manually)
506 --------------------------------------------
508 In this section, you will see a brief description of how to install google
509 test. However, it is strongly recommended that you take a look to the official
510 repository (https://github.com/google/googletest) and refers to that if you
511 have any problem to install it. Follow the steps below:
513 * Install: cmake and pthread
514 * Clone google test project from: https://github.com/google/googletest and
515 enter in the project directory
516 * Inside project directory, type:
519 cmake -DBUILD_SHARED_LIBS=ON .
523 * After compilation, copy all "*.so" inside directory "googlemock" and
524 "googlemock/gtest" to "/usr/lib/"
525 * Done! Now you can compile your tests.
527 If you have any problem, go to the official repository to find help.
529 Ps.: Some distros already have googletest packed. If your distro supports it,
530 you can use it instead of compile.
535 If you want to add new unit tests for Yosys, just follow the steps below:
537 * Go to directory "yosys/test/unit/"
538 * In this directory you can find something similar Yosys's directory structure.
539 To create your unit test file you have to follow this pattern:
540 fileNameToImplementUnitTest + Test.cc. E.g.: if you want to implement the
541 unit test for kernel/celledges.cc, you will need to create a file like this:
542 tests/unit/kernel/celledgesTest.cc;
543 * Implement your unit test
548 To compile and run all unit tests, just go to yosys root directory and type:
553 If you want to remove all unit test files, type: