In this project you will design a multiplexer, a decoder, an encoder, and a shifter using Verilog HDL. Instead of building the circuit using logic operators, you will learn to describe a circuit behaviorally according to the functionality you wish the circuit to perform.
Qty | Description |
---|---|
1 | Digilent^{®} Nexys™4, Nexys™3, Nexys™2, or Basys™2 FPGA Board |
1 | Xilinx ISE Design Suite: WebPACK (14.6 Recommended) |
1 | Digilent Adept |
Data selectors, more commonly called multiplexers (or just “muxes”), function by connecting one of their input signals to their output signals as directed by their “select” or control input signals. Figure 1 shows the truth table, logic graph, and block diagram of a 4-to-1 mux, where I0, I1, I2, I3 are four data inputs, Y is the output, S1 and S1 are select signals.
Since most data elements in computer systems are bytes, or words consisting of 8, 16, 32 or more bits, muxes used in computer circuits must switch 8, 16, 32, or more signals all at once. Muxes that can switch many signals simultaneously are called “bus muxes”. A block diagram and schematic for a bus mux that can select one of four 8-bit data elements is shown in Fig. 2.
This project starts with designing a 4-1 2-bit bus multiplexer. Eight on-board slide switches will be used to provide the data inputs, two push buttons will be used as select signals, and LEDs 0 and 1 will be used to show the output of the multiplexer. Instead of implementing the multiplexer using logic operators, we are going to describe the circuit behaviorally using an always block and an if statement, or a case statement.
We are presenting three ways to code the multiplexer behaviorally here. However, you only need one in your code. You are encouraged to try out all three of the different ways so as to understand and experience the difference in Verilog syntax.
module mux_4_1 (
input [1:0] I0,
input [1:0] I1,
input [1:0] I2,
input [1:0] I3,
input [1:0] Sel,
output [1:0] Y
);
assign Y = (Sel == 2'd0) ? I0 : (
(Sel == 2'd1) ? I1 : (
(Sel == 2'd2) ? I2 : I3
)
);
reg [1:0] Y;
always @ (Sel, I0, I1, I2, I3)
begin
if (Sel == 2'd0)
Y = I0;
else if (Sel == 2'd1)
Y = I1;
else if (Sel == 2'd2)
Y = I2;
else
Y = I3;
end
reg [1:0] Y;
always @ (Sel, I0, I1, I2, I3)
begin
case (Sel)
2'd0:
Y = I0;
2'd1:
Y = I1;
2'd2:
Y = I2;
2'd3:
Y = I3;
default:
Y = 2'd0;
endcase
end
Decoder circuits receive inputs in the form of an N-bit binary number and generate one or more outputs according to some requirement. A binary decoder has $N$ inputs and $2^N$ outputs. If the N inputs are taken as an N-bit binary number, then only the output that corresponds to the input binary number is asserted. For example, in the 3:8 binary decoder shown in Fig. 3 below, if a binary 5 (or “101”) is presented on the input of the decoder, then only the 5th output of the decoder (Y5) will be asserted and all of the other outputs will be de-asserted.
In this section we are going to design a 3:8 binary decoder. Switches 0 to 2 are used as the inputs for 3:8 decoder and 8 on-board LEDs are used to indicate the output of the decoder.
module decoder_3_8 (
input [2:0] I,
output [7:0] Y
);
reg [7:0] Y;
always @ (I)
begin
case (I)
3'd0:
Y = 8'd1;
3'd1:
Y = 8'd2;
3'd2:
Y = 8'd4;
3'd3:
Y = 8'd8;
3'd4:
Y = 8'd16;
3'd5:
Y = 8'd32;
3'd6:
Y = 8'd64;
3'd7:
Y = 8'd128;
default:
Y = 8'd0;
endcase
end
An encoder essentially performs the reverse of a decoder function in a combinational logic. It receives N inputs (where N is typically power of two, i.e., 4, 8, 16, etc.), and asserts an output binary code of M bits (usually $M=log_{2}N$). The M-bit binary code indicates which input was asserted. Since more than one input line to the encoder might be asserted at any given time, the priority encoder asserts an output code corresponding to the highest numbered input that is asserted. The truth table and block diagram of a priority encoder is displayed in Fig. 4 below.
In this section, we are going to design a 4-input priority encoder. Four on-board switches will be used as data inputs. Another slide switch will act as “Enable” signal. Two LEDs will show the encoded value of inputs, and another two LEDs act as the “GS” and the “Eout” Signal.
module decoder_3_8 (
input [3:0] I,
input Ein,
output [1:0] Y,
output GS,
output Eout
);
reg [1:0] Y;
reg GS;
reg Eout;
always @ (I, Ein)
begin
if(Ein == 1)
Y = (I[3] == 1) ? 2'd3 : (
(I[2] == 1) ? 2'd2 : (
(I[1] == 1) ? 2'd1 : 2'd0
)
);
else
Y = 2'd0;
end
always @ (I, Ein)
begin
if (Ein == 1 && I == 0)
Eout = 1'b1;
else
Eout = 1'b0;
end
always @ (I, Ein)
begin
if (Ein == 1 && I != 0)
GS = 1'b1;
else
GS = 1'b0;
end
A shifter is a circuit that produces an N-bit output based on an N-bit data input and some control bits, where the N output bits are place-shifted copies of the input bits, and the way the bits will be shifted is determined by the control bits. As an example, the truth table for a 4-bit shifter is shown below in Fig. 5. There are three control bits (D, R, En) in the example. They enable different functions:
In this section, we are going to design a 4-input Shifter. Four on-board switches will be used as data inputs. Three other slide switches will act as control signals F, R, and D. A push button will be used as the Enable signal. Four LEDs will show the output of the shifter.
module decoder_3_8 (
input [3:0] I,
input D,
input R,
input F,
input En,
output [3:0] Y
);
reg [3:0] Y;
always @ (I, Ein)
begin
if (En == 0)
Y = I;
else
if (R == 0)
Y = (D == 0) ? {I[2:0], F} : {F, I[3:1]};
else
Y = (D == 0) ? {I[2:0], I[3]} : {I[0], I[3:1]};
end
Now that you've completed this project, try these modifications: