diff --git a/docs/resources/PRESENTATION_Prog/.gitignore b/docs/source/code_examples/extensions/.gitignore similarity index 100% rename from docs/resources/PRESENTATION_Prog/.gitignore rename to docs/source/code_examples/extensions/.gitignore diff --git a/docs/resources/PRESENTATION_Prog/Makefile b/docs/source/code_examples/extensions/Makefile similarity index 82% rename from docs/resources/PRESENTATION_Prog/Makefile rename to docs/source/code_examples/extensions/Makefile index 60ca513a8..bec29369c 100644 --- a/docs/resources/PRESENTATION_Prog/Makefile +++ b/docs/source/code_examples/extensions/Makefile @@ -1,9 +1,11 @@ PROGRAM_PREFIX := -YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys all: test0.log test1.log test2.log +dots: test1.dot + CXXFLAGS=$(shell $(YOSYS)-config --cxxflags) DATDIR=$(shell $(YOSYS)-config --datdir) @@ -18,6 +20,9 @@ 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 +test1.dot: + $(YOSYS) -m ./my_cmd.so -p 'test1; show -format dot -prefix test1' + 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 diff --git a/docs/resources/PRESENTATION_Prog/absval_ref.v b/docs/source/code_examples/extensions/absval_ref.v similarity index 69% rename from docs/resources/PRESENTATION_Prog/absval_ref.v rename to docs/source/code_examples/extensions/absval_ref.v index ca0a115a0..3f547b50b 100644 --- a/docs/resources/PRESENTATION_Prog/absval_ref.v +++ b/docs/source/code_examples/extensions/absval_ref.v @@ -1,3 +1,3 @@ module absval_ref(input signed [3:0] a, output [3:0] y); - assign y = a[3] ? -a : a; + assign y = a[3] ? -a : a; endmodule diff --git a/docs/resources/PRESENTATION_Prog/my_cmd.cc b/docs/source/code_examples/extensions/my_cmd.cc similarity index 97% rename from docs/resources/PRESENTATION_Prog/my_cmd.cc rename to docs/source/code_examples/extensions/my_cmd.cc index 9cb4b8e38..36ddbe175 100644 --- a/docs/resources/PRESENTATION_Prog/my_cmd.cc +++ b/docs/source/code_examples/extensions/my_cmd.cc @@ -14,7 +14,7 @@ struct MyPass : public Pass { log("Modules in current design:\n"); for (auto mod : design->modules()) - log(" %s (%zd wires, %zd cells)\n", log_id(mod), + log(" %s (%d wires, %d cells)\n", log_id(mod), GetSize(mod->wires()), GetSize(mod->cells())); } } MyPass; diff --git a/docs/resources/PRESENTATION_Prog/sigmap_test.v b/docs/source/code_examples/extensions/sigmap_test.v similarity index 67% rename from docs/resources/PRESENTATION_Prog/sigmap_test.v rename to docs/source/code_examples/extensions/sigmap_test.v index 18dcf5eb7..8d0b43836 100644 --- a/docs/resources/PRESENTATION_Prog/sigmap_test.v +++ b/docs/source/code_examples/extensions/sigmap_test.v @@ -1,3 +1,3 @@ module test(input a, output x, y); -assign x = a, y = a; + assign x = a, y = a; endmodule diff --git a/docs/source/code_examples/synth_flow/Makefile b/docs/source/code_examples/synth_flow/Makefile index 804f6da37..b6c83f05d 100644 --- a/docs/source/code_examples/synth_flow/Makefile +++ b/docs/source/code_examples/synth_flow/Makefile @@ -3,7 +3,6 @@ TARGETS += proc_01 proc_02 proc_03 TARGETS += opt_01 opt_02 opt_03 opt_04 TARGETS += memory_01 memory_02 TARGETS += techmap_01 -TARGETS += abc_01 PROGRAM_PREFIX := diff --git a/docs/source/code_examples/synth_flow/abc_01.v b/docs/source/code_examples/synth_flow/abc_01.v deleted file mode 100644 index 3bc686353..000000000 --- a/docs/source/code_examples/synth_flow/abc_01.v +++ /dev/null @@ -1,10 +0,0 @@ -module test(input clk, a, b, c, - output reg y); - - reg [2:0] q1, q2; - always @(posedge clk) begin - q1 <= { a, b, c }; - q2 <= q1; - y <= ^q2; - end -endmodule diff --git a/docs/source/code_examples/synth_flow/abc_01.ys b/docs/source/code_examples/synth_flow/abc_01.ys deleted file mode 100644 index bb0b3780f..000000000 --- a/docs/source/code_examples/synth_flow/abc_01.ys +++ /dev/null @@ -1,5 +0,0 @@ -read_verilog abc_01.v -read_verilog -lib abc_01_cells.v -hierarchy -check -top test -proc; opt; techmap -abc -dff -liberty abc_01_cells.lib;; diff --git a/docs/source/code_examples/synth_flow/abc_01_cells.lib b/docs/source/code_examples/synth_flow/abc_01_cells.lib deleted file mode 100644 index bf6b34788..000000000 --- a/docs/source/code_examples/synth_flow/abc_01_cells.lib +++ /dev/null @@ -1,54 +0,0 @@ -// test comment -/* test comment */ -library(demo) { - cell(BUF) { - area: 6; - pin(A) { direction: input; } - pin(Y) { direction: output; - function: "A"; } - } - cell(NOT) { - area: 3; - pin(A) { direction: input; } - pin(Y) { direction: output; - function: "A'"; } - } - cell(NAND) { - area: 4; - pin(A) { direction: input; } - pin(B) { direction: input; } - pin(Y) { direction: output; - function: "(A*B)'"; } - } - cell(NOR) { - area: 4; - pin(A) { direction: input; } - pin(B) { direction: input; } - pin(Y) { direction: output; - function: "(A+B)'"; } - } - cell(DFF) { - area: 18; - ff(IQ, IQN) { clocked_on: C; - next_state: D; } - pin(C) { direction: input; - clock: true; } - pin(D) { direction: input; } - pin(Q) { direction: output; - function: "IQ"; } - } - cell(DFFSR) { - area: 18; - ff(IQ, IQN) { clocked_on: C; - next_state: D; - preset: S; - clear: R; } - pin(C) { direction: input; - clock: true; } - pin(D) { direction: input; } - pin(Q) { direction: output; - function: "IQ"; } - pin(S) { direction: input; } - pin(R) { direction: input; } - } -} diff --git a/docs/source/code_examples/synth_flow/abc_01_cells.v b/docs/source/code_examples/synth_flow/abc_01_cells.v deleted file mode 100644 index 444094798..000000000 --- a/docs/source/code_examples/synth_flow/abc_01_cells.v +++ /dev/null @@ -1,40 +0,0 @@ - -module BUF(A, Y); -input A; -output Y = A; -endmodule - -module NOT(A, Y); -input A; -output Y = ~A; -endmodule - -module NAND(A, B, Y); -input A, B; -output Y = ~(A & B); -endmodule - -module NOR(A, B, Y); -input A, B; -output Y = ~(A | B); -endmodule - -module DFF(C, D, Q); -input C, D; -output reg Q; -always @(posedge C) - Q <= D; -endmodule - -module DFFSR(C, D, Q, S, R); -input C, D, S, R; -output reg Q; -always @(posedge C, posedge S, posedge R) - if (S) - Q <= 1'b1; - else if (R) - Q <= 1'b0; - else - Q <= D; -endmodule - diff --git a/docs/source/using_yosys/yosys_flows.rst b/docs/source/using_yosys/yosys_flows.rst index bafdb4c08..22f964a02 100644 --- a/docs/source/using_yosys/yosys_flows.rst +++ b/docs/source/using_yosys/yosys_flows.rst @@ -278,7 +278,9 @@ Checking. Checking techmap ~~~~~~~~~~~~~~~~ -.. todo:: add/expand supporting text, reference no longer exists +.. todo:: add/expand supporting text + +.. TODO:: reference no longer exists Remember the following example from :doc:`/getting_started/typical_phases`? diff --git a/docs/source/yosys_internals/extending_yosys/extensions.rst b/docs/source/yosys_internals/extending_yosys/extensions.rst index 346eb5265..ab8cf0cb6 100644 --- a/docs/source/yosys_internals/extending_yosys/extensions.rst +++ b/docs/source/yosys_internals/extending_yosys/extensions.rst @@ -1,52 +1,25 @@ Writing extensions ================== +.. role:: yoscrypt(code) + :language: yoscrypt + .. todo:: check text is coherent 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 of the Yosys source code contains notes on various +aspects of Yosys development. In particular, the files GettingStarted and +CodingStyle may be of interest. -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 - -.. literalinclude:: /temp/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/code_examples/stubnets/stubnets.cc``. - -.. literalinclude:: /code_examples/stubnets/stubnets.cc - :language: c++ - :linenos: - :caption: docs/source/code_examples/stubnets/stubnets.cc - -.. literalinclude:: /code_examples/stubnets/Makefile - :language: makefile - :linenos: - :caption: docs/source/code_examples/stubnets/Makefile - -.. literalinclude:: /code_examples/stubnets/test.v - :language: verilog - :linenos: - :caption: docs/source/code_examples/stubnets/test.v +.. todo:: what's in guidelines/GettingStarted that's missing from the manual? Quick guide ----------- -See also: ``docs/resources/PRESENTATION_Prog/*``. +Code examples from this section are included in the +``docs/code_examples/extensions/`` directory of the Yosys source code. Program components and data formats ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -76,39 +49,90 @@ It is possible to only work on this simpler version: When trying to understand what a command does, creating a small test case to look at the output of :cmd:ref:`dump` and :cmd:ref:`show` before and after the -command has been executed can be helpful. The -:doc:`/using_yosys/more_scripting/selections` document has more information on -using these commands. +command has been executed can be helpful. +:doc:`/using_yosys/more_scripting/selections` has more information on using +these commands. + +Creating a command +~~~~~~~~~~~~~~~~~~ + +.. todo:: add/expand supporting text + +Let's create a very simple test command which prints the arguments we called it +with, and lists off the current design's modules. + +.. literalinclude:: /code_examples/extensions/my_cmd.cc + :language: c++ + :lines: 1, 4, 6, 7-20 + :caption: Example command :yoscrypt:`my_cmd` from ``my_cmd.cc`` + +Note that we are making a global instance of a class derived from +``Yosys::Pass``, which we get by including ``kernel/yosys.h``. + +Compiling to a plugin +~~~~~~~~~~~~~~~~~~~~~ + +Yosys can be extended by adding additional C++ code to the Yosys code base, or +by loading plugins into Yosys. For maintainability it is generally recommended +to create plugins. + +The following command compiles our example :yoscrypt:`my_cmd` to a Yosys plugin: + +.. code:: shell + + yosys-config --exec --cxx --cxxflags --ldflags \ + -o my_cmd.so -shared my_cmd.cc --ldlibs + +Or shorter: + +.. code:: shell + + yosys-config --build my_cmd.so my_cmd.cc + +Running Yosys with the ``-m`` option allows the plugin to be used. Here's a +quick example that also uses the ``-p`` option to run :yoscrypt:`my_cmd foo +bar`. + +.. code:: shell-session + + $ yosys -m ./my_cmd.so -p 'my_cmd foo bar' + + -- Running command `my_cmd foo bar' -- + Arguments to my_cmd: + my_cmd + foo + bar + Modules in current design: Creating modules from scratch ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. todo:: add/expand supporting text, also use files in docs/resources/PRESENTATION_Prog - Let's create the following module using the RTLIL API: -.. literalinclude:: ../../../resources/PRESENTATION_Prog/absval_ref.v - :language: Verilog - :caption: docs/resources/PRESENTATION_Prog/absval_ref.v +.. literalinclude:: /code_examples/extensions/absval_ref.v + :language: Verilog + :caption: absval_ref.v -.. code:: C++ +We'll do the same as before and format it as a a ``Yosys::Pass``. - RTLIL::Module *module = new RTLIL::Module; - module->name = "\\absval"; +.. literalinclude:: /code_examples/extensions/my_cmd.cc + :language: c++ + :lines: 23-47 + :caption: :yoscrypt:`test1` - creating the absval module, from ``my_cmd.cc`` - RTLIL::Wire *a = module->addWire("\\a", 4); - a->port_input = true; - a->port_id = 1; +.. code:: shell-session - RTLIL::Wire *y = module->addWire("\\y", 4); - y->port_output = true; - y->port_id = 2; + $ yosys -m ./my_cmd.so -p 'test1' -Q - 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); + -- Running command `test1' -- + Name of this module: absval - module->fixup_ports(); +And if we look at the schematic for this new module we see the following: + +.. figure:: /_images/code_examples/extensions/test1.* + :class: width-helper + + Output of ``yosys -m ./my_cmd.so -p 'test1; show'`` Modifying modules ~~~~~~~~~~~~~~~~~ @@ -124,7 +148,6 @@ When modifying existing modules, stick to the following DOs and DON'Ts: - 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 section) when you need a unique handle for each signal bit. @@ -133,13 +156,14 @@ Using the SigMap helper class Consider the following module: -.. code:: Verilog +.. literalinclude:: /code_examples/extensions/sigmap_test.v + :language: Verilog + :caption: sigmap_test.v - 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: -In this case ``a``, ``x``, and ``y`` are all different names for the same signal. However: +.. todo:: use my_cmd.cc literalincludes .. code:: C++ @@ -148,7 +172,8 @@ In this case ``a``, ``x``, and ``y`` are all different names for the same signal 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). +unique signal from the group (usually the wire that is directly driven by a cell +or port). .. code:: C++ @@ -159,7 +184,8 @@ unique signal from the group (usually the wire that is directly driven by a cell Printing log messages ~~~~~~~~~~~~~~~~~~~~~ -The ``log()`` function is a ``printf()``-like function that can be used to create 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: @@ -206,53 +232,24 @@ Use ``log_cmd_error()`` to report a recoverable error: Use ``log_assert()`` and ``log_abort()`` instead of ``assert()`` and ``abort()``. -Creating a command -~~~~~~~~~~~~~~~~~~ +The "stubnets" example module +------------------------------ -Simply create a global instance of a class derived from ``Pass`` to create -a new yosys command: +The following is the complete code of the "stubnets" example module. It is +included in the Yosys source distribution as +``docs/source/code_examples/stubnets/stubnets.cc``. -.. code:: C++ +.. literalinclude:: /code_examples/stubnets/stubnets.cc + :language: c++ + :linenos: + :caption: docs/source/code_examples/stubnets/stubnets.cc - #include "kernel/yosys.h" - USING_YOSYS_NAMESPACE +.. literalinclude:: /code_examples/stubnets/Makefile + :language: makefile + :linenos: + :caption: docs/source/code_examples/stubnets/Makefile - struct MyPass : public Pass { - MyPass() : Pass("my_cmd", "just a simple test") { } - virtual void execute(std::vector 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' +.. literalinclude:: /code_examples/stubnets/test.v + :language: verilog + :linenos: + :caption: docs/source/code_examples/stubnets/test.v