diff --git a/docs/source/cell/word_binary.rst b/docs/source/cell/word_binary.rst new file mode 100644 index 00000000000..47a847ee446 --- /dev/null +++ b/docs/source/cell/word_binary.rst @@ -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: diff --git a/docs/source/cell_word.rst b/docs/source/cell_word.rst index 9b781132468..c23a4e1b15d 100644 --- a/docs/source/cell_word.rst +++ b/docs/source/cell_word.rst @@ -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 diff --git a/docs/source/yosys_internals/formats/cell_library.rst b/docs/source/yosys_internals/formats/cell_library.rst index fff12894ac6..c42802fb9a7 100644 --- a/docs/source/yosys_internals/formats/cell_library.rst +++ b/docs/source/yosys_internals/formats/cell_library.rst @@ -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 ~~~~~~~~~~~~ diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 142632660f9..da06820302b 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -119,6 +119,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. //- @@ -149,6 +150,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. //- @@ -179,6 +181,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. //- @@ -209,6 +212,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. //- @@ -377,6 +381,8 @@ endmodule // -------------------------------------------------------- +//* group binary + module \$shl (A, B, Y); parameter A_SIGNED = 0; @@ -400,6 +406,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$shr (A, B, Y); @@ -424,6 +431,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$sshl (A, B, Y); @@ -448,6 +456,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$sshr (A, B, Y); @@ -472,6 +481,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$shift (A, B, Y); @@ -504,6 +514,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$shiftx (A, B, Y); @@ -641,6 +652,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$lt (A, B, Y); @@ -665,6 +677,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$le (A, B, Y); @@ -689,6 +702,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$eq (A, B, Y); @@ -713,6 +727,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$ne (A, B, Y); @@ -737,6 +752,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$eqx (A, B, Y); @@ -761,6 +777,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$nex (A, B, Y); @@ -785,6 +802,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$ge (A, B, Y); @@ -809,6 +827,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$gt (A, B, Y); @@ -833,6 +852,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$add (A, B, Y); @@ -857,6 +877,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$sub (A, B, Y); @@ -881,6 +902,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$mul (A, B, Y); @@ -1059,6 +1081,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). //- @@ -1089,6 +1112,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). //- @@ -1121,6 +1145,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). //- @@ -1158,6 +1183,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). //- @@ -1196,6 +1222,7 @@ endmodule // -------------------------------------------------------- `ifndef SIMLIB_NOPOW +//* group binary module \$pow (A, B, Y); parameter A_SIGNED = 0; @@ -1246,6 +1273,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$logic_and (A, B, Y); @@ -1270,6 +1298,7 @@ endgenerate endmodule // -------------------------------------------------------- +//* group binary module \$logic_or (A, B, Y);