View Course Path

Verilog code for 2:1 Multiplexer (MUX) – All modeling styles

After reading this post, you’ll be able to

  • Get knowledge on different styles of modeling in Verilog HDL
  • Design the 2:1 MUX in Verilog with all abstraction layers (modeling styles).
  • Generate RTL Schematic and simulate the 2:1 MUX using testbench.

What is a multiplexer?

A multiplexer is a device that selects one output from multiple inputs. It is also known as a data selector. Multiplexers are used in communication systems to increase the amount of data that can be sent over a network within a certain amount of time and bandwidth. It allows us to ‘squeeze’ multiple data lines into one data line.

The multiplexer (MUX) functions as a multi-input and single-output switch. The selection of the input is done using select lines. A MUX with 2^n input lines have n select lines and is said to be a 2^n: 1 MUX with one output. You can find the detailed working and schematic representation of a multiplexer here.

Now let’s start the coding part. Well, in Verilog hardware descriptive language, we have four main abstraction layers (or modeling styles).

  1. Gate level modeling
  2. Dataflow modeling
  3. Behavioral modeling
  4. Structural modeling

In this article, we’ll write the Verilog code for the simplest multiplexer, i.e. a 2:1 MUX.

Comparing 2:1 with 2^n: 1 (as mentioned before) we get n = 1, which is the number of select lines (input variables = 2, select lines = 1, output signal = 1). Now before jumping to the coding section, a brief description of each modeling style has been presented before you.

Gate Level Modeling

As the name suggests, this style of modeling will include primitive gates that are predefined in Verilog. This is virtually the lowest abstraction layer, which is used by designers for implementing the lowest level modules, as the switch level modeling isn’t that common. The prerequisite for this style is knowing the basic logic diagram of the digital circuit that you wish to code.

Since we’re concerned about designing the Verilog code for a 2:1 MUX, have a look at its circuit diagram.

Logic circuit

2:1 MUX logic diagram
Logic Diagram of 2: 1 MUX

The input signals are D0 and D1. S is the select line with Y as its output. We can orally solve for the expression of the output that comes out to be:

Y = D0.S’ + D1.S

Verilog code for 2:1 MUX using gate-level modeling

For the gate level, we will first declare the module for 2: 1 MUX, followed by the input-output signals. The order of mentioning output and input variables is crucial here, the output variable is written first in the bracket, then the input ones.

module m21(Y, D0, D1, S);

The module is a keyword here. m21 is the name of the module. Y is the output and D0, D1 and S being input are written after. Note that we don’t declare intermediate signals while defining the module.

Next comes the declaration of input, output, and intermediate signals. You might have noticed that other modeling styles include the declaration of variables along-with their respective data- types. But in the gate- level, we only declare the intermediate variables as wire; there’s no need for reg or wire declaration for input-output entities.

output Y;
input D0, D1, S;
wire T1, T2, Sbar;

Next comes the instantiation part for gates. and not and or are the predefined built-in gates, and we’re instantiating these gates with their respective input-output ports.

For example for not gate, Sbar is the output and S is the input. Similarly for and gate, T1, D1, and T2, D2 are inputs to two and gates and S and Sbar are their respective output.

and (T1, D1, S), (T2, D0, Sbar);
not (Sbar, S);
or (Y, T1, T2);

The endmodule marks the end of the module.

endmodule

Here’s the final code of the 2:1 mux using gate-level modeling.

module m21(Y, D0, D1, S);

output Y;
input D0, D1, S;
wire T1, T2, Sbar;

and (T1, D1, S), (T2, D0, Sbar);
not (Sbar, S);
or (Y, T1, T2);

endmodule

RTL Schematic

This is the design abstraction, which shows the internal circuitry involved. It is the hardware implementation of a system.

RTL schematic for 2x1 MUX
RTL schematic Gate level modeling

Data flow modeling

The dataflow level shows the nature of the flow of data in continuous assignment statements (assign keyword). It describes the combinational circuit by their functions rather than their gate structures. For coding in the dataflow style, we only need to know about the logical expression of the circuit.

Logical Expression

The equation for 2:1 mux is:

Y = D0.S’ + D1.S

where Y is the final output, D0, D1, and S are inputs.

Verilog code for 2:1 MUX using data flow modeling

To start with this, first, you need to declare the module. There’s no need for data- type declaration in this modeling.

module m21(Y, D0, D1, S);
output Y;
input D0, D1, S;

Now since this the dataflow style, one is supposed to use assign statements. I have used a ternary operator for the output Y. This operator ? means that the output Y becomes equal to data D1 if select line S is true otherwise D0 is the final output.

assign Y= (S)? D1: D0;

Final code:

module m21(D0, D1, S, Y);

output Y;
input D0, D1, S;

assign Y=(S)?D1:D0;

endmodule

RTL Schematic

The hardware schematic for a 2:1 multiplexer in dataflow level modeling is shown below. You will notice that this schematic is different from that of the gate-level. It involves the symbol of a multiplexer rather than showing up the logic gates involved, unlike gate-level modeling.

RTL hardware schematic
RTL hardware schematic Dataflow Modeling

Behavioral modeling

This level describes the behavior of a digital system. In most of the cases, we code the behavioral model using the truth table of the circuit.

Truth-table for 2:1 MUX

truth table 2x1
Truth Table for 2:1 MUX

Now to find the expression, we will use K- map for final output Y.

Equation from the truth table: Y = D0.S’ + D1.S

