You will create a debounce state machine and use this state machine to debounce the button on the NEXYS4 board to reliably count the number of times the button is pressed.
Carefully read and review Chapter 26 of the textbook. This lab will closely follow that design.
Figure 26.1 in the textbook demonstrates the “noise” that occurs with mechanical buttons or switches. In this figure, the button signal starts at zero, transitions between zero and one, and then settles down to one.
Assuming a 100 MHz clock (10 ns period), how many clock cycles are needed to implement a delay of at least 5 ms?
How many bits are needed for a counter to implement a 5 ms delay with a 100 MHz clock?
The first exercise is to create the debounce state machine. Begin this exercise by creating the module name and ports for your module as described below:
Module Name = debounce | |||
---|---|---|---|
Port Name | Direction | Width | Function |
clk | Input | 1 | 100 MHz System Clock |
reset | Input | 1 | Active high reset |
noisy | Input | 1 | Noisy debounce input |
debounced | Output | 1 | Debounced output |
As shown in Figure 26.3, the debounce circuit described in Chapter 26 is composed of two parts: a state machine and a timer. You will need to create these two parts which will be described in more detail below.
Debounce State Machine
The first part of this debounce circuit is the debounce finite state machine (Figure 26.4). You will need to create this state machine using behavioral SystemVerilog. The inputs to the state machine are “noisy”, which is a module input, and “timerDone”, which is an internal signal. The outputs of the state machine are the signals “debounced”, which is a module output, and an internal signal named “clrTimer”.
Create your debounce FSM using behavior SystemVerilog.
The diagram above shows a clr
signal that resets/initializes your state machine. You should use your reset
input to set your state machine to S0.
Debounce Timer
The second part of the debounce circuit is the debounce timer. The purpose of this timer is to wait a predetermined amount of time for the noise input signal to settle down. The description of the debounce timer is found at the end of section 26.1. For this design, however, you will be required to wait precisely 5ms instead of whatever the maximum value for your timer is. At 5ms your timer should assert “timerDone”. Your counter should be cleared when clrTimer is asserted by the state machine.
By the way, if you have a parameterized counter from a previous lab, go ahead and use it - no need to re-invent the wheel. If not, you may choose to create a counter module parameterized for both maximum count value as well as bit-width (you will be needing such a counter in essentially every lab you complete moving forward).
Exercise 1 Pass-off: Show a TA your debounce module. Explain how you implemented the state machine and how the state machine should behave when it receives a noisy input.
After completing your SystemVerilog module, you will need to simulate your module to make sure it operates as described in the textbook. Create a TCL simulation script that simulates your debounce module with the following conditions:
Include a copy of your TCL simulation script
After completing your TCL simulation, download the following testbench file and simulate your debounce circuit with this testbench. Make sure the simulation runs as long as necessary until the “simulation done” message is received (this will take about 100ms of simulation time).
Include a copy of your testbench output in your lab report
Exercise 2 Pass-off: No passoff, just make sure that you passed the testbench with zero errors.
For this exercise, you will create a top-level circuit that instances the debounce circuit for debouncing one of the push buttons. This debounce circuit will be used to increment a counter so you can verify that the counter increments only once for each button press. In addition to the debounce circuit, you will include a second counter that counts the button presses for a different button that is not debounced. You will compare the values of the two different counters to see the impact of debouncing. Begin this exercise by creating a SystemVerilog module with the following name and top-level ports:
Module Name = debounce_top | |||
---|---|---|---|
Port Name | Direction | Width | Function |
clk | Input | 1 | 100 MHz System Clock |
CPU_RESETN | Input | 1 | Active low reset |
btnc | Input | 1 | Counter button input |
anode | Output | 8 | Seven Segment Display anode outputs |
segment | Output | 8 | Seven Segment Display cathode segment outputs |
Debounce Counter
The first section of this module will include the debounce state machine and a counter. The purpose of this circuit is to accurately count the number of times a button has been pressed. Although this function sounds simple, it takes some effort to create a circuit to reliably count button presses. As shown in the figure below, there are four components associated with this section of the circuit:
1. The first first part of this circuit is the “synchronizer” whose purpose is to synchronize the asynchronous button signal to the global system clock. Because this signal is not synchronized to the clock, it is possible that this signal could cause metastability on later circuitry including the debounce state machine. You can synchronize the signal by feeding it through two flip flips, as described in section 24.3 (the textbook uses only one flip-flop - you will need to use two because of the 100 MHz clock rate).
2. Instance the your debounce
state machine and attach the output of the synchronizer to the input of your state machine. The output of your state machine is now a synchronized, debounced version of the button input.
3. Add the “edge detector” circuit. The purpose of this circuit is to create a single clock cycle pulse when the debounced button signal transitions from a zero to a one. This single clock cycle pulse will be used to increment the button counter. If you attach the output of the debounce state machine directly into the input of your counter, the counter will increment continuously for as long as the button is pressed. The edge detector is added to make sure that the counter is only incremented once each time the button goes through a 0→1 transition.
An edge detector circuit can be implemented by feeding a signal through two flip-flops (F1, then F2) and then outputting the equation F1 AND F2
'. This is shown in Figure 26.5 of the textbook.
4. The final part of this circuit is a counter that counts the button transitions. Create a 16-bit counter with an enable input. Attach the enable signal to the output of the edge detection circuit. The output from the counter will be displayed on the seven segment display. Use the reset intput to clear this counter.
Undebounced Counter
To demonstrate the behavior of the debounce circuit, a second counter is added to the top-level design which is incremented using a signal that is not debounced. The behavior of this counter will be contrasted with the debounced counter. You will use btnc as the input, the reset signal to clear, an edge detector, and a 16-bit counter, but you will not use a synchronizer or a debouncer.
Seven Segment Display
After creating your two button counters, instance the Seven Segment Controller and connect the seven segment display as described below:
Your top-level design should look something like this (clock, reset not shown):
Simulation
After completing your top-level module, create a TCL script to simulate at least three “noisy” button presses on your top-level design. Verify that your design counts properly in these noisy button press situations.
Exercise 3 Pass-off: Show a TA your top level code and your tcl script. Your simulation must show the expected behavior of your debounce module.
After successfully verifying your top-level module, create and add a .xdc file to the project and proceed with the implementation of your design.
Provide a summary of your synthesis warnings.
After successfully synthesizing your design, proceed with the implementation and bitstream generation of your design.
Indicate the number of Look-up Tables (LUT) and Input/Output (I/O) pins for your design.
Once the bitstream has been generated, download your bitstream to verify that it works correctly. After downloading your circuit, press the button several times to see if you can see a difference between the counter using the debounce state machine and the counter that does not use the debug state machine.
Summarize the results from your experiments comparing the debounced counter value to the non-debounced counter value.
How many hours did you work on the lab?
Please provide any suggestions for improving this lab in the future.
Submit your SystemVerilog modules using the code submission on Learning Suite. (Make sure your SystemVerilog conforms to the lab SystemVerilog coding standards).
Here are some ideas for personal exploration in this laboratory:
Describe your personal exploration activities