Docs: Move binary operators to cell appendix

Add binary group tag to relevant cells.
Remove content from `cell_library.rst` that is already moved.
This commit is contained in:
Krystine Sherwin 2024-05-27 12:31:42 +12:00
parent b127ac07f8
commit c662529316
No known key found for this signature in database
4 changed files with 133 additions and 152 deletions

View File

@ -0,0 +1,91 @@
.. role:: verilog(code)
:language: Verilog
Binary operators
~~~~~~~~~~~~~~~~
All binary RTL cells have two input ports ``A`` and ``B`` and one output port
``Y``. They also have the following parameters:
``A_SIGNED``
Set to a non-zero value if the input ``A`` is signed and therefore should be
sign-extended when needed.
``A_WIDTH``
The width of the input port ``A``.
``B_SIGNED``
Set to a non-zero value if the input ``B`` is signed and therefore should be
sign-extended when needed.
``B_WIDTH``
The width of the input port ``B``.
``Y_WIDTH``
The width of the output port ``Y``.
.. table:: Cell types for binary operators with their corresponding Verilog expressions.
======================= =============== ======================= ===========
Verilog Cell Type Verilog Cell Type
======================= =============== ======================= ===========
:verilog:`Y = A & B` `$and` :verilog:`Y = A ** B` `$pow`
:verilog:`Y = A | B` `$or` :verilog:`Y = A < B` `$lt`
:verilog:`Y = A ^ B` `$xor` :verilog:`Y = A <= B` `$le`
:verilog:`Y = A ~^ B` `$xnor` :verilog:`Y = A == B` `$eq`
:verilog:`Y = A << B` `$shl` :verilog:`Y = A != B` `$ne`
:verilog:`Y = A >> B` `$shr` :verilog:`Y = A >= B` `$ge`
:verilog:`Y = A <<< B` `$sshl` :verilog:`Y = A > B` `$gt`
:verilog:`Y = A >>> B` `$sshr` :verilog:`Y = A + B` `$add`
:verilog:`Y = A && B` `$logic_and` :verilog:`Y = A - B` `$sub`
:verilog:`Y = A || B` `$logic_or` :verilog:`Y = A * B` `$mul`
:verilog:`Y = A === B` `$eqx` :verilog:`Y = A / B` `$div`
:verilog:`Y = A !== B` `$nex` :verilog:`Y = A % B` `$mod`
``N/A`` `$shift` ``N/A`` `$divfloor`
``N/A`` `$shiftx` ``N/A`` `$modfloor`
======================= =============== ======================= ===========
The `$shl` and `$shr` cells implement logical shifts, whereas the `$sshl` and
`$sshr` cells implement arithmetic shifts. The `$shl` and `$sshl` cells
implement the same operation. All four of these cells interpret the second
operand as unsigned, and require ``B_SIGNED`` to be zero.
Two additional shift operator cells are available that do not directly
correspond to any operator in Verilog, `$shift` and `$shiftx`. The `$shift` cell
performs a right logical shift if the second operand is positive (or unsigned),
and a left logical shift if it is negative. The `$shiftx` cell performs the same
operation as the `$shift` cell, but the vacated bit positions are filled with
undef (x) bits, and corresponds to the Verilog indexed part-select expression.
For the binary cells that output a logical value (`$logic_and`, `$logic_or`,
`$eqx`, `$nex`, `$lt`, `$le`, `$eq`, `$ne`, `$ge`, `$gt`), when the ``Y_WIDTH``
parameter is greater than 1, the output is zero-extended, and only the least
significant bit varies.
Division and modulo cells are available in two rounding modes. The original
`$div` and `$mod` cells are based on truncating division, and correspond to the
semantics of the verilog ``/`` and ``%`` operators. The `$divfloor` and
`$modfloor` cells represent flooring division and flooring modulo, the latter of
which is also known as "remainder" in several languages. See the following table
for a side-by-side comparison between the different semantics.
.. table:: Comparison between different rounding modes for division and modulo cells.
+-----------+--------+-----------+-----------+-----------+-----------+
| Division | Result | Truncating | Flooring |
+-----------+--------+-----------+-----------+-----------+-----------+
| | | $div | $mod | $divfloor | $modfloor |
+===========+========+===========+===========+===========+===========+
| -10 / 3 | -3.3 | -3 | -1 | -4 | 2 |
+-----------+--------+-----------+-----------+-----------+-----------+
| 10 / -3 | -3.3 | -3 | 1 | -4 | -2 |
+-----------+--------+-----------+-----------+-----------+-----------+
| -10 / -3 | 3.3 | 3 | -1 | 3 | -1 |
+-----------+--------+-----------+-----------+-----------+-----------+
| 10 / 3 | 3.3 | 3 | 1 | 3 | 1 |
+-----------+--------+-----------+-----------+-----------+-----------+
.. autocellgroup:: binary
:members:
:source:
:linenos:

