Combinational Logic

Recall that we are disciplining ourselves to design synchronous sequential circuits, which consist of combinational logic and registers. The outputs of combinational logic depend only on the current inputs. This section describes how to write behavioral models of combinational logic with HDLs.

Bitwise Operators

Bitwise Operators act on single-bit signals or on multi-bit busses. For example, the gates module in HDL Example 4.3 demonstrates bitwise operations on 4-bit busses for most common basic logic functions.

Example 4.3 Logic Gates
module gates(input  logic [3:0] a, b,
             output logic [3:0] y1, y2, y3
                                y4, y5, y6);
    /* five different two-input logic
       gates acting on 4-bit busses */
    assign y1 = a & b;    // AND
    assign y2 = a | b;    // OR
    assign y3 = a ^ b;    // XOR
    assign y4 = ~(a ^ b); // XNOR
    assign y5 = ~(a & b); // NAND
    assign y6 = ~(a | b); // NOR
endmodule

The schematic for the above code snippet may look like as follows,

Operators, Operands, Expression and Statements

Using the gate module shown in Example 4.3,

  1. ~, ^, | are examples of SystemVerilog/Verilog operators.

  2. a, b, and y1 are operands

  3. A combination of operators and operands, such as a & b, ~(a | b), is called an expression

  4. A complete command such as assign y4 = ~(a & b); is called a statement

Continuous Assignment Statement

assign out = in1 op in2; is called a continuous assignment statement. Continuous assignment statements end with a semicolon. Anytime the inputs on the right side of the = in a continuous assignment state change, the output on the left side is recomputed. Thus, continuous assignment statements describe combinational logic.

Comments and White Space

SystemVerilog/Verilog comments are just like those in C or Java. SystemVerilog/Verilog is case-sensitive. y1 and Y1 are different signals in SystemVerilog/Verilog.

SystemVerilog/Verilog is not picky about the use of white space (e.g., spaces, tabs, and line breaks). Nevertheless, proper indenting and use of blank lines is helpful to make nontrivial designs readable.

Be consistent in your use of capitalization and underscores in signal and module names. This text uses all lower case. Module and signal names must not begin with a digit.

Reduction Operators

Reduction operators imply a multiple-input gate acting on a single bus. HDL Example 4.4 describes an eight-input AND gate with inputs a7,a6,⋯ ,a0a_7,a_6,\cdots,a_0.

Analogous reduction operators exist for OR, XOR, NAND, and XNOR gates. Recall that a multiple-input XOR performs parity, returning TRUE if an odd number of inputs are TRUE.

Conditional Assignment

Conditional Assignments select the output from among alternatives based on an input called the condition. This is pretty useful for describing the multiplexer in combinational logic.

1

2:1 multiplexer

HDL Example 4.5 illustrates a 2:1 multiplexer using conditional assignment.

Code Explanation

2

4:1 Multiplexer

HDL Example 4.6 shows a 4:1 multiplexer based on the same principle as the 2:1 multiplexer in HDL Example 4.5.

Internal Variables

Internal Variables refer to the variables that are neither inputs nor outputs but are used only internal to the module. They are similar to local variables in programming languages. Example 4.7 shows how they are used in HDLs.

Code Explanation

Precedence

Table 4.1 summarises the operator precedence in SystemVerilog

Numbers

Numbers can be specified in binary, octal, decimal, or hexadecimal (bases 2, 8, 10, and 16, respectively).

  • The size, e.g., the number of bits, may optionally be given, and leading zeros are inserted to reach this size.

  • Underscores (_) in numbers are ignored and can be helpful in breaking long numbers into more readable chunks.

The following table shows numbers are written in SystemVerilog/Verilog.

Numbers
Bits
Base
Val
Stored

3'b101

3

2

5

101

'b11

?

2

3

000 ... 0011

8'b11

8

2

3

00000011

8'b1010_1011

8

2

171

10101011

3'd6

3

10

6

110

6'o42

6

8

34

100010

8'hAB

8

16

171

10101011

42

?

10

42

00 ... 0101010

Table Explanation

Z's and X's

HDLs use z to indicate a floating value, z is particularly useful for describing a tristate buffer, whose output floats when the enable is 0. Similarly, HDLs use x to indicate an invalid logic level.

TODO: Read through tristate buffer if have time.

Bit Swizzling

Often it is necessary to operate on a subset of a bus or to concatenate (join together) signals to form busses. These operations are collectively known as bit swizzling. In HDL Example 4.12, y is given the 9-bit value c2c1d0d0d0d0c0101c_2c_1d_0d_0d_0d_0c_0101 using bit swizzling operations.

Delays

HDL statements may be associated with delays specified in arbitrary units. They are helpful during simulation to predict how fast a circuit will work (if you specify meaningful delays) and also for debugging purposes to understand cause and effect (deducing the source of a bad output is tricky if all signals change simultaneously in the simulation results).

The delay of a gate produced by the synthesizer depends on its tpdt_{\text{pd}} and tcdt_{\text{cd}} specifications, not on numbers in HDL code.

HDL Example 4.13 adds delays to the original function from HDL Example 4.1, y=aˉbˉcˉ+abˉcˉ+abˉcy=\bar a\bar b\bar c+a\bar b\bar c+a\bar bc.

Code Explanation

Last updated