0% found this document useful (0 votes)
42 views

Verilog code for 8_1 Multiplexer (MUX) - All modeling styles

The document provides an overview of multiplexers, specifically focusing on the 8:1 multiplexer, including its implementation using different modeling styles in Verilog: gate-level, dataflow, and behavioral modeling. It includes detailed Verilog code examples for each modeling style, as well as a testbench for simulation. The document also discusses the advantages of multiplexing in digital systems, such as reduced transmission costs and bandwidth savings.

Uploaded by

thambigan
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
42 views

Verilog code for 8_1 Multiplexer (MUX) - All modeling styles

The document provides an overview of multiplexers, specifically focusing on the 8:1 multiplexer, including its implementation using different modeling styles in Verilog: gate-level, dataflow, and behavioral modeling. It includes detailed Verilog code examples for each modeling style, as well as a testbench for simulation. The document also discusses the advantages of multiplexing in digital systems, such as reduced transmission costs and bandwidth savings.

Uploaded by

thambigan
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

A multiplexer is a data selector which selects a particular input data

B
line and produce that in the output section. It is implemented using
combinational circuits and is very commonly used in digital systems.
C
Sending data over multiplexing reduces the cost of transmission
lines, and saves bandwidth.

A 2^n:1 multiplexer has 2^n input lines, n select lines, and a single
output line. You can find a detailed explanation and schematic
representation for multiplexers over here.

There are four layers of abstraction in an HDL:

1. Gate level modeling


2. Dataflow modeling
3. Behavioral modeling
4. Structural modeling S

This article will deal with the modeling styles for an 8:1 multiplexer.
Verilog code for 8:1 mux using structural modeling
RTL schematic
Testbench for 8×1 Mux using Verilog
TCL Console
Simulation Waveforms

Gate level modeling


The gate-level modeling is virtually the lowest abstract level of
modeling. This style of modeling will include primitive gates that are
predefined in Verilog HDL. The designer should know the basic logic
circuit and the logic gates that are employed in that circuit for a
particular system. There is another abstraction layer below gate-level:
switch level modeling, which deals with the transistor technologies.

Logic circuit
The following figure is the 8×1 multiplexer. Now this 8×1 MUX is a
high-level multiplexer. For simplicity, the 8×1 mux can also be
implemented using 2×1 or 4×1 multiplexers.
You can observe that the input signals
are D0, D1, D2, D3, D4, D5, D6, D7, S0, S1, S2 and the output signal
is out.

Verilog code for 8:1 mux using gate-level


modeling
First of all, we need to mention the timescale directive for the
compiler. This will control the time unit, which measures the delays
and simulation time, and time precision specifies how delays are
rounded off for the simulation. It starts with `timescale.

`timescale 1ns/1ps

The following code will be simulated in nanoseconds, as mentioned


Input variables: D0, D1, D2, D3, D4, D5, D6, D7, S0, S1,
S2
Output variable: out

module m81(input D0, D1, D2, D3, D4, D5, D6,


D7, S0, S1, S2, output out);

There’s another way to define the input-output ports. We can declare


the data lines and select lines as vector nets also. Here’s the
declaration.

input wire [7:0] D;


input wire [2:0] S;

In some of the complex circuits, we need intermediate signals, and


they are declared as wires.

wire T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
T11;
and(T4, D0, T1, T2, T3);
or(out, T4, T5, T6, T7, T8, T9, T10, T11);

T4 is the output for AND gate, D0, T1, T2, and T3 are
the input variables.
For OR gate, the output is out and input is T4, T5, T6,
T7, T8, T9, T10 and T11.

If there exist more than two same gates, we can concatenate the
expression into one single statement.

not(T1, S0), (T2, S1), (T3, S2);

Summing up, we will get the final gate-level modeling Verilog code:

