top of page

How to design multiplexers in Verilog

Writer's picture: Alcides CostaAlcides Costa

You and your friend are having lunch at a restaurant and decide to put all expenses on a single tab. When it's time to pay the bill at the cashier, the attendant multiplies the number of meals by two, adds the cost of all the drinks, and presents the final amount to you. You notice that the attendant added one extra drink and ask to subtract it from the bill. In the end, with the corrected amount, you and your friend ask to divide the total by two, as you are splitting the bill.


This scene, common in our lives, had a four-basic-operations calculator as a supporting element. In this calculator, there is an elementary circuit called a multiplexer. It is through this circuit that the basic operations of the calculator are selected.


In this tutorial, you will learn to:

  • Design a 2-input multiplexer circuit (MUX2) using logic gates

  • Implement the MUX2 design in Verilog

  • Map, compile, and prototype a MUX2 on the Community board (C-Board)

  • Create a 4-input multiplexer (MUX4) from three MUX2

  • Read and understand the Pitanga project summary report

  • Interact with a project on the C-Board


Before proceeding, we recommend the following tutorial:

  • How to design hierachical circuits in Verilog


What is a multiplexer?

A multiplexer is a combinational digital circuit that transmits the bit from one of its inputs to its single output. The selection of a particular input is controlled by a control signal.



On the left side of the animation above, we have the representation of a 1-bit 2-input multiplexer in the form of switches. This multiplexer (or MUX2) propagates the input values to the output, alternating (or multiplexing) the inputs based on the switch position. On the right side of the figure, we have the symbolic representation of the same MUX2. In the symbolic representation, the switch position is controlled by the signal c0.


From the animation, it is possible to identify that the MUX2 has 3 inputs and 1 output, namely: e0, e1, c0, and s0, respectively. The MUX2 can also be described by the following truth table, where 'X' can be '0' or '1':


e0

e1

c0

s0

1

0

X

0

0

2

1

X

0

1

3

X

0

1

0

4

X

1

1

1

Note that, depending on the variable c0, the output s0 is not affected by the value of 'X'. In other words, the value of 'X' does not matter for the output s0 (don't care).


Describing a MUX2 in Verilog

The truth table from the previous section allows us to derive the following logic equation through the minterms indicated in rows 2 and 4:

s0 =  (e0 AND (NOT c0)) OR (e1 AND c0)

From this sum-of-products equation, we have the schematic of the MUX2 shown in the table below. The schematic includes labels for the internal wires (w_0, w_1, and w_3). These labels are necessary to describe the circuit in Verilog, as shown on the right side of the table below.

Schematic (MUX2)

Verilog Code (MUX2)









    wire w_0, w_1, w_2;

    not(w_2, c0);
    and(w_0, e0, w_2);
    and(w_1, e1, c0);
    or(s0, w_0, w_1);

Notice that the schematic encoding for logic gates in Verilog is quite straightforward. The only precaution to take is to always place the output of the logic gate in the first position on the left, leaving the subsequent positions for the gate inputs.

logic_gate (output, input1, input2, ...);

To finalize the Verilog coding for the MUX2, we need to define the input and output ports. We will do this using the module/endmodule construct.



module mux2(
    input   e0,
    input   e1,
    input   c0,
    output  s0);

    wire w_0, w_1, w_2;

    not(w_2, c0);
    and(w_0, e0, w_2);
    and(w_1, e1, c0);
    or(s0, w_0, w_1);
endmodule

Done! You have just designed and described a 2-input multiplexer in Verilog. Save the code above in a file named mux2.v and proceed to the next section.


Mapping, compiling, and prototyping

Prototyping the MUX2 on the C-Board is quite simple, and we will do this by following the steps below:


1) Copy the Copy and paste the pinout code indicated below (mux2.pinout) into the pinout editor.

mux2.pinout

3) Clique no botão "Run"


If you have not made any coding errors in Verilog, the project summary report will be printed in the text terminal. Note that the report contains a different number of wires and logic gates compared to those used in the schematic. This happens because the Pitanga emulator identified a more optimized way to implement your design, using fewer logic gates than initially required. This optimization is normal and will occur whenever the emulator finds a circuit that uses fewer transistors than necessary.

                     DESIGN SUMMARY REPORT
  module     : mux2
  design file: pitanga.v
  pinout file: pitanga.pinout

