Project 2: Demultiplexer

B441/E315, Fall 2018                                                        Version 2018.2

Due Date: Sept 7, 2018

Overview

In this lab you will design and implement a 3-to-8 Demultiplexer.  Demultiplexers help control the logical flow of the digital circuit, and are used in addressing memory and may types of data communication.

Background

To understand demultiplexers, one should first understand a decoder.  

Decoder

A decoder is a combinational circuit with n inputs and 2n output. For each combination of inputs, one and only one output logic 1, while all the other outputs are logic 0. For example, a decoder with 3 inputs {a, b, c} will have 8 outputs {d0, d1, d2, d3, d4, d5, d6, d7}. This circuit is also sometimes called a “one-hot”, as only one of the output is ‘1’ (or hot) at a time.  

The truth table for the decoder is shown below.

 

a

b

c

d0

d1

d2

d3

d4

d5

d6

d7

0

0

0

1

0

0

0

0

0

0

0

0

0

1

0

1

0

0

0

0

0

0

0

1

0

0

0

1

0

0

0

0

0

0

1

1

0

0

0

1

0

0

0

0

1

0

0

0

0

0

0

1

0

0

0

1

0

1

0

0

0

0

0

1

0

0

1

1

0

0

0

0

0

0

0

1

0

1

1

1

0

0

0

0

0

0

0

1

As each output is ‘1’ for only a single combination of inputs, a boolean expression that produces a particular output can be constructed by testing for the specific input combination.  For example, output d1 is logic 1 only if:

a = 0

b = 0

c = 1

Thus, each output can be produced by AND-ing the input signals, if the input signal is 0, we apply NOT operation and if the input signal is 0, we take the original signal (skipping the NOT operation).

For example, the Boolean expression for the output d1 will be:

a

b

c

d1

The expression for d1:

0

0

1

1

~a & ~b & c

The full schematic for a 3-input decoder is:

This is often abstracted to a “decoder” box which looks similar to this:

Note that the notations “~a”, “a’”, and “ā” are all logical equivalents of the same “NOT(a)”.  

Demultiplexer

A demultiplexer is a combinational circuit with 1 data input, n select inputs and 2n outputs. For each combination of select inputs, data is transferred to the corresponding output, while the other outputs are 0.  It is very similar to a decoder, except the output signal is dependent on an additional input, rather than always fixed to ‘1’.  

For example, a simpler 2-to-4 (or just 2-4) demultiplexer is shown below.  It has 1 data input (e), 2 select inputs (a and b), and 4 outputs (d0 - d3).

With a demultiplexer, when a = 1 and b = 1, the input e is transferred to the output d3, while other outputs are 0. This is illustrated with the different colors in the truth table below. The ‘e’ signal is used to ‘e’nable the selected output signal.  

 

a

b

e

d0

d1

d2

d3

0

0

0

0

0

0

0

0

0

1

1

0

0

0

0

1

0

0

0

0

0

0

1

1

0

1

0

0

1

0

0

0

0

0

0

1

0

1

0

0

1

0

1

1

0

0

0

0

0

1

1

1

0

0

0

1

Submodules

Submodules in Verilog allow you to use smaller modules as building blocks for constructing more complex modules.  Recall from lecture that we can construct a TwoBelt Alarm system by creating two BeltAlarm submodules, as show below.  

In Verilog, we recommend using this method to construct submodules:

        SubModuleName SubModule_InstanceName (

                        .subModuleVariableName1(localVariableName1),

                        .subModuleVariableName2(localVariableName2)

        );

 

SubModuleName is the name as it appears in the submodules verilog file.  It will be the same for all instances of the submodule.   SubModule_InstanceName is the name given for a particular submodule instance.  You can instantiate multiple of the same submodules, but they must have different InstanceNames.  subModuleVariableNames signals must match those given in the submodule’s verilog file.  localVariableNames signals must match a signal in the current module (not the submodule).  

If BeltAlarm looks like this:

module BeltAlarm(

  input k, p, s,

  output alarm  

);

        assign alarm = k & p & ~s;