View File

@ -1,9 +1,22 @@
Word-level cells
----------------
Most of the RTL cells closely resemble the operators available in HDLs such as
Verilog or VHDL. Therefore Verilog operators are used in the following sections
to define the behaviour of the RTL cells.
Note that all RTL cells have parameters indicating the size of inputs and
outputs. When passes modify RTL cells they must always keep the values of these
parameters in sync with the size of the signals connected to the inputs and
outputs.
Simulation models for the RTL cells can be found in the file
:file:`techlibs/common/simlib.v` in the Yosys source tree.
.. toctree::
:maxdepth: 2
:glob:
/cell/word_unary
/cell/word_binary
/cell/word_other

View File

@ -13,8 +13,6 @@ Most of the passes in Yosys operate on netlists, i.e. they only care about the
chapter discusses the cell types used by Yosys to represent a behavioural design
internally.
.. TODO:: is this chapter split preserved
This chapter is split in two parts. In the first part the internal RTL cells are
covered. These cells are used to represent the design on a coarse grain level.
Like in the original HDL code on this level the cells operate on vectors of
@ -23,155 +21,6 @@ gate cells are covered. These cells are used to represent the design on a
fine-grain gate-level. All cells from this category operate on single bit
signals.
RTL cells
---------
Most of the RTL cells closely resemble the operators available in HDLs such as
Verilog or VHDL. Therefore Verilog operators are used in the following sections
to define the behaviour of the RTL cells.
Note that all RTL cells have parameters indicating the size of inputs and
outputs. When passes modify RTL cells they must always keep the values of these
parameters in sync with the size of the signals connected to the inputs and
outputs.
Simulation models for the RTL cells can be found in the file
:file:`techlibs/common/simlib.v` in the Yosys source tree.
Unary operators
~~~~~~~~~~~~~~~
All unary RTL cells have one input port ``\A`` and one output port ``\Y``. They
also have the following parameters:
``\A_SIGNED``
Set to a non-zero value if the input ``\A`` is signed and therefore should be
sign-extended when needed.
``\A_WIDTH``
The width of the input port ``\A``.
``\Y_WIDTH``
The width of the output port ``\Y``.
:numref:`tab:CellLib_unary` lists all cells for unary RTL operators.
.. table:: Cell types for unary operators with their corresponding Verilog expressions.
:name: tab:CellLib_unary
================== ============
Verilog Cell Type
================== ============
:verilog:`Y = ~A` $not
:verilog:`Y = +A` $pos
:verilog:`Y = -A` $neg
:verilog:`Y = &A` $reduce_and
:verilog:`Y = |A` $reduce_or
:verilog:`Y = ^A` $reduce_xor
:verilog:`Y = ~^A` $reduce_xnor
:verilog:`Y = |A` $reduce_bool
:verilog:`Y = !A` $logic_not
================== ============
For the unary cells that output a logical value (`$reduce_and`, `$reduce_or`,
`$reduce_xor`, `$reduce_xnor`, `$reduce_bool`, `$logic_not`), when the
``\Y_WIDTH`` parameter is greater than 1, the output is zero-extended, and only
the least significant bit varies.
Note that `$reduce_or` and `$reduce_bool` actually represent the same logic
function. But the HDL frontends generate them in different situations. A
`$reduce_or` cell is generated when the prefix ``|`` operator is being used. A
`$reduce_bool` cell is generated when a bit vector is used as a condition in an
``if``-statement or ``?:``-expression.
Binary operators
~~~~~~~~~~~~~~~~
All binary RTL cells have two input ports ``\A`` and ``\B`` and one output port
``\Y``. They also have the following parameters:
``\A_SIGNED``
Set to a non-zero value if the input ``\A`` is signed and therefore should be
sign-extended when needed.
``\A_WIDTH``
The width of the input port ``\A``.
``\B_SIGNED``
Set to a non-zero value if the input ``\B`` is signed and therefore should be
sign-extended when needed.
``\B_WIDTH``
The width of the input port ``\B``.
``\Y_WIDTH``
The width of the output port ``\Y``.
:numref:`tab:CellLib_binary` lists all cells for binary RTL operators.
.. table:: Cell types for binary operators with their corresponding Verilog expressions.
:name: tab:CellLib_binary
======================= ============= ======================= =========
Verilog Cell Type Verilog Cell Type
======================= ============= ======================= =========
:verilog:`Y = A & B` $and :verilog:`Y = A < B` $lt
:verilog:`Y = A | B` $or :verilog:`Y = A <= B` $le
:verilog:`Y = A ^ B` $xor :verilog:`Y = A == B` $eq
:verilog:`Y = A ~^ B` $xnor :verilog:`Y = A != B` $ne
:verilog:`Y = A << B` $shl :verilog:`Y = A >= B` $ge
:verilog:`Y = A >> B` $shr :verilog:`Y = A > B` $gt
:verilog:`Y = A <<< B` $sshl :verilog:`Y = A + B` $add
:verilog:`Y = A >>> B` $sshr :verilog:`Y = A - B` $sub
:verilog:`Y = A && B` $logic_and :verilog:`Y = A * B` $mul
:verilog:`Y = A || B` $logic_or :verilog:`Y = A / B` $div
:verilog:`Y = A === B` $eqx :verilog:`Y = A % B` $mod
:verilog:`Y = A !== B` $nex ``N/A`` $divfloor
:verilog:`Y = A ** B` $pow ``N/A`` $modfloor
======================= ============= ======================= =========
The `$shl` and `$shr` cells implement logical shifts, whereas the `$sshl` and
`$sshr` cells implement arithmetic shifts. The `$shl` and `$sshl` cells
implement the same operation. All four of these cells interpret the second
operand as unsigned, and require ``\B_SIGNED`` to be zero.
Two additional shift operator cells are available that do not directly
correspond to any operator in Verilog, `$shift` and `$shiftx`. The `$shift` cell
performs a right logical shift if the second operand is positive (or unsigned),
and a left logical shift if it is negative. The `$shiftx` cell performs the same
operation as the `$shift` cell, but the vacated bit positions are filled with
undef (x) bits, and corresponds to the Verilog indexed part-select expression.
For the binary cells that output a logical value (`$logic_and`, `$logic_or`,
`$eqx`, `$nex`, `$lt`, `$le`, `$eq`, `$ne`, `$ge`, `$gt`), when the ``\Y_WIDTH``
parameter is greater than 1, the output is zero-extended, and only the least
significant bit varies.
Division and modulo cells are available in two rounding modes. The original
`$div` and `$mod` cells are based on truncating division, and correspond to the
semantics of the verilog ``/`` and ``%`` operators. The `$divfloor` and
`$modfloor` cells represent flooring division and flooring modulo, the latter of
which is also known as "remainder" in several languages. See
:numref:`tab:CellLib_divmod` for a side-by-side comparison between the different
semantics.
.. table:: Comparison between different rounding modes for division and modulo cells.
:name: tab:CellLib_divmod
+-----------+--------+-----------+-----------+-----------+-----------+
| Division | Result | Truncating | Flooring |
+-----------+--------+-----------+-----------+-----------+-----------+
| | | $div | $mod | $divfloor | $modfloor |
+===========+========+===========+===========+===========+===========+
| -10 / 3 | -3.3 | -3 | -1 | -4 | 2 |
+-----------+--------+-----------+-----------+-----------+-----------+
| 10 / -3 | -3.3 | -3 | 1 | -4 | -2 |
+-----------+--------+-----------+-----------+-----------+-----------+
| -10 / -3 | 3.3 | 3 | -1 | 3 | -1 |
+-----------+--------+-----------+-----------+-----------+-----------+
| 10 / 3 | 3.3 | 3 | 1 | 3 | 1 |
+-----------+--------+-----------+-----------+-----------+-----------+
Multiplexers
~~~~~~~~~~~~

