Simple Combinational Circuit Design

Project 4: Majority of Five

Introduction

How could you find a majority of the vote if each of five voters has a switch to vote for yes or no? The logic is fairly simple and will be used in this project. Any time there are three or more of the five who vote yes, then there is a majority and the LED needs to turn on.

Before you begin, you should:
  • Have the Xilinx® ISE WebPACK™ installed.
  • Have your FPGA board set up.
  • Be able to define a logic circuit using a truth table.
  • Be able to derive a logic equation from a truth table.
  • Be able to describe logic functions using Verilog HDL and implement them on an FPGA.
After you're done, you should:
  • Understand and be able to use Boolean Algebra.
  • Know how to create a K-Map from a truth table.
  • Know how to create minimized logic equation using K-map.
  • Know how to run a Verilog Circuit Simulation.

Inventory:

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

Background Knowledge

If a truth table is completed for the logic equation, it is a fairly easy step to get a maxterm equation and simplify it with an entered variable K-map. Knowing how to use and read a K-map is a fundamental step in creating a digital circuit with minimum transistors and no redundancies.

Step 1: Define Top Module and I/Os

Start a new project as instructed in previous projects. Use a blank Verilog file and construct a proper UCF file for your board.
For this project, we are going to utilize 5 inputs and an LED as an output. The LED will illuminate whenever the majority of voters vote yes.

An example of the module and I/O declaration for Verilog file is shown as follows:

				module top(
					input [4:0] sw,
					output Led
				);
			

Step 2: Construct a Minimum Logic Expression From the Truth Table Using K-Map

  1. Assume that there are 5 people (A, B, C, D, and E). If three or more of them vote yes, represented by a “1”, the result is 1. Using this information, fill in a K-map to represent the logic expression. It should result in a super K-map as displayed in Fig. 1 below.
    Figure 1. Truth table presented in a super K-Map.
  2. It is pretty difficult to loop a super K-map, so we need to compress it in order to make looping plausible.
    Figure 2. Compress the super K-Map with entered variables.
  3. Now that the K-map has been compressed, it is time to loop it. There is only one variable E here, so we consider loops with the entered variable E first. You can compare your loop result to the graph below in Fig. 3. You should have six loops to correspond to the six product terms.
    Figure 3. SOP loops with entered variable E.
  4. Now that we have covered the cells with variable E, it is time to see if all of the information in the K-map is looped. By looking at the K-map, we can see that there are a few more loops that we need to create. The column partition of the cell with the value '1' is not covered by a loop in the previous step. In order to create a fully looped K-map these cells need to be looped. You may check your loops with the graph below in Fig. 4. There should be 4 loops corresponding with the 4 product terms.
    Figure 4. SOP loops with the value 1.
  5. From the logic diagram that you have created it is now possible to construct the logic expression in SOP form as follows: \[\begin{align} Y=& A\cdot B\cdot C + A\cdot B\cdot D +A\cdot C\cdot D +B\cdot C\cdot D + A\cdot B\cdot E + A\cdot D\cdot E + \\ & A\cdot C\cdot E +B\cdot C\cdot E + C\cdot D\cdot E +B\cdot D\cdot E \end{align}\]
  6. From this SOP equation you can build a simple assign statement to control the LED wire. The following code uses “&” as the symbol for logic AND and “|” as the symbol for logic OR. This uses “assign” statements, which were discussed in-depth in prior projects. The “assign” statement and the LED will be held at logic high whenever the combinational logic statement is true.
    				assign led = (sw[0] & sw[1] & sw[3]) |
    							 (sw[0] & sw[1] & sw[2]) |
    							 (sw[1] & sw[2] & sw[3]) |
    							 (sw[0] & sw[2] & sw[3]) |
    							 (sw[0] & sw[1] & sw[4]) |
    							 (sw[2] & sw[3] & sw[4]) |
    							 (sw[0] & sw[2] & sw[4]) |
    							 (sw[0] & sw[3] & sw[4]) |
    							 (sw[1] & sw[3] & sw[4]) |
    							 (sw[1] & sw[2] & sw[4]);
    				
  7. Finally, make sure that the module is closed with “endmodule”.
    			 		endmodule
    				

Step 3: Verify the Circuit in Simulator

How can we tell if a complex logic block is working as expected?

The Verilog code can be simulated by utilizing a Verilog test fixture, also called a test bench. To add a test fixture, you will need to add a file like you would when starting a new module, only you will select “Verilog Test Fixture” rather than “Verilog Module”. This will open up a template for the test fixture. The comments section has been removed for readability.

			'timescale 1ns/ 1ps
			

