Introduction: Project 5: Multiplexer, Decoder, Encoder, and Shifter

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.

What you need:

-Have the Xilinx® Vivado WebPACK™ installed.

-Have your FPGA board set up.

-Be able to write combinational logic using logic operators in Verilog and implement them on an FPGA.

While all the basic theory will not be covered here, these links can provide you with the relevant background you will need:

-Multiplexers

-Binary Decoder

-Priority Encoder

-Shifter

Step 1: Multiplexers

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, S0 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.

Step 2: Design a Multiplexer

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.

Create a project in Xilinx Vivado targeting the FPGA board you are using, as you have done in previous labs.

Create a Verilog module called mux_4_1 with inputs I0, I1, I2, I3, Sel and output Y as follows:

1 module mux_4_1 (
2 input [1:0] I0,

3 input [1:0] I1,

4 input [1:0] I2,

5 input [1:0] I3,

6 input [1:0] Sel,

7 output [1:0] Y

8 );

Step 3: Ways to Code the Mux

The first way to code a mux behaviorally is to use the “?:” selection operator. This method is most analogous to the if statement. The way I read it is, assign Y to I0 if the statement in the parenthesis is true, else do the stuff after the colon, and so on.

1 assign Y = (Sel == 2'd0) ? I0 : (

2 (Sel == 2'd1) ? I1 : (

3 (Sel == 2'd2) ? I2 : I3

4 )

5 );

The second way to code a mux is by using an always block together with an “if” statement. However, as Y is assigned in an always block, Y needs to be declared as type reg.

1 reg [1:0] Y;

2

3 always @ (Sel, I0, I1, I2, I3)

4 begin

5 if (Sel == 2'd0) 6 Y = I0;

7 else if (Sel == 2'd1)

8 Y = I1;

9 else if (Sel == 2'd2)

10 Y = I2;

11 else 12 Y = I3;

13 end

The third way to code a mux is by using an always block together with a “case” statement.

1 reg [1:0] Y;

2

3 always @ (Sel, I0, I1, I2, I3)

4 begin

5 case (Sel)

6 2'd0:

7 Y = I0;

8 2'd1:

9 Y = I1;

10 2'd2:

11 Y = I2;

12 2'd3:

13 Y = I3;

14 default: 15 Y = 2'd0;

16 endcase

17 end

Finally, create an XDC file and map the following:

- I0[0] to SW0, I0[1] to SW1

- I1[0] to SW2, I1[1] to SW3

- I2[0] to SW4, I2[1] to SW5

- I3[1] to SW6, I3[2] to SW7

- Sel[0] to BTN0, Sel[1] to BTN1

- Y[0] to LED0, Y[1] to LED1

Step 4: Binary Decoder

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 2N 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 above, 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.

Step 5: Design a Binary Decoder

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.

Create a project in Xilinx ISE targeting the FPGA board you are using, as in the previous projects.

Create a Verilog module called decoder_3_8 with inputs I and output Y as follows:

1 module decoder_3_8 (
2 input [2:0] I,

3 output [7:0] Y

4 );

The most efficient way to describe the behavior of a decoder is to use a case statement in an always block.

1 reg [7:0] Y;
2

3 always @ (I)

4 begin

5 case (I)

6 3'd0:

7 Y = 8'd1;

8 3'd1:

9 Y = 8'd2;

10 3'd2:

11 Y = 8'd4;

12 3'd3:

13 Y = 8'd8;

14 3'd4:

15 Y = 8'd16;

16 3'd5:

17 Y = 8'd32;

18 3'd6:

19 Y = 8'd64;

20 3'd7:

21 Y = 8'd128;

22 default:

23 Y = 8'd0;

24 endcase

25 end

Create a XDC File and map:
- I[2:0] to SW2, SW1, SW0

- Y[7:0] to LED 7-0

Step 6: Priority Encoder

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=log2N). 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 above.

Step 7: Design a Priority Encoder

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.

Create a project in Xilinx Vivado targeting the FPGA board you are using, as in previous projects.

Create a Verilog module called encoder with inputs I, Ein, and outputs Eout, GS, and Y as follows:

1 module decoder_3_8 (
2 input [3:0] I,

3 input Ein,

4 output [1:0] Y,

5 output GS,

6 output Eout

7 );

The most efficient way to describe the behavior of a priority encoder is to use if statement in an always block. As we have three outputs here, we will code the behavioral description for those three outputs in three always blocks.

1 reg [1:0] Y;
2 reg GS;

3 reg Eout;

4

5 always @ (I, Ein)

6 begin

7 if(Ein == 1)

8 Y = (I[3] == 1) ? 2'd3 : (

9 (I[2] == 1) ? 2'd2 : (

10 (I[1] == 1) ? 2'd1 : 2'd0

11 )

12 );

13 else

14 Y = 2'd0;

15 end

16

17 always @ (I, Ein)

18 begin

19 if (Ein == 1 && I == 0)

20 Eout = 1'b1;

21 else

22 Eout = 1'b0;

23 end

24

25 always @ (I, Ein)

26 begin

27 if (Ein == 1 && I != 0)

28 GS = 1'b1;

29 else

30 GS = 1'b0;

31 end

Create a XDC File and map:

- I[3:0] to SW3, SW2, SW1, SW0
- Ein to SW7

- Y[1:0] to LED 1-0

- Eout to LED 7

- GS to LED 6

Step 8: Shifter

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 above in Fig. 5. There are three control bits (D, R, En) in the example. They enable different functions:

-A Fill signal (F) determines whether bits vacated by shift operations receive a '1' or a '0'.

- A Rotate signal (R = '1' for rotate) determines whether shifted-out bits are discarded or recaptured in vacated bits.

-A Direction signal (D = '1' for right) determines which direction the shift will take.

- An Enable signal (En = '1' for shift by 1 bit, '0' for shift by 0 bit, i.e., bypass) determines whether a shift operation needs to be done.

Step 9: Design a Shifter

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.

Create a project in Xilinx Vivado targeting the FPGA board you are using, as in previous projects.

Create a Verilog module called “shifter” with inputs I, En, D, R, F and outputs Y as follows:

1 module decoder_3_8 (
2 input [3:0] I,

3 input D,

4 input R,

5 input F,

6 input En,

7 output [3:0] Y

8 );

Similar to previous steps, we are going to use if statement again to implement the shifter.

1 reg [3:0] Y;
2

3 always @ (I, Ein)

4 begin

5 if (En == 0)

6 Y = I;

7 else

8 if (R == 0)

9 Y = (D == 0) ? {I[2:0], F} : {F, I[3:1]};

10 else

11 Y = (D == 0) ? {I[2:0], I[3]} : {I[0], I[3:1]};

12 end

In the previous code, {A,B} is used to concatenate two groups of signals into a bus. For example, Y = {I[2:0], F} means Y[3:1] = I[2:0] and Y[0] = F.

Create a XDC File and map:

-I[3:0] to SW3, SW2, SW1, SW0
-R to SW7, D to SW6, F to SW5

- En to Btn0

-Y[3:0] to LED 3-0

Step 10: Test Your Knowledge

Now that you've completed this project, try these modifications:

Create a test fixture for each of the circuits discussed in this section (multiplexer, decoder, priority encoder, and shifter). Keep in mind to test all possible input patterns.

-Challenge Problem-

If you are confident in your ability to design a multiplexer, a decoder, an encoder, and a shifter using Verilog HDL,
go ahead and try out the design challenge problem below for some extra practice!

-Design Problem 1