View File

@ -139,6 +139,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $and (A, B, Y)
//* group binary
//-
//- A bit-wise AND. This corresponds to the Verilog '&' operator.
//-
@ -169,6 +170,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $or (A, B, Y)
//* group binary
//-
//- A bit-wise OR. This corresponds to the Verilog '|' operator.
//-
@ -199,6 +201,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $xor (A, B, Y)
//* group binary
//-
//- A bit-wise XOR. This corresponds to the Verilog '^' operator.
//-
@ -229,6 +232,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $xnor (A, B, Y)
//* group binary
//-
//- A bit-wise XNOR. This corresponds to the Verilog '~^' operator.
//-
@ -400,6 +404,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $shl (A, B, Y)
//* group binary
//-
//- A logical shift-left operation. This corresponds to the Verilog '<<' operator.
//-
@ -430,6 +435,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $shr (A, B, Y)
//* group binary
//-
//- A logical shift-right operation. This corresponds to the Verilog '>>' operator.
//-
@ -460,6 +466,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $sshl (A, B, Y)
//* group binary
//-
//- An arithmatic shift-left operation.
//- This corresponds to the Verilog '<<<' operator.
@ -491,6 +498,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $sshr (A, B, Y)
//* group binary
//-
//- An arithmatic shift-right operation.
//- This corresponds to the Verilog '>>>' operator.
@ -518,6 +526,7 @@ endgenerate
endmodule
// --------------------------------------------------------
//* group binary
module \$shift (A, B, Y);
@ -550,6 +559,7 @@ endgenerate
endmodule
// --------------------------------------------------------
//* group binary
module \$shiftx (A, B, Y);
@ -691,6 +701,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $lt (A, B, Y)
//* group binary
//-
//- A less-than comparison between inputs 'A' and 'B'.
//- This corresponds to the Verilog '<' operator.
@ -722,6 +733,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $le (A, B, Y)
//* group binary
//-
//- A less-than-or-equal-to comparison between inputs 'A' and 'B'.
//- This corresponds to the Verilog '<=' operator.
@ -753,6 +765,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $eq (A, B, Y)
//* group binary
//-
//- An equality comparison between inputs 'A' and 'B'.
//- This corresponds to the Verilog '==' operator.
@ -784,6 +797,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $ne (A, B, Y)
//* group binary
//-
//- An inequality comparison between inputs 'A' and 'B'.
//- This corresponds to the Verilog '!=' operator.
@ -815,6 +829,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $eqx (A, B, Y)
//* group binary
//-
//- An exact equality comparison between inputs 'A' and 'B'.
//- This corresponds to the Verilog '===' operator.
@ -848,6 +863,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $nex (A, B, Y)
//* group binary
//-
//- An exact inequality comparison between inputs 'A' and 'B'.
//- This corresponds to the Verilog '!==' operator.
@ -881,6 +897,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $ge (A, B, Y)
//* group binary
//-
//- A greater-than-or-equal-to comparison between inputs 'A' and 'B'.
//- This corresponds to the Verilog '>=' operator.
@ -912,6 +929,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $gt (A, B, Y)
//* group binary
//-
//- A greater-than comparison between inputs 'A' and 'B'.
//- This corresponds to the Verilog '>' operator.
@ -943,6 +961,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $add (A, B, Y)
//* group binary
//-
//- Addition of inputs 'A' and 'B'. This corresponds to the Verilog '+' operator.
//-
@ -973,6 +992,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $sub (A, B, Y)
//* group binary
//-
//- Subtraction between inputs 'A' and 'B'.
//- This corresponds to the Verilog '-' operator.
@ -1004,6 +1024,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $mul (A, B, Y)
//* group binary
//-
//- Multiplication of inputs 'A' and 'B'.
//- This corresponds to the Verilog '*' operator.
@ -1185,6 +1206,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $div (A, B, Y)
//* group binary
//-
//- Division with truncated result (rounded towards 0).
//-
@ -1215,6 +1237,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $mod (A, B, Y)
//* group binary
//-
//- Modulo/remainder of division with truncated result (rounded towards 0).
//-
@ -1247,6 +1270,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $divfloor (A, B, Y)
//* group binary
//-
//- Division with floored result (rounded towards negative infinity).
//-
@ -1284,6 +1308,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $modfloor (A, B, Y)
//* group binary
//-
//- Modulo/remainder of division with floored result (rounded towards negative infinity).
//-
@ -1324,6 +1349,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $pow (A, B, Y)
//* group binary
//-
//- Exponentiation of an input (Y = A ** B).
//- This corresponds to the Verilog '**' operator.
@ -1362,10 +1388,10 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $logic_not (A, Y)
//* group unary
//-
//- A logical inverter. This corresponds to the Verilog unary prefix '!' operator.
//-
//* group unary
module \$logic_not (A, Y);
parameter A_SIGNED = 0;
@ -1390,6 +1416,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $logic_and (A, B, Y)
//* group binary
//-
//- A logical AND. This corresponds to the Verilog '&&' operator.
//-
@ -1420,6 +1447,7 @@ endmodule
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $logic_or (A, B, Y)
//* group binary
//-
//- A logical OR. This corresponds to the Verilog '||' operator.
//-