User Tools


This is an old revision of the document!


Combinational Logic Styles

There are many different styles of SystemVerilog code that you can use to generate combinational circuits.

Consider the following logic function that outputs a 1 when an odd number of the three input bits are 1. (This is a 3-input XOR).

in[2] in[1] in[0] out
0 0 0 0
0 0 1 1
0 1 0 1
0 1 1 0
1 0 0 1
1 0 1 0
1 1 0 0
1 1 1 1
logic [2:0] in;
logic       out;
 
<Combinational Logic Here>

Assuming the above SystemVerilog code, there are many different ways to implement the same combinational logic. Here are some different examples:


Structural SV

Sum of Products:

logic [2:0] in_not;
 
not(in_not[0], in[0]);
not(in_not[1], in[1]);
not(in_not[2], in[2]);
 
and(term1, in_not[2], in_not[1], in[0]);
and(term2, in_not[2], in[1], in_not[0]);
and(term3, in[2], in_not[1], in_not[0]);
and(term4, in[2], in[1], in[0]);
or(out, term1, term2, term3, term4);

Minimized (single XOR gate):

xor(out, in[2], in[1], in[0]);

Dataflow SV

Using assign statement, and the ternary operator:

assign out = in[2] ? (in[1] ? (in[0] ? 1'b1 : 1'b0)
                            : (in[0] ? 1'b0 : 1'b1))
                   : (in[1] ? (in[0] ? 1'b0 : 1'b1)
                            : (in[0] ? 1'b1 : 1'b0));                                                                               

Using assign statement, with sum of products, and dataflow operators :

assign out = (~in[2] & ~in[1] & in[0]) | (~in[2] & in[1] & ~in[0]) |
             (in[2] & ~in[1] & ~in[0]) | (in[2] & in[2] & in[0]);

Using assign statement, vectored comparison operators, binary literals:

assign out = (in == 3'b001) || (in == 3'b010) || (in == 3'b100) || (in == 3'b111);

Using assign statement, vectored comparison operators, decimal literals:

assign out = (in == 3'd1) || (in == 3'd2) || (in == 3'd4) || (in == 3'd7);

Behavioral SV

Using always_comb block with if statement.

always_comb begin
    out = 1'b0;
    if ((in == 3'b001) || (in == 3'b010) || (in == 3'b100) || (in == 3'b111)) begin
        out = 1'b1;
    end else begin
        // This else isn't necessary because of the default value at the top, but is included here
        // to show you the syntax.
        out = 1'b0;
    end        
end

Using always_comb block with case statement.

always_comb begin
    out = 1'b0;
    case(in)
        3'b001: out = 1'b1;
        3'b010: out = 1'b1;
        3'b100: 
            out = 1'b1;
        3'b111: begin
            out = 1'b1;
        end
        default: begin
            // This default isn't necessary because of the default value at the top, but is included here
            // to show you the syntax.
            out = 1'b0;
        end
    endcase
end

The example above mixes different formatting of the case statements to show you the variations available. Note: Similar to if and always blocks, you will need to include a begin and end if your case contains more than one statement.