endmodule

Then you can create a TwoBeltAlarm by instantiating two BeltAlarm modules as shown below.  Notice that there are two BeltAlarm modules, but they both have different names, ba_drv and ba_pas.  Also, their output is OR’ed together to form the output of the overall TwoBeltAlarm module

module TwoBeltAlarm(

  input k, st_pas, sb_pas,

  input st_drv, sb_drv

  output alarm

);

  wire al_pas, al_drv; //intermediate wires

 

  //submodules,

  BeltAlarm ba_drv(.k(k), .p(st_drv),

             .s(sb_drv), .alarm(al_drv) );

  BeltAlarm ba_pas(.k(k), .p(st_pas),

             .s(sb_pas), .alarm(al_pas));

 

  assign alarm = al_pas | al_drv;

endmodule

Assignment Description

For this assignment, you will need to create a 3-8 decoder, then use it as a submodule to create a 3-8 demultiplexer.  You will also need to create a corresponding testbench.  

Decoder

First, start by creating a Verilog file named decoder.v defined as follows:

module decoder(

         input a, b, c,

         output d0, d1, d2, d3, d4, d5, d6, d7

         );

You will need to assign the correct expressions for the outputs d0-d7 to match the decoder truth table given in the Background section. The expression for d1 was given for you.

Although not required, we recommend constructing a testbench to ensure the correctness of your decoder.  

Demultiplexer

Now create a top.v that will serve as your demultiplexer by including the e signal.  

module top(

         input a, b, c,

        input e,

         output d0, d1, d2, d3, d4, d5, d6, d7

         );

You will now need to instantiate a decoder submodule within your top-level demultiplexer module.  See the Background section for an example.  Additional signals internal to your demultiplexer can be created with the wire command as follows:

   wire new_wire;

Your demultiplexer module will need to modify the outputs for the decoder’s d0-d7 signals for its own d0-d7 outputs.   Remember the corresponding d output should be 0 when e==0, and the same as the original decoder when e == 1.

Testbench

You will also need to create a test bench called top_tb.v to test your code.  Remember to select “System Verilog” from the “File Type” drop-down menu. You can use the following starter code:

`timescale 1ns / 1ps

module testbench;

 

        reg a, b, c;

        reg e;

        wire d0,d1,d2,d3,d4,d5,d6,d7;

        top demux0 (

            .a(a),

            .b(b),

            .c(c),

            .e(e),

            .d0(d0),

            .d1(d1),

            .d2(d2),

            .d3(d3),

            .d4(d4),

            .d5(d5),

            .d6(d6),

            .d7(d7)

         );

        

        initial

        begin

        //your testcode here!

            $display("@@@Passed");

            $finish;

 

        end

endmodule

Your testbench should ensure the correct output for all 16 possible input combinations of a, b, c, and e.   Recall, you can use the following verilog line to test a signal:

assert( led == 0) else $fatal(1, "led==0 Failed");

Please ensure your testbench module is named testbench.

If you miss an input combinations, the autograder will detect it during testing.  

Constraints

You will also need to reconfigure your constraints file so use the following assignments of switches and LEDs:

                        Verilog Name                Pin Name                PACKAGE_PIN

a                      sw0                        V17

b                      sw1                        V16

c                              sw2                        W16

e                        sw4                        W15

 

d0                     led0                        U16

d1                     led1                        E19

d2                     led2                        U19

d3                     led3                        V19

d4                     led4                        W18

d5                             led5                        U15

d6                             led6                        U14

d7                             led7                        V14

Evaluation

The evaluation will have two steps, first submission of your source code and testbench to the autograder.  Second, you will need to synthesize your design, download it to the FPGA and do a demonstration for the TA.

Autograder (60%)  

Log on to https://autograder.sice.indiana.edu and submit your code as per Lab 1.

Demonstration (40%)

Program your FPGA with your demultiplexer and demonstrate your working system to the TA.  You will not receive full points until the TA has approved your demonstration.