Verilog code for 2:1 MUX using behavioral modeling

First, define the module m21 and declare the input and output variables.

module m21( D0, D1, S, Y);

Don’t forget to mention the data- type of the ports. Since it is the behavioral modeling, we will declare the output Y as reg while the rest of the inputs as wire.

input wire D0, D1, S; 
output reg Y;

Behavioral modeling mainly includes two statements:

  • An initial statement which is executed the only once
  • always statement, which is executed once the sensitivity list is activated.

You should notice that the output is equal to the second input if the select line is high. Otherwise, it is equal to the first input itself. This logic can be stated by using the if-else statement.

Since the output of 2:1 MUX changes once there is a change in D0 OR D1 OR S we’ll use always statement. Now, if the S event is true, the output Y will be D1, else the output will be D0.

always @(D0 or D1 or S) 
begin 
 if(S) 
 Y= D1;
 else 
 Y=D0; 
end

Summing up the final code:

module m21( D0, D1, S, Y);
input wire D0, D1, S;
output reg Y;

always @(D0 or D1 or S)
begin

if(S) 
Y= D1;
else
Y=D0;

end

endmodule

RTL Schematic

Hardware schematic for 2:1 MUX:

RTL hardware schematic
RTL hardware schematic Behavioral Modeling

Structural modeling

Structural modeling describes the hardware structure of a digital system. It is usually written in RTL and is somewhat similar to gate-level modeling. The only difference is it doesn’t include any built-in gates. The components and connections all need to separately defined here. There’s a proper definition for the expression of the digital system within the module itself.  It includes module declaration and instantiation, port-list and it’s associates.

Logic circuit

Now the logical diagram for a 2:1 MUX shows that we need two AND gates, one OR gate and one NOT gate. We’ll structurize for each of the gates separately.

2x1 logical diagram
Verilog code for 2:1 MUX using structural modeling

First, we’ll start by declaring the modules for each logic gate. Below is the declaration of a module for AND gate, we can define the input-output variables in the next line also. We don’t need the data- type for signals since it’s the structure of the circuit that needs to be emphasized.

module and_gate(output a, input b, c);

Now using the assign statement, write the function of the logic gate in a statement. You may use the delay.

assign a = b & c; 
endmodule

That marks the end of a module for AND gate. Similarly for other gates also:

NOT gate =>

module not_gate(output d, input e); 
assign d = ~ e; 
endmodule

OR gate =>

module or_gate(output l, input m, n); 
assign l = m | n; 
endmodule

NOTE: use a different variable name for each input and output signal.

Time for us to combine these individual modules for logic gates into one single module for 2:1 MUX. This is done with the help of a concept called module instantiation and falls under a separate module top. The above individual modules will be used in the following by instantiating them with the name_of_the_instance. Instantiation is used when we want to repeat a particular function/ module for different sets of input.

First, write the name of the module you need. Then give the instance a name. The association list will contain the output signal first, followed by the input ones.

and_gate u1(T1, D1, S);

Here and_gate is the name of the module, u1 is the instance’s name. T1 wire(which is the intermediate signal) is the output, D1 and S are input. Repeat this for the rest of the modules after considering the logic diagram.

and_gate u1(T1, D1, S); 
not_gate u2(T2, S); 
and_gate u3(T3, D0, T2); 
or_gate u4(Y, T1, T3);

Here’s the final code for 2:1 mux in structural style.

module and_gate(output a, input b, c);
assign a = b & c;
endmodule

module not_gate(output d, input e);
assign d = ~ e;
endmodule

module or_gate(output l, input m, n);
assign l = m | n;
endmodule

module m21(Y, D0, D1, S);
output Y;
input D0, D1, S;
wire T1, T2, T3;
and_gate u1(T1, D1, S);
not_gate u2(T2, S);
and_gate u3(T3, D0, T2);
or_gate u4(Y, T1, T3);
endmodule

RTL schematic

RTL schematic for 2x1 MUX
RTL schematic Structural Modelling

Testbench for the 2:1 Mux in Verilog

A testbench drives the input to the design code of the system. It is used to provide the initial stimulus to the input signals and check for the entire range of possible combinations. You may find a detailed explanation and steps to write the testbench over here!

This is the testbench code for the 2:1 multiplexer.

module top;
wire out;
reg d0, d1, s;
m21 name(.Y(out), .D0(d0), .D1(d1), .S(s));
initial
begin
d0=1'b0;
d1=1'b0;
s=1'b0;
#100 $finish;
end
always #40 d0=~d0;
always #20 d1=~d1;
always #10 s=~s;
always@(d0 or d1 or s)
$monitor("At time = %t, Output = %d", $time, out);
endmodule;

Simulation Waveform

Here is the final simulated waveform for the 2X1 MUX circuit.

Simulation Waveform 2:1 MUX
Simulation Waveform 2:1 MUX

2 thoughts on “Verilog code for 2:1 Multiplexer (MUX) – All modeling styles

  1. Hi,

    I think you might have made a mistake in your truth table for this 2×1 MUX?

    You only have half the truth table, and it looks like the you swapped the output for the second and third line.

    I believe it should look like this:

    S D0 D1|Out
    ——————–
    0 0 0 | 0
    0 0 1 | 0
    0 1 0 | 1
    0 1 1 | 1
    1 0 0 | 0
    1 0 1 | 1
    1 1 0 | 0
    1 1 1 | 1

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.