This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
|
resources:combinational_logic_styles [2019/06/28 10:34] jgoeders created |
resources:combinational_logic_styles [2020/02/07 16:22] (current) nelson |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Combinational Logic Styles ====== | ====== 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 | | ||
| + | |||
| + | |||
| + | |||
| + | <code SystemVerilog> | ||
| + | logic [2:0] in; | ||
| + | logic out; | ||
| + | |||
| + | <Combinational Logic Here> | ||
| + | |||
| + | </code> | ||
| + | |||
| + | 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: | ||
| + | <code SystemVerilog> | ||
| + | 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); | ||
| + | </code> | ||
| + | |||
| + | Minimized (single XOR gate): | ||
| + | |||
| + | <code SystemVerilog> | ||
| + | xor(out, in[2], in[1], in[0]); | ||
| + | </code> | ||
| + | |||
| + | ---- | ||
| + | |||
| + | === Dataflow SV === | ||
| + | |||
| + | Using assign statement, and the ternary operator (also known as the ?: operator): | ||
| + | <code SystemVerilog> | ||
| + | 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; | ||
| + | </code> | ||
| + | |||
| + | |||
| + | Using assign statement, with sum of products, and dataflow operators : | ||
| + | <code SystemVerilog> | ||
| + | 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]); | ||
| + | |||
| + | </code> | ||
| + | |||
| + | Using assign statement, vectored comparison operators, binary literals: | ||
| + | <code SystemVerilog> | ||
| + | assign out = (in == 3'b001) || (in == 3'b010) || (in == 3'b100) || (in == 3'b111); | ||
| + | </code> | ||
| + | |||
| + | Using assign statement, vectored comparison operators, decimal literals: | ||
| + | <code SystemVerilog> | ||
| + | assign out = (in == 3'd1) || (in == 3'd2) || (in == 3'd4) || (in == 3'd7); | ||
| + | </code> | ||
| + | ---- | ||
| + | === Behavioral SV === | ||
| + | |||
| + | Using ''always_comb'' block with if statement. | ||
| + | <code SystemVerilog> | ||
| + | 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 | ||
| + | </code> | ||
| + | |||
| + | Using ''always_comb'' block with case statement. | ||
| + | <code SystemVerilog> | ||
| + | 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 | ||
| + | </code> | ||
| + | |||
| + | 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. | ||