Table of Contents
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
As a 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 (also known as the ?: operator):
assign out =
(in==3’b000)?0:
(in==3’b001)?1:
(in==3’b010)?1:
(in==3’b011)?0:
(in==3’b100)?1:
(in==3’b101)?0:
(in==3’b110)?0:
1;
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[1] & 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.