Total number of wires: 7
Total number of cells: 4
Total number of ports: 6

  Cell      Instances   Cell      Instances   Cell      Instances
 -----------------------------------------------------------------
  AND2              0 | NAND2             3 | XOR2              0 
  AND3              0 | NAND3             0 | XOR3              0
  AND4              0 | NAND4             0 | XOR4              0
  OR2               0 | NOR2              0 | XNOR2             0
  OR3               0 | NOR3              0 | XNOR3             0
  OR4               0 | NOR4              0 | XNOR4             0
 -----------------------------------------------------------------
  BUF               0 | INV               1 | DFFRSE            0

Cells utilization: 4
Transistor count : 14/500 transistors (2.80 %)

Finally, check if the MUX2 circuit matches the design by toggling the switches sw5, sw1, and sw0. In the animation below, you can see the design operating on the C-Board alongside a MUX2.


Prototyping a MUX4 with Code Reuse

Code reuse is a very common technique. Large projects utilize this technique to deliver reliable circuits more quickly. In this section, we will do the same: we will reuse the MUX2 code to design a MUX4.


Below is the schematic of a MUX4 composed of three 2-input multiplexers. The internal signals have been named and will be necessary for coding the circuit in Verilog.


Remember that the syntax for instantiating modules is:

module_name instance_name (
    .module_port(mapped_signal),
    .module_port(mapped_signal),
    ...
    .module_port(mapped_signal)
);

Here is the description of a 4-input multiplexer in Verilog. Note that the MUX4 code only instantiates MUX2 modules, reusing the code from the previous section:


module mux4(
    input       e0,
    input       e1,
    input       e2,
    input       e3,
    input       A,
    input       B,
    output      Y);

    wire    w_0, w_1;
    
    mux2 MUX2A (.e0(e0) , .e1(e1) , .c0(A), .s0(w_0));
    mux2 MUX2B (.e0(e2) , .e1(e3) , .c0(A), .s0(w_1));
    mux2 MUX2C (.e0(w_0), .e1(w_1), .c0(B), .s0(Y));
endmodule

Copy and paste the code above into the Verilog editor of the Pitanga IDE, above the mux2 module. Then, write the pinout code for the project in the pinout editor. Take some time to do this. Otherwise, use the following mapping:

mux4.pinout

Finally, compile and prototype the MUX4 project. The summary report should indicate a higher number of transistors used compared to the MUX2, as expected. However, this number is not three times greater because the Pitanga emulator performed optimizations, reducing the number of transistors.

                     DESIGN SUMMARY REPORT
  module     : mux4
  design file: pitanga.v
  pinout file: pitanga.pinout

Total number of wires: 15
Total number of cells: 9
Total number of ports: 9

  Cell      Instances   Cell      Instances   Cell      Instances
 -----------------------------------------------------------------
  AND2              1 | NAND2             4 | XOR2              0 
  AND3              0 | NAND3             2 | XOR3              0
  AND4              0 | NAND4             0 | XOR4              0
  OR2               0 | NOR2              0 | XNOR2             0
  OR3               0 | NOR3              0 | XNOR3             0
  OR4               0 | NOR4              0 | XNOR4             0
 -----------------------------------------------------------------
  BUF               0 | INV               2 | DFFRSE            0

Cells utilization: 9
Transistor count : 38/500 transistors (7.60 %)

Interacting with the MUX4 on the C-Board

With the MUX4 project configured on the C-Board, we will demonstrate that this circuit can be used as a universal two-input logic gate.


In the first row of the table below, we have three MUX4s with different input configurations. Notice that by keeping the inputs e0, e1, e2, and e3 static, the MUX4 circuit behaves like a truth table, with inputs A and B serving as the indices of this table. In the example below, there are three MUX4 configurations. Each configuration functions as a two-input logic gate: AND, OR, and XOR, respectively. In the last row of the table, we see the operation of these respective MUX4 configurations on the C-Board.

AND2

OR2

XOR2













Note that the multiplexer circuit can be used to implement any type of logic gate. This is why programmable logic circuits, such as those found in FPGAs and CPLDs, use it as the base cell.


Conclusion

Congratulations! You have just prototyped a digital circuit without using FPGAs. With the help of the Pitanga Virtual Board and the Pitanga vPLD, you gained the experience of designing multiplexers in Verilog. In the end, you successfully developed more complex multiplexers and understood the importance of multiplexers in the design of programmable logic circuits, such as CPLDs and FPGAs.

 

Did you know that the Pitanga Virtual Board can be used in your educational institution? Contact us to learn more!

23 views0 comments

Comments


bottom of page