Designing Multiplexers in Verilog and SystemVerilog

Multiplexers, or MUXes, are fundamental components of digital circuits that allow selecting one of several input signals and forwarding it to a single output. In this post, we'll explain how to design multiplexers in Verilog and SystemVerilog, and provide examples to help you get started.

Designing a 2:1 1-Bit MUX with a Ternary Operator in Verilog and SystemVerilog

In this example, we'll design a 2:1 1-bit MUX using a ternary operator. Here's the code:

module Mux2to1Simple(
  input  logic a, b, select,
  output logic y
);
  assign y = select ? b : a;
endmodule

In this example, we've defined a module called Mux2to1Simple with 1-bit data input lines a and b, a select line select, and a 1-bit data output line y. The assign statement assigns the value of b to y if select is 1, and the value of a otherwise.

Designing a 2:1 MUX with a Parameterized Width in Verilog and SystemVerilog

In this example, we'll design a 2:1 MUX with a width that can be parameterized. Here's the code:

module Mux2to1 #(
  parameter Width = 8
) (
  input  logic [Width-1:0] a, b, select,
  output logic [Width-1:0] y
);
  assign y = select ? b : a;
endmodule

In this example, we've defined a module called Mux2to1 with data input lines a and b, a select line select, and a data output line y, all with a width of Width. The assign statement works the same way as in the previous example.

Designing an 8:1 MUX with a Case Statement in Verilog and SystemVerilog

In this example, we'll design an 8:1 MUX using a case statement. Here's the code:

module Mux8to1 #(
  parameter Width = 8,
) (
  input  logic [Width-1:0] dataIn [0:7],
  input  logic [2:0]       select,
  output logic [Width-1:0] dataOut
);
  always_comb begin
    unique case (select)
      3'b000: dataOut = dataIn[0];
      3'b001: dataOut = dataIn[1];
      3'b010: dataOut = dataIn[2];
      3'b011: dataOut = dataIn[3];
      3'b100: dataOut = dataIn[4];
      3'b101: dataOut = dataIn[5];
      3'b110: dataOut = dataIn[6];
      3'b111: dataOut = dataIn[7];
    endcase
  end
endmodule

In this example, we've defined a module called Mux8to1 with 8 data input lines and 3 select lines, all with a width of Width. The unique case statement in the always block is used instead of a regular case statement to ensure that only one input is selected based on the value of the select signal. The unique case statement is particularly useful for preventing issues like incomplete case statements or ambiguous logic.

Conclusion

Designing multiplexers is a fundamental skill in digital circuit design, and Verilog and SystemVerilog is an ideal language for this task. By following the examples in this post, you can learn how to design 2:1 MUXes with a ternary operator, 2:1 MUXes with a parameterized width, and 8:1 MUXes with a case statement.