You and your friend are having lunch at a restaurant and decide to keep all expenses on a single bill. When it's time to pay at the cashier, the attendant multiplies the number of meals by two, adds up the cost of all drinks, and presents you with the final amount. You realize that the attendant added an extra drink and ask them to subtract it from the bill. In the end, with the corrected amount, you and your friend ask to split the total bill in half since you're going to split the cost.
This scene, common in our lives, had a supporting role played by a four-function calculator. In this calculator, there is a basic circuit called a multiplexer. It is through this circuit that the basic operations of the calculator are selected.
In this tutorial, you will learn how 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
Create a 4-input multiplexer (MUX4) using three MUX2s
Read and understand the project summary report
Interact with a project on the Community board.
Before proceeding, we recommend the following tutorials:
What is a multiplexer?
A multiplexer is a combinational digital circuit that transmits the bit of one of its inputs to its single output. The selection of a particular input is performed by a control signal.
On the left side of the animation above, we have the representation of a 2-input, 1-bit multiplexer in the form of switches. This multiplexer (or MUX2) propagates the input values to the output, interleaving (or multiplexing) the inputs according to the position of the switch. On the right side of the figure, we have the symbolic representation of the same MUX2. In the symbolic representation, the position of the switch 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 generate the following logical equation using the minterms indicated in rows 2 and 4:
s0 = (e0 AND (NOT c0)) OR (e1 AND c0)
From this sum-of-product equation, we have the schematic of the MUX2 in the table below. The schematic has labels for the internal wires (w_0, w_1, and w_3). These labels are necessary to describe the circuit in Verilog on the right-hand side of the table below.
Esquemático (MUX2) | Código Verilog (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);
|
Note that the coding of the schematic for logic gates in Verilog is very straightforward. The only care to be taken is to always place the output of the logic gate in the first position on the left, leaving the following positions for the inputs of the logic gate.
porta_lógica (saída, entrada1, entrada2, ...)
Note: The Pitanga platform accepts logic gates and, or, xor, nand, nor and xnor with up to 4 inputs.
To finish the Verilog coding for MUX2, we need to define the input and output ports. We will do this using the module/endmodule construction.
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 to a file named mux2.v and proceed to the next section.
Mapping, compiling, and prototyping.
Prototyping the MUX2 on the Community board is very simple, and we will do it by following the steps below:
1) Create the mapping file for the ports described in Verilog to the components of the Community board. Do this using the following example:
mux2.pinout
2) Open the Community board.
. pitanga.sh
python pitanga.py
Usuários Windows podem abrir a placa Community com um duplo clique no link Pitanga
3) Click on the "Upload Files" button and select the files mux2.v and mux2.pinout. Then, click on "Run".
If you haven't made any coding errors in Verilog, the text terminal will print a report summarizing the project. Note that the report has the same number of wires and logic gates used in the schematic. For this project, only 0.8% of the logical capacity of the virtual programmable Pitanga chip was used.
DESIGN SUMMARY REPORT
module : mux2
design file: mux2.v
pinout file: mux2.pinout
Total number of wires: 3
Total number of cells: 4
Cell Instances Cell Instances Cell Instances
-----------------------------------------------------------------------------
AND2 2 | NAND2 0 | XOR2 0
AND3 0 | NAND3 0 | XOR3 0
AND4 0 | NAND4 0 | XOR4 0
OR2 1 | 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/500 cells (0.8 %).
4) Finally, verify that the MUX2 circuit is in accordance with the project by clicking on the switches sw9, sw1, and sw0. In the animation below, you can see the project in operation on the Community board alongside a MUX2.
Prototyping a MUX4 with code reuse
Code reuse is a very common technique. Large projects use this technique to be able to deliver reliable circuits more quickly. In this section, we will do the same: we will reuse the code from MUX2 to design a MUX4.
Below is a schematic of a MUX4 composed of three 2-input multiplexers. The internal signals have been named and will be necessary for encoding the circuit in Verilog.
Just a reminder that the syntax for instantiating modules is
nome_do_modulo nome_da_instancia(
.porta_do_modulo(sinal_mapeado),
.porta_do_modulo(sinal_mapeado),
...
.porta_do_modulo(sinal_mapeado)
);
Here is a Verilog description for a 4-input multiplexer. 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
Save the above code in a file called mux4.v. Then, write the project pinout file and save it as mux4.pinout. Take some time to do this. Otherwise, you can use the following pin mapping.
mux4.pinout
Finally, compile and prototype the MUX4 project. The summary report should indicate three times the number of logic cells used compared to the MUX2, as expected.
DESIGN SUMMARY REPORT
module : mux4
design file: mux4.v
pinout file: mux4.pinout
Total number of wires: 11
Total number of cells: 12
Cell Instances Cell Instances Cell Instances
-----------------------------------------------------------------------------
AND2 6 | NAND2 0 | XOR2 0
AND3 0 | NAND3 0 | XOR3 0
AND4 0 | NAND4 0 | XOR4 0
OR2 3 | NOR2 0 | XNOR2 0
OR3 0 | NOR3 0 | XNOR3 0
OR4 0 | NOR4 0 | XNOR4 0
-----------------------------------------------------------------------------
BUF 0 | INV 3 | DFFRSE 0
Cells utilization: 12/500 cells (2.4 %).
Interacting with the MUX4 on the Community board
With the MUX4 project configured on the Community board, we will demonstrate that this circuit can be used as a universal 2-input logic gate.
In the first row of the table below, we have three MUX4s with different input configurations. Note that by keeping the inputs e0, e1, e2, and e3 static, the MUX4 circuit behaves like a truth table, with the inputs A and B being the indices of this table. In the example below, there are three MUX4 configurations. Each configuration functions as a 2-input logic gate, namely, AND, OR, and XOR, respectively. In the last row of the table, we show the functioning of the corresponding MUX4 configurations on the Community board.
AND2 | OR2 | XOR2 |
Note that the multiplexer circuit can be used to implement any type of logic gate. It is for this reason that programmable logic circuits, such as those found in FPGAs and CPLDs, use it as the basic cell.
Conclusion
Congratulations! You have just prototyped a digital circuit without using FPGAs. With the help of the Community virtual board and the Pitanga programmable chip, you have gained experience in designing multiplexers in Verilog. In the end, you were able to create more complex multiplexers and understand the importance of multiplexers in the design of programmable logic circuits, such as CPLDs and FPGAs.
Did you know that the Student board has a faster Pitanga chip with more logic cells than the Community board? And that the Student board does not have a user limit? Then, consider subscribing to one of our plans. Contact us!
Comments