Arbitrary logic functions

The $lut cell type implements a single-output LUT (lookup table). It implements an arbitrary logic function with its \LUT parameter to map input port \A to values of \Y output port values. In psuedocode: Y = \LUT[A]. \A has width set by parameter \WIDTH and \Y has a width of 1. Every logic function with a single bit output has a unique $lut representation.

The $sop cell type implements a sum-of-products expression, also known as disjunctive normal form (DNF). It implements an arbitrary logic function. Its structure mimics a programmable logic array (PLA). Output port \Y is the sum of products of the bits of the input port \A as defined by parameter \TABLE. \A is \WIDTH bits wide. The number of products in the sum is set by parameter \DEPTH, and each product has two bits for each input bit - for the presence of the unnegated and negated version of said input bit in the product. Therefore the \TABLE parameter holds 2 * \WIDTH * \DEPTH bits.

For example:

Let \WIDTH be 3. We would like to represent \Y =~\A[0] + \A[1]~\A[2]. There are 2 products to be summed, so \DEPTH shall be 2.

~A[2]-----+
 A[2]----+|
~A[1]---+||
 A[1]--+|||
~A[0]-+||||
 A[0]+|||||
     |||||| product formula
     010000 ~\A[0]
     001001 \A[1]~\A[2]

So the value of \TABLE will become 010000001001.

Any logic function with a single bit output can be represented with $sop but may have variously minimized or ordered summands represented in the \TABLE values.

yosys> help $lut
Properties:

is_evaluable

Simulation model (verilog)
Listing 222 simlib.v
1786module \$lut (A, Y);
1787
1788    parameter WIDTH = 0;
1789    parameter LUT = 0;
1790
1791    input [WIDTH-1:0] A;
1792    output Y;
1793
1794    \$bmux #(.WIDTH(1), .S_WIDTH(WIDTH)) mux(.A(LUT[(1<<WIDTH)-1:0]), .S(A), .Y(Y));
1795
1796endmodule
yosys> help $sop
Properties:

is_evaluable

Simulation model (verilog)
Listing 223 simlib.v
1802module \$sop (A, Y);
1803
1804    parameter WIDTH = 0;
1805    parameter DEPTH = 0;
1806    parameter TABLE = 0;
1807
1808    input [WIDTH-1:0] A;
1809    output reg Y;
1810
1811    integer i, j;
1812    reg match;
1813
1814    always @* begin
1815        Y = 0;
1816        for (i = 0; i < DEPTH; i=i+1) begin
1817            match = 1;
1818            for (j = 0; j < WIDTH; j=j+1) begin
1819                if (TABLE[2*WIDTH*i + 2*j + 0] && A[j]) match = 0;
1820                if (TABLE[2*WIDTH*i + 2*j + 1] && !A[j]) match = 0;
1821            end
1822            if (match) Y = 1;
1823        end
1824    end
1825
1826endmodule