Say you have a voting system with 5 voters. Say they won if a majority of the voters voted yes. How could you find out if there was a majority win? 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.
|1||Digilent® Nexys™4, or Basys™3 FPGA Board|
|1||Xilinx Vivado Design Suite: WebPACK (2014.4 Recommended)|
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.
Start a new project as instructed in previous projects. Use a blank Verilog file and construct a proper XDC 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 );
assign led = (sw & sw & sw) | //ABC (sw & sw & sw) | //ABD (sw & sw & sw) | //ACD (sw & sw & sw) | //BCD (sw & sw & sw) | //ABE (sw & sw & sw) | //ADE (sw & sw & sw) | //ACE (sw & sw & sw) | //BCE (sw & sw & sw) | //CDE (sw & sw & sw); //BDE
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 right click on Simulation Sources and click Edit Simulation Sets.
When the window opens click Create file, and name the file majority_of_five_test_fixture.
Once the file is created it will be under the Simulation Sources section of the project manager sources tab. Expand this section and double click the file you just created. The file will contain a template for a module. You can delete everything in this file, we will write the test fixture ourselves.
The first line of the test fixture should contain the timescale. You may recognize this line from the other Verilog files we created.
'timescale 1ns/ 1ps
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.
I named the test bench to match the simulation file we created. The next two lines define the inputs and outputs we are interested in testing. Unlike the circuit that was built as a Verilog Module, a test bench is a module that has no input or output ports. 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 majority_of_five_test_fixture; // Inputs reg [4:0] sw; // Outputs wire led;
Next we need to instantiate the module that we are testing. The majorityof5 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) majorityof5 uut ( .sw(sw), .led(led) );
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 20 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) #20 sw = k; #20 $finish; end
Finally, we close the module as usual with endmodule.
'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) #20 sw = k; #20 $finish; end endmodule
Now that you've completed this project, try these modifications: