aboutsummaryrefslogtreecommitdiffstats
path: root/docs/source/CHAPTER_Verilog.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/source/CHAPTER_Verilog.rst')
-rw-r--r--docs/source/CHAPTER_Verilog.rst666
1 files changed, 666 insertions, 0 deletions
diff --git a/docs/source/CHAPTER_Verilog.rst b/docs/source/CHAPTER_Verilog.rst
new file mode 100644
index 000000000..484844fba
--- /dev/null
+++ b/docs/source/CHAPTER_Verilog.rst
@@ -0,0 +1,666 @@
+.. _chapter:verilog:
+
+The Verilog and AST frontends
+=============================
+
+This chapter provides an overview of the implementation of the Yosys Verilog and
+AST frontends. The Verilog frontend reads Verilog-2005 code and creates an
+abstract syntax tree (AST) representation of the input. This AST representation
+is then passed to the AST frontend that converts it to RTLIL data, as
+illustrated in :numref:`Fig. %s <fig:Verilog_flow>`.
+
+.. figure:: ../images/verilog_flow.*
+ :class: width-helper
+ :name: fig:Verilog_flow
+
+ Simplified Verilog to RTLIL data flow
+
+Transforming Verilog to AST
+---------------------------
+
+The Verilog frontend converts the Verilog sources to an internal AST
+representation that closely resembles the structure of the original
+Verilog code. The Verilog frontend consists of three components, the
+Preprocessor, the Lexer and the Parser.
+
+The source code to the Verilog frontend can be found in
+frontends/verilog/ in the Yosys source tree.
+
+The Verilog preprocessor
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Verilog preprocessor scans over the Verilog source code and
+interprets some of the Verilog compiler directives such as
+:literal:`\`include`, :literal:`\`define` and :literal:`\`ifdef`.
+
+It is implemented as a C++ function that is passed a file descriptor as
+input and returns the pre-processed Verilog code as a ``std::string``.
+
+The source code to the Verilog Preprocessor can be found in
+frontends/verilog/preproc.cc in the Yosys source tree.
+
+The Verilog lexer
+~~~~~~~~~~~~~~~~~
+
+The Verilog Lexer is written using the lexer generator flex . Its source
+code can be found in frontends/verilog/verilog_lexer.l in the Yosys
+source tree. The lexer does little more than identifying all keywords
+and literals recognised by the Yosys Verilog frontend.
+
+The lexer keeps track of the current location in the Verilog source code
+using some global variables. These variables are used by the constructor
+of AST nodes to annotate each node with the source code location it
+originated from.
+
+Finally the lexer identifies and handles special comments such as
+"``// synopsys translate_off``" and "``// synopsys full_case``". (It is
+recommended to use :literal:`\`ifdef` constructs instead of the
+Synsopsys translate_on/off comments and attributes such as
+``(* full_case *)`` over "``// synopsys full_case``" whenever possible.)
+
+The Verilog parser
+~~~~~~~~~~~~~~~~~~
+
+The Verilog Parser is written using the parser generator bison . Its
+source code can be found in frontends/verilog/verilog_parser.y in the
+Yosys source tree.
+
+It generates an AST using the ``AST::AstNode`` data structure defined in
+frontends/ast/ast.h. An ``AST::AstNode`` object has the following
+properties:
+
+.. list-table:: AST node types with their corresponding Verilog constructs.
+ :name: tab:Verilog_AstNodeType
+ :widths: 50 50
+
+ * - AST Node Type
+ - Corresponding Verilog Construct
+ * - AST_NONE
+ - This Node type should never be used.
+ * - AST_DESIGN
+ - This node type is used for the top node of the AST tree. It has no corresponding Verilog construct.
+ * - AST_MODULE, AST_TASK, AST_FUNCTION
+ - ``module``, ``task`` and ``function``
+ * - AST_WIRE
+ - ``input``, ``output``, ``wire``, ``reg`` and ``integer``
+ * - AST_MEMORY
+ - Verilog Arrays
+ * - AST_AUTOWIRE
+ - Created by the simplifier when an undeclared signal name is used.
+ * - AST_PARAMETER, AST_LOCALPARAM
+ - ``parameter`` and ``localparam``
+ * - AST_PARASET
+ - Parameter set in cell instantiation
+ * - AST_ARGUMENT
+ - Port connection in cell instantiation
+ * - AST_RANGE
+ - Bit-Index in a signal or element index in array
+ * - AST_CONSTANT
+ - A literal value
+ * - AST_CELLTYPE
+ - The type of cell in cell instantiation
+ * - AST_IDENTIFIER
+ - An Identifier (signal name in expression or cell/task/etc. name in other contexts)
+ * - AST_PREFIX
+ - Construct an identifier in the form <prefix>[<index>].<suffix> (used only in advanced generate constructs)
+ * - AST_FCALL, AST_TCALL
+ - Call to function or task
+ * - AST_TO_SIGNED, AST_TO_UNSIGNED
+ - The ``$signed()`` and ``$unsigned()`` functions
+ * - AST_CONCAT, AST_REPLICATE
+ - The ``{...}`` and ``{...{...}}`` operators
+ * - AST_BIT_NOT, AST_BIT_AND, AST_BIT_OR, AST_BIT_XOR, AST_BIT_XNOR
+ - The bitwise operators ``~``, ``&``, ``|``, ``^`` and ``~^``
+ * - AST_REDUCE_AND, AST_REDUCE_OR, AST_REDUCE_XOR, AST_REDUCE_XNOR
+ - The unary reduction operators ``~``, ``&``, ``|``, ``^`` and ``~^``
+ * - AST_REDUCE_BOOL
+ - Conversion from multi-bit value to boolean value (equivalent to AST_REDUCE_OR)
+ * - AST_SHIFT_LEFT, AST_SHIFT_RIGHT, AST_SHIFT_SLEFT, AST_SHIFT_SRIGHT
+ - The shift operators ``<<``, ``>>``, ``<<<`` and ``>>>``
+ * - AST_LT, AST_LE, AST_EQ, AST_NE, AST_GE, AST_GT
+ - The relational operators ``<``, ``<=``, ``==``, ``!=``, ``>=`` and ``>``
+ * - AST_ADD, AST_SUB, AST_MUL, AST_DIV, AST_MOD, AST_POW
+ - The binary operators ``+``, ``-``, ``*``, ``/``, ``%`` and ``**``
+ * - AST_POS, AST_NEG
+ - The prefix operators ``+`` and ``-``
+ * - AST_LOGIC_AND, AST_LOGIC_OR, AST_LOGIC_NOT
+ - The logic operators ``&&``, ``||`` and ``!``
+ * - AST_TERNARY
+ - The ternary ``?:``-operator
+ * - AST_MEMRD AST_MEMWR
+ - Read and write memories. These nodes are generated by the AST simplifier for writes/reads to/from Verilog arrays.
+ * - AST_ASSIGN
+ - An ``assign`` statement
+ * - AST_CELL
+ - A cell instantiation
+ * - AST_PRIMITIVE
+ - A primitive cell (``and``, ``nand``, ``or``, etc.)
+ * - AST_ALWAYS, AST_INITIAL
+ - Verilog ``always``- and ``initial``-blocks
+ * - AST_BLOCK
+ - A ``begin``-``end``-block
+ * - AST_ASSIGN_EQ. AST_ASSIGN_LE
+ - Blocking (``=``) and nonblocking (``<=``) assignments within an ``always``- or ``initial``-block
+ * - AST_CASE. AST_COND, AST_DEFAULT
+ - The ``case`` (``if``) statements, conditions within a case and the default case respectively
+ * - AST_FOR
+ - A ``for``-loop with an ``always``- or ``initial``-block
+ * - AST_GENVAR, AST_GENBLOCK, AST_GENFOR, AST_GENIF
+ - The ``genvar`` and ``generate`` keywords and ``for`` and ``if`` within a generate block.
+ * - AST_POSEDGE, AST_NEGEDGE, AST_EDGE
+ - Event conditions for ``always`` blocks.
+
+- | The node type
+ | This enum (``AST::AstNodeType``) specifies the role of the node.
+ :numref:`Table %s <tab:Verilog_AstNodeType>`
+ contains a list of all node types.
+
+- | The child nodes
+ | This is a list of pointers to all children in the abstract syntax
+ tree.
+
+- | Attributes
+ | As almost every AST node might have Verilog attributes assigned to
+ it, the ``AST::AstNode`` has direct support for attributes. Note
+ that the attribute values are again AST nodes.
+
+- | Node content
+ | Each node might have additional content data. A series of member
+ variables exist to hold such data. For example the member
+ ``std::string str`` can hold a string value and is used e.g. in the
+ AST_IDENTIFIER node type to store the identifier name.
+
+- | Source code location
+ | Each ``AST::AstNode`` is automatically annotated with the current
+ source code location by the ``AST::AstNode`` constructor. It is
+ stored in the ``std::string filename`` and ``int linenum`` member
+ variables.
+
+The ``AST::AstNode`` constructor can be called with up to two child
+nodes that are automatically added to the list of child nodes for the
+new object. This simplifies the creation of AST nodes for simple
+expressions a bit. For example the bison code for parsing
+multiplications:
+
+.. code:: none
+ :number-lines:
+
+ basic_expr '*' attr basic_expr {
+ $$ = new AstNode(AST_MUL, $1, $4);
+ append_attr($$, $3);
+ } |
+
+The generated AST data structure is then passed directly to the AST
+frontend that performs the actual conversion to RTLIL.
+
+Note that the Yosys command ``read_verilog`` provides the options ``-yydebug``
+and ``-dump_ast`` that can be used to print the parse tree or abstract
+syntax tree respectively.
+
+Transforming AST to RTLIL
+-------------------------
+
+The AST Frontend converts a set of modules in AST representation to
+modules in RTLIL representation and adds them to the current design.
+This is done in two steps: simplification and RTLIL generation.
+
+The source code to the AST frontend can be found in ``frontends/ast/`` in
+the Yosys source tree.
+
+AST simplification
+~~~~~~~~~~~~~~~~~~
+
+A full-featured AST is too complex to be transformed into RTLIL
+directly. Therefore it must first be brought into a simpler form. This
+is done by calling the ``AST::AstNode::simplify()`` method of all
+AST_MODULE nodes in the AST. This initiates a recursive process that
+performs the following transformations on the AST data structure:
+
+- Inline all task and function calls.
+
+- Evaluate all ``generate``-statements and unroll all ``for``-loops.
+
+- Perform const folding where it is necessary (e.g. in the value part
+ of AST_PARAMETER, AST_LOCALPARAM, AST_PARASET and AST_RANGE nodes).
+
+- Replace AST_PRIMITIVE nodes with appropriate AST_ASSIGN nodes.
+
+- Replace dynamic bit ranges in the left-hand-side of assignments with
+ AST_CASE nodes with AST_COND children for each possible case.
+
+- Detect array access patterns that are too complicated for the
+ RTLIL::Memory abstraction and replace them with a set of signals and
+ cases for all reads and/or writes.
+
+- Otherwise replace array accesses with AST_MEMRD and AST_MEMWR nodes.
+
+In addition to these transformations, the simplifier also annotates the
+AST with additional information that is needed for the RTLIL generator,
+namely:
+
+- All ranges (width of signals and bit selections) are not only const
+ folded but (when a constant value is found) are also written to
+ member variables in the AST_RANGE node.
+
+- All identifiers are resolved and all AST_IDENTIFIER nodes are
+ annotated with a pointer to the AST node that contains the
+ declaration of the identifier. If no declaration has been found, an
+ AST_AUTOWIRE node is created and used for the annotation.
+
+This produces an AST that is fairly easy to convert to the RTLIL format.
+
+Generating RTLIL
+~~~~~~~~~~~~~~~~
+
+After AST simplification, the ``AST::AstNode::genRTLIL()`` method of
+each AST_MODULE node in the AST is called. This initiates a recursive
+process that generates equivalent RTLIL data for the AST data.
+
+The ``AST::AstNode::genRTLIL()`` method returns an ``RTLIL::SigSpec``
+structure. For nodes that represent expressions (operators, constants,
+signals, etc.), the cells needed to implement the calculation described
+by the expression are created and the resulting signal is returned. That
+way it is easy to generate the circuits for large expressions using
+depth-first recursion. For nodes that do not represent an expression
+(such as AST_CELL), the corresponding circuit is generated and an empty
+``RTLIL::SigSpec`` is returned.
+
+Synthesizing Verilog always blocks
+--------------------------------------
+
+For behavioural Verilog code (code utilizing ``always``- and
+``initial``-blocks) it is necessary to also generate ``RTLIL::Process``
+objects. This is done in the following way:
+
+Whenever ``AST::AstNode::genRTLIL()`` encounters an ``always``- or
+``initial``-block, it creates an instance of
+``AST_INTERNAL::ProcessGenerator``. This object then generates the
+``RTLIL::Process`` object for the block. It also calls
+``AST::AstNode::genRTLIL()`` for all right-hand-side expressions
+contained within the block.
+
+First the ``AST_INTERNAL::ProcessGenerator`` creates a list of all
+signals assigned within the block. It then creates a set of temporary
+signals using the naming scheme $\ <number> \\\ <original_name> for each
+of the assigned signals.
+
+Then an ``RTLIL::Process`` is created that assigns all intermediate
+values for each left-hand-side signal to the temporary signal in its
+``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree.
+
+Finally a ``RTLIL::SyncRule`` is created for the ``RTLIL::Process`` that
+assigns the temporary signals for the final values to the actual
+signals.
+
+A process may also contain memory writes. A ``RTLIL::MemWriteAction`` is
+created for each of them.
+
+Calls to ``AST::AstNode::genRTLIL()`` are generated for right hand sides
+as needed. When blocking assignments are used,
+``AST::AstNode::genRTLIL()`` is configured using global variables to use
+the temporary signals that hold the correct intermediate values whenever
+one of the previously assigned signals is used in an expression.
+
+Unfortunately the generation of a correct
+``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree for behavioural code is a
+non-trivial task. The AST frontend solves the problem using the approach
+described on the following pages. The following example illustrates what
+the algorithm is supposed to do. Consider the following Verilog code:
+
+.. code:: verilog
+ :number-lines:
+
+ always @(posedge clock) begin
+ out1 = in1;
+ if (in2)
+ out1 = !out1;
+ out2 <= out1;
+ if (in3)
+ out2 <= out2;
+ if (in4)
+ if (in5)
+ out3 <= in6;
+ else
+ out3 <= in7;
+ out1 = out1 ^ out2;
+ end
+
+This is translated by the Verilog and AST frontends into the following
+RTLIL code (attributes, cell parameters and wire declarations not
+included):
+
+.. code:: RTLIL
+ :number-lines:
+
+ cell $logic_not $logic_not$<input>:4$2
+ connect \A \in1
+ connect \Y $logic_not$<input>:4$2_Y
+ end
+ cell $xor $xor$<input>:13$3
+ connect \A $1\out1[0:0]
+ connect \B \out2
+ connect \Y $xor$<input>:13$3_Y
+ end
+ process $proc$<input>:1$1
+ assign $0\out3[0:0] \out3
+ assign $0\out2[0:0] $1\out1[0:0]
+ assign $0\out1[0:0] $xor$<input>:13$3_Y
+ switch \in2
+ case 1'1
+ assign $1\out1[0:0] $logic_not$<input>:4$2_Y
+ case
+ assign $1\out1[0:0] \in1
+ end
+ switch \in3
+ case 1'1
+ assign $0\out2[0:0] \out2
+ case
+ end
+ switch \in4
+ case 1'1
+ switch \in5
+ case 1'1
+ assign $0\out3[0:0] \in6
+ case
+ assign $0\out3[0:0] \in7
+ end
+ case
+ end
+ sync posedge \clock
+ update \out1 $0\out1[0:0]
+ update \out2 $0\out2[0:0]
+ update \out3 $0\out3[0:0]
+ end
+
+Note that the two operators are translated into separate cells outside
+the generated process. The signal ``out1`` is assigned using blocking
+assignments and therefore ``out1`` has been replaced with a different
+signal in all expressions after the initial assignment. The signal
+``out2`` is assigned using nonblocking assignments and therefore is not
+substituted on the right-hand-side expressions.
+
+The ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree must be interpreted
+the following way:
+
+- On each case level (the body of the process is the root case), first
+ the actions on this level are evaluated and then the switches within
+ the case are evaluated. (Note that the last assignment on line 13 of
+ the Verilog code has been moved to the beginning of the RTLIL process
+ to line 13 of the RTLIL listing.)
+
+ I.e. the special cases deeper in the switch hierarchy override the
+ defaults on the upper levels. The assignments in lines 12 and 22 of
+ the RTLIL code serve as an example for this.
+
+ Note that in contrast to this, the order within the
+ ``RTLIL::SwitchRule`` objects within a ``RTLIL::CaseRule`` is
+ preserved with respect to the original AST and Verilog code.
+
+- The whole ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree describes an
+ asynchronous circuit. I.e. the decision tree formed by the switches
+ can be seen independently for each assigned signal. Whenever one
+ assigned signal changes, all signals that depend on the changed
+ signals are to be updated. For example the assignments in lines 16
+ and 18 in the RTLIL code in fact influence the assignment in line 12,
+ even though they are in the "wrong order".
+
+The only synchronous part of the process is in the ``RTLIL::SyncRule``
+object generated at line 35 in the RTLIL code. The sync rule is the only
+part of the process where the original signals are assigned. The
+synchronization event from the original Verilog code has been translated
+into the synchronization type (posedge) and signal (\\clock) for the
+``RTLIL::SyncRule`` object. In the case of this simple example the
+``RTLIL::SyncRule`` object is later simply transformed into a set of
+d-type flip-flops and the ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree
+to a decision tree using multiplexers.
+
+In more complex examples (e.g. asynchronous resets) the part of the
+``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree that describes the
+asynchronous reset must first be transformed to the correct
+``RTLIL::SyncRule`` objects. This is done by the proc_adff pass.
+
+The ProcessGenerator algorithm
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``AST_INTERNAL::ProcessGenerator`` uses the following internal state
+variables:
+
+- | ``subst_rvalue_from`` and ``subst_rvalue_to``
+ | These two variables hold the replacement pattern that should be
+ used by ``AST::AstNode::genRTLIL()`` for signals with blocking
+ assignments. After initialization of
+ ``AST_INTERNAL::ProcessGenerator`` these two variables are empty.
+
+- | ``subst_lvalue_from`` and ``subst_lvalue_to``
+ | These two variables contain the mapping from left-hand-side signals
+ (\\\ <name>) to the current temporary signal for the same thing
+ (initially $0\\\ <name>).
+
+- | ``current_case``
+ | A pointer to a ``RTLIL::CaseRule`` object. Initially this is the
+ root case of the generated ``RTLIL::Process``.
+
+As the algorithm runs these variables are continuously modified as well
+as pushed to the stack and later restored to their earlier values by
+popping from the stack.
+
+On startup the ProcessGenerator generates a new ``RTLIL::Process``
+object with an empty root case and initializes its state variables as
+described above. Then the ``RTLIL::SyncRule`` objects are created using
+the synchronization events from the AST_ALWAYS node and the initial
+values of ``subst_lvalue_from`` and ``subst_lvalue_to``. Then the AST
+for this process is evaluated recursively.
+
+During this recursive evaluation, three different relevant types of AST
+nodes can be discovered: AST_ASSIGN_LE (nonblocking assignments),
+AST_ASSIGN_EQ (blocking assignments) and AST_CASE (``if`` or ``case``
+statement).
+
+Handling of nonblocking assignments
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When an AST_ASSIGN_LE node is discovered, the following actions are
+performed by the ProcessGenerator:
+
+- The left-hand-side is evaluated using ``AST::AstNode::genRTLIL()``
+ and mapped to a temporary signal name using ``subst_lvalue_from`` and
+ ``subst_lvalue_to``.
+
+- The right-hand-side is evaluated using ``AST::AstNode::genRTLIL()``.
+ For this call, the values of ``subst_rvalue_from`` and
+ ``subst_rvalue_to`` are used to map blocking-assigned signals
+ correctly.
+
+- Remove all assignments to the same left-hand-side as this assignment
+ from the ``current_case`` and all cases within it.
+
+- Add the new assignment to the ``current_case``.
+
+Handling of blocking assignments
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When an AST_ASSIGN_EQ node is discovered, the following actions are
+performed by the ProcessGenerator:
+
+- Perform all the steps that would be performed for a nonblocking
+ assignment (see above).
+
+- Remove the found left-hand-side (before lvalue mapping) from
+ ``subst_rvalue_from`` and also remove the respective bits from
+ ``subst_rvalue_to``.
+
+- Append the found left-hand-side (before lvalue mapping) to
+ ``subst_rvalue_from`` and append the found right-hand-side to
+ ``subst_rvalue_to``.
+
+Handling of cases and if-statements
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When an AST_CASE node is discovered, the following actions are performed
+by the ProcessGenerator:
+
+- The values of ``subst_rvalue_from``, ``subst_rvalue_to``,
+ ``subst_lvalue_from`` and ``subst_lvalue_to`` are pushed to the
+ stack.
+
+- A new ``RTLIL::SwitchRule`` object is generated, the selection
+ expression is evaluated using ``AST::AstNode::genRTLIL()`` (with the
+ use of ``subst_rvalue_from`` and ``subst_rvalue_to``) and added to
+ the ``RTLIL::SwitchRule`` object and the object is added to the
+ ``current_case``.
+
+- All lvalues assigned to within the AST_CASE node using blocking
+ assignments are collected and saved in the local variable
+ ``this_case_eq_lvalue``.
+
+- New temporary signals are generated for all signals in
+ ``this_case_eq_lvalue`` and stored in ``this_case_eq_ltemp``.
+
+- The signals in ``this_case_eq_lvalue`` are mapped using
+ ``subst_rvalue_from`` and ``subst_rvalue_to`` and the resulting set
+ of signals is stored in ``this_case_eq_rvalue``.
+
+Then the following steps are performed for each AST_COND node within the
+AST_CASE node:
+
+- Set ``subst_rvalue_from``, ``subst_rvalue_to``, ``subst_lvalue_from``
+ and ``subst_lvalue_to`` to the values that have been pushed to the
+ stack.
+
+- Remove ``this_case_eq_lvalue`` from
+ ``subst_lvalue_from``/``subst_lvalue_to``.
+
+- Append ``this_case_eq_lvalue`` to ``subst_lvalue_from`` and append
+ ``this_case_eq_ltemp`` to ``subst_lvalue_to``.
+
+- Push the value of ``current_case``.
+
+- Create a new ``RTLIL::CaseRule``. Set ``current_case`` to the new
+ object and add the new object to the ``RTLIL::SwitchRule`` created
+ above.
+
+- Add an assignment from ``this_case_eq_rvalue`` to
+ ``this_case_eq_ltemp`` to the new ``current_case``.
+
+- Evaluate the compare value for this case using
+ ``AST::AstNode::genRTLIL()`` (with the use of ``subst_rvalue_from``
+ and ``subst_rvalue_to``) modify the new ``current_case`` accordingly.
+
+- Recursion into the children of the AST_COND node.
+
+- Restore ``current_case`` by popping the old value from the stack.
+
+Finally the following steps are performed:
+
+- The values of ``subst_rvalue_from``, ``subst_rvalue_to``,
+ ``subst_lvalue_from`` and ``subst_lvalue_to`` are popped from the
+ stack.
+
+- The signals from ``this_case_eq_lvalue`` are removed from the
+ ``subst_rvalue_from``/``subst_rvalue_to``-pair.
+
+- The value of ``this_case_eq_lvalue`` is appended to
+ ``subst_rvalue_from`` and the value of ``this_case_eq_ltemp`` is
+ appended to ``subst_rvalue_to``.
+
+- Map the signals in ``this_case_eq_lvalue`` using
+ ``subst_lvalue_from``/``subst_lvalue_to``.
+
+- Remove all assignments to signals in ``this_case_eq_lvalue`` in
+ ``current_case`` and all cases within it.
+
+- Add an assignment from ``this_case_eq_ltemp`` to
+ ``this_case_eq_lvalue`` to ``current_case``.
+
+Further analysis of the algorithm for cases and if-statements
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+With respect to nonblocking assignments the algorithm is easy: later
+assignments invalidate earlier assignments. For each signal assigned
+using nonblocking assignments exactly one temporary variable is
+generated (with the $0-prefix) and this variable is used for all
+assignments of the variable.
+
+Note how all the ``_eq_``-variables become empty when no blocking
+assignments are used and many of the steps in the algorithm can then be
+ignored as a result of this.
+
+For a variable with blocking assignments the algorithm shows the
+following behaviour: First a new temporary variable is created. This new
+temporary variable is then registered as the assignment target for all
+assignments for this variable within the cases for this AST_CASE node.
+Then for each case the new temporary variable is first assigned the old
+temporary variable. This assignment is overwritten if the variable is
+actually assigned in this case and is kept as a default value otherwise.
+
+This yields an ``RTLIL::CaseRule`` that assigns the new temporary
+variable in all branches. So when all cases have been processed a final
+assignment is added to the containing block that assigns the new
+temporary variable to the old one. Note how this step always overrides a
+previous assignment to the old temporary variable. Other than
+nonblocking assignments, the old assignment could still have an effect
+somewhere in the design, as there have been calls to
+``AST::AstNode::genRTLIL()`` with a
+``subst_rvalue_from``/``subst_rvalue_to``-tuple that contained the
+right-hand-side of the old assignment.
+
+The proc pass
+~~~~~~~~~~~~~
+
+The ProcessGenerator converts a behavioural model in AST representation
+to a behavioural model in ``RTLIL::Process`` representation. The actual
+conversion from a behavioural model to an RTL representation is
+performed by the proc pass and the passes it launches:
+
+- | proc_clean and proc_rmdead
+ | These two passes just clean up the ``RTLIL::Process`` structure.
+ The proc_clean pass removes empty parts (eg. empty assignments)
+ from the process and proc_rmdead detects and removes unreachable
+ branches from the process's decision trees.
+
+- | proc_arst
+ | This pass detects processes that describe d-type flip-flops with
+ asynchronous resets and rewrites the process to better reflect what
+ they are modelling: Before this pass, an asynchronous reset has two
+ edge-sensitive sync rules and one top-level for the reset path.
+ After this pass the sync rule for the reset is level-sensitive and
+ the top-level has been removed.
+
+- | proc_mux
+ | This pass converts the /-tree to a tree of multiplexers per written
+ signal. After this, the structure only contains the s that describe
+ the output registers.
+
+- | proc_dff
+ | This pass replaces the s to d-type flip-flops (with asynchronous
+ resets if necessary).
+
+- | proc_dff
+ | This pass replaces the s with $memwr cells.
+
+- | proc_clean
+ | A final call to proc_clean removes the now empty objects.
+
+Performing these last processing steps in passes instead of in the
+Verilog frontend has two important benefits:
+
+First it improves the transparency of the process. Everything that
+happens in a separate pass is easier to debug, as the RTLIL data
+structures can be easily investigated before and after each of the
+steps.
+
+Second it improves flexibility. This scheme can easily be extended to
+support other types of storage-elements, such as sr-latches or
+d-latches, without having to extend the actual Verilog frontend.
+
+Synthesizing Verilog arrays
+---------------------------
+
+Add some information on the generation of $memrd and $memwr cells and
+how they are processed in the memory pass.
+
+Synthesizing parametric designs
+-------------------------------
+
+Add some information on the ``RTLIL::Module::derive()`` method and how
+it is used to synthesize parametric modules via the hierarchy pass.