`timescale 1ns/1ps
module m81(input D0, D1, D2, D3, D4, D5, D6,
D7, S0, S1, S2, output out);
wire T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
T11;
not(T1, S0);
not(T2, S1);
not(T3, S2);
and(T4, D0, T1, T2, T3), (T5, D1, S0, T2,
T3);
and(T6, D2, T1, S1, T3), (T7, D3, S0, S1,
T3);
and(T8, D4, T1, T2, S2), (T9, D5, S0, T2,
S2);
and(T10, D6, T1, S1, S2), (T11, D7, S0, S1,
S2);
RTL Schematic For Gate-level Modeling

Data flow modeling


This modeling represents the flow of the data through
the combinational circuit. The Verilog code in this abstraction layer
doesn’t include any logic gates. Instead, we should know the final
output expression of the given circuit.

The logical equation for the 8:1 multiplexer is:-

out = (D0.S2′.S1′.S0′) + (D1.S2′.S1′.S0) + (D2.S2′.S1.S0′) +


(D3.S2′.S1.S0) + (D4.S2.S1′.S0′) + (D5.S2.S1′.S0) + (D6.S2.S1.S0′)
+ (D7.S2.S1.S0)

where D0, D1, D2, D3, D4, D5, D6, D7, S0, S1, and S2 are the inout
variables and the output variable is out.

Verilog code for 8:1 mux using dataflow


modeling
Beginning with the coding part, first, we should keep in
mind that the dataflow model of a system has
an assign statement, which is used to express the
assign out = (D0 & S2bar & S1bar & S0bar) |
(D1 & S2bar & S1bar & S0) | (D2 & S2bar & S1
& S0bar) + (D3 & S2bar & S1 & S0) + (D4 & S2
& S1bar & S0bar) + (D5 & S2 & S1bar & S0) +
(D6 & S2 & S1 & S0bar) + (D7 & S2 & S1 & S0);

The variables S2bar, S1bar, and S0bar haven’t been


mentioned in the logic circuit as well as in the module.
One may declare them in the port-list itself or can be
treated as intermediate signals. Therefore, we need to
define these signals, which are technically the NOT
operation of select lines.

assign S0bar=~S0;
assign S1bar=~S1;
assign S2bar=~S2;

So the whole code is:

module m81(output out, input D0, D1, D2, D3,


D4, D5, D6, D7, S0, S1, S2);
assign S1bar=~S1;
assign S0bar=~S0;
assign S2bar=~S2;
assign out = (D0 & S2bar & S1bar & S0bar) |
(D1 & S2bar & S1bar & S0) | (D2 & S2bar & S1
& S0bar) + (D3 & S2bar & S1 & S0) + (D4 & S2
& S1bar & S0bar) + (D5 & S2 & S1bar & S0) +
(D6 & S2 & S1 & S0bar) + (D7 & S2 & S1 & S0);
endmodule
RTL Schematic for Dataflow Modeling

Behavioral modeling
This is the highest abstraction layer of all. It emphasizes the behavior
of the digital circuit. In most cases, implementing the truth table will
describe the behavior with no failure.

Truth table

Truth Table for 8:1 MUX

Verilog code for 8:1 mux using


behavioral modeling
The module declaration will remain the same as that of the above
styles with m81 as the module’s name.
One can find numerous ways to implement the truth table, whether it
is a nested if-else statement or case statement.

Here, I’ve used the case statement under always block.

always@(S0 & S1 & S2)


begin
case(S0 & S1 & S2)

Let’s write down the cases for each row of the truth table. For S0=0,
S1=0, S2=0, the input variable D0 will get transferred to the output
variable out.

3'b000: out=D0;

Similarly,

3'b001: out=D1;
3'b010: out=D2;
3'b011: out=D3;
3'b100: out=D4;
3'b101: out=D5;
3'b110: out=D6;
3'b111: out=D7;

3'b000 represents the 3- bit binary value for the expression inside
the case statement.

Design code:
module m81(out, D0, D1, D2, D3, D4, D5, D6,
D7, S0, S1, S2);
input wire D0, D1, D2, D3, D4, D5, D6, D7,
S0, S1, S2;
output reg out;
always@(*)
begin
case(S0 & S1 & S2)
3'b000: out=D0;
3'b001: out=D1;
3'b010: out=D2;
3'b011: out=D3;
3'b100: out=D4;
3'b101: out=D5;
3'b110: out=D6;
3'b111: out=D7;
default: out=1'b0;
endcase
end
endmodule

RTL Schematic
logic diagram for 8×1 MUX

Verilog code for 8:1 mux using structural


modeling
Decide which logical gates you want to implement the circuit with. In
the 8×1 MUX, we need eight AND gates, one OR gate, and three
NOT gates.

Start defining each gate within a module.


Here’s the module for AND gate with the module
name and_gate. The port-list will contains the output and
input variables. Note that there’s no need to follow any
sequence for mentioning output variables first, then input
signals.

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


assign a = b & c & d & e;
endmodule
module or_gate(output l, input m, n, o, p, q,
r, s, t);
assign l = m | n | o | p | q | r | s | t;
endmodule

The next thing to be done is the instantiation of modules. We’ll


combine the above modules into one single module for 8:1
multiplexer.

Start with the name of the module you need. This will
work as an instance. Give this instance a name. Then
mention the port-list.

not_gate u1(s1bar, S1);

u1 is the instance name, s1bar is the output which


contains the NOT operation of S1 input.
You can declare names for input-output other than the
names used in defining modules. The order, however, is
very important here. It should be the same as that of the
modules for the gates. This is similar to the function call
and arguments in C.

Similarly for others instances:

not_gate u2(s0bar, S0);


not_gate u3(s2bar, S2);
and_gate u4(T1, D0, s0bar, s1bar, s2bar);
and_gate u5(T2, D1, S0, s1bar, s2bar);
d t 6(T3 D2 0b S1 2b )
module and_gate(output a, input b, c, d, e);
assign a = b & c & d & e;
endmodule

module not_gate(output f, input g);


assign f = ~ g;
endmodule

module or_gate(output l, input m, n, o, p, q,


r, s, t);
assign l = m | n | o | p | q | r | s | t;
endmodule

module m81(out, D0, D1, D2, D3, D4, D5, D6,


D7, S0, S1, S2);
output out;
input D0, D1, D2, D3, D4, D5, D6, D7, S0, S1,
S2;
wire s0bar, s1bar, T1, T2, T3, T4, T5, T6,
T7, T8;

not_gate u1(s1bar, S1);


not_gate u2(s0bar, S0);
not_gate u3(s2bar, S2);

and_gate u4(T1, D0, s0bar, s1bar, s2bar);


and_gate u5(T2, D1, S0, s1bar, s2bar);
and_gate u6(T3, D2, s0bar, S1, s2bar);
and_gate u7(T4, D3, S0, S1, s2bar);
and_gate u8(T5, D4, s0bar, s1bar, S2);
and_gate u9(T6, D5, S0, s1bar, S2);
and_gate u10(T7, D6, s0bar, S1, S2);
and_gate u11(T8, D7, S0, S1, S2);
or_gate u12(out, T1, T2, T3, T4, T5, T6, T7,
T8);
Testbench for 8×1 Mux using
Verilog
The testbench is a set of lines that are used to test and simulate the
design code for a given system. It tests the design for a variety of
possible inputs. Follow up this post for step-by-step instruction to
write a testbench.

`timescale 1ns/1ps
module top;
wire out;
reg D0, D1, D2, D3, D4, D5, D6, D7, D8, S0,
S1, S2;
m81 name(.D0(D0), .D1(D1), .D2(D2), .D3(D3),
.D4(D4), .D5(D5), .D6(D6), .D7(D7), .S0(S0),
.S1(S1), .S2(S2), .out(out));
initial
begin
D0=1'b0; D1=1'b0; D2=1'b0; D3=1'b0; D4=1'b0;
D5=1'b0; D6=1'b0; D7=1'b0;S0=1'b0; S1=1'b0;
S2=1'b0;
#500 $finish;
end
always #1 D0=~D0;
always #2 D1=~D1;
always #3 D2=~D2;
always #4 D3=~D3;
always #5 D4=~D4;
always #6 D5=~D5;
always #7 D6=~D6;
always #8 D7=~D7;
always #9 S0=~S0;
always #10 S1=~S1;
always #11 S2=~S2;
always@(D0 or D1 or D2 or D3 or D4 or D5 or
TCL Console

Simulation Waveforms
The simulation waveform for 8X1 MUX is:

Simulation Waveform 8×1 Multiplexer

The above simulation result is the same for each of the abstraction
layers, truly satisfying the truth table.
5 thoughts on “Verilog code for 8:1 Multiplexer (MUX)
styles”
1. Bire says:
March 29, 2021 at 9:42 PM
Sir can u tell me how can write verilog cod and vhdl code foe 16-1mux and 1-16 dwmux
Reply
1. Umair Hussaini says:
April 5, 2021 at 11:53 AM
Hi Bire! You can easily change the code in the above post for a 16:1 mux by simply in
steps in this post for the VHDL coding of a demux.
Reply
2. Arpit says:
September 7, 2020 at 1:43 PM
This is with respect to behavioral style of modeling.
In the statement, case(S0 & S1 & S2), let us suppose values of S0, S1, S2 are 0,1,0 respectiv
so, S0 & S1 & S2 evaluates to 0&1&0 = 0.
And therefore the control switches to 1’b000: out=0; (i.e. 0),
instead of switching to 1’b010: out =D2;
can’t we simply leave case(S0 S1 S2) ??
Reply
1. Umair Hussaini says:
October 10, 2020 at 10:14 PM
Can you please reframe your question? I didn’t quite understand it.
Reply
1. James says:
January 2, 2021 at 10:44 PM
He’s pointing out a mistake. case(S0 & S1 & S2) should be replaced with
case({S2,S1,S0})
or
wire [2:0] select;
assign select = {S2,S1,S0};
case(select)
Reply

You might also like