Here we need to talk about 'timescale. The 'timescale compiler directive defines the units used in a delay command, which is simply “#50”. This means that there is a delay for 50 units defined in the 'timescale compiler directive. The value before the backslash is the delay unit and the value after the backslash defines the smallest increment that can be used in the delay.

The test fixture block of code is a module just like a typical Verilog module but functioning in test fixture, we artificially manipulate the inputs and can examine how the circuit behaves in simulation.

  1. Declare a test bench.

    The test fixture is named “testbench” in this example and defines the input and outputs that we are interested in from the block of code that is being tested. Unlike the circuit that was built as a Verilog Module, a test bench is a module that has no input or output port. It only has internal signals that are connected to the circuit under test (CUT). It generates inputs for the CUT and senses the outputs of the CUT to verify that the CUT is implemented as specified.

    						module testbench;
    						
    						// Inputs
    						reg [4:0] sw;
    						// Outputs
    						wire Led;
    					
  2. Instantiate the “majority of five” in the test bench.

    The top module is instantiated in the test fixture. The input port “sw” of the top module is connected to an internal register called sw as declared in the previous step, the output port LED is connected to the wired LED. Later projects will go into further detail on instantiating.

    						// Instantiate the Unit Under Test (UUT)
    						top uut (
    							.sw(sw),
    							.Led(Led)
    						);
    					
  3. Generating the stimulus in the test bench.

    In this part of the project, you will start writing codes to generate stimulus for the “majority of five” circuit. Initial block is used here to code the stimulus generation. Initial block will be processed only once by the simulator. Before the initial block, we will define an integer k, so that we can loop through all the possible input combinations for the “majority of five” circuit. Inside the initial block, we will initialize all the input to zero. A for statement is used to loop through all the input possibilities. One input pattern will be held at the input for 50 ns before updating to the next input pattern. After cycling through all of the possible input patterns, the $finish command is used to end the simulation. The code is shown as follows:

    						// Declare loop index variable
    						integer k;
    						
    						// Apply input stimulus
    						initial
    						begin
    							sw = 0;
    						
    							for (k=0; k<32; k=k+1)
    								#5 sw = k;
    						
    							#20	$finish;
    						end
    					
  4. Finish the fixture.

    Finally, we close the module as usual with endmodule.

    						endmodule
    					
  5. So the test bench should look like the following:
    						'timescale 1ns/ 1ps
    
    						module testbench;
    						
    						// Inputs
    						reg [4:0] sw;
    						// Outputs
    						wire Led;
    						
    						// Instantiate the Unit Under Test (UUT)
    						top uut (
    							.sw(sw),
    							.Led(Led)
    						);
    
    						// Declare loop index variable
    						integer k;
    						
    						// Apply input stimulus
    						initial
    						begin
    							sw = 0;
    						
    							for (k=0; k<32; k=k+1)
    								#5 sw = k;
    						
    							#20	$finish;
    						end
    						
    						endmodule
    					
  6. Now that the code is done, change the view from implementation to simulation, as shown in Fig. 5.
    Figure 5. Change from “Implementation View” to “Simulation View” in the project tab.
  7. Select the test fixture and double click the “Simulate Behavioral Model” in the processes tab, as shown in Fig. 6.
    Figure 6. Double-click “Simulate Behavioral Model” to start simulation.
  8. An ISim window will open looking like Fig. 7:
    Figure 7. ISim window.
  9. Expand the “sw” category. Click on the zoom to fully view the button and the view will show the changing inputs that were coded in the counter, as displayed in Fig. 8.
    Figure 8. Simulation Waveform shows that the inputs change every 5 ns.
  10. Click on the button and it will progress the test for the time in the dropdown box. Now you can see the entire loop in action.

    The top line in Fig. 9 shows when an LED is held high and any time there are three to five switches turned on so the LED would turn on. You have now successfully run a Verilog Simulation for Majority of Five!

    Figure 9. Verify the circuit we designed by matching the waveform to the description of circuit intended functionality.

    The above are screenshots of Xilinx ISE WebPACK running on Windows 7.

Test Your Knowledge!

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

  • Come up with a POS equation by looping the K-Map again and simulate the POS circuit.
  • Try to code the logic expression in an un-optimized fashion (same as we did in previous projects). Use View RTL Schematic / Technology Schematic under Synthesize Step in Implementation View to see how the tools optimize the function. Is it the same as what we did by hand?

Challenge Problem

  • If you are confident in your understanding of the majority of five, go ahead and try out the design challenge problem below for some extra practice!

  • Other product and company names mentioned herein are trademarks or trade names of their respective companies. © 2014 Digilent Inc. All rights reserved.