Introduction: Basic Stopwatch Using VHDL and Basys3 Board

Welcome to the instructable on how to build a stopwatch using basic VHDL and Basys 3 board. We are excited to share our project with you! This was a final project for course CPE 133 (Digital Design) at Cal Poly, SLO in Fall 2016. The project we built is a simple stopwatch that starts, resets, and pauses time. It takes in three push buttons on the Basys3 board as inputs, and the time is displayed on the board's four-digit seven-segment display. The elapsed time is displayed in a seconds : centiseconds format. It uses the board’s system clock as an input to keep track of the time elapsed and outputs the time to the four digits of the seven-segment display.

Step 1: Materials

The materials you will need for this project:

  • 1 computer with Vivado Design Suite WebPack installed from Xilinx (prefer version 2016.2)
  • 1 Digilent Basys3 Xilinx Artix-7 FPGA board
  • 1 USB port cable

Step 2: Setting Inputs and Outputs

The figure above shows a top level block diagram of the main stopwatch module. The stopwatch takes in inputs "CLK" (clock), "S1" (start button), "S2" (pause button), and "RST" (reset) and has a 4-bit output "Anodes", a 7-bit output "segment," and a single-bit output "DP" (decimal point). When input "S1" is high, the stopwatch starts counting time. When "S2" is low, the stopwatch pauses the time. When "RST" is high, the stopwatch stops and resets the time. There are four submodules within the circuit: the clock divider, the digit counter, the seven-segment display driver, and the seven-segment display encoder. The stopwatch main module links all the submodules together and to the inputs and outputs.

Step 3: Making Clocks

The clock divider module takes in a system clock and uses a divisor input to create a clock of any speed no greater than that of the system clock. The stopwatch uses two different clock modules, one which creates a 500 Hz clock and another which creates a 100 Hz clock. The schematic for the clock divider is shown in the figure above. The clock divider takes in a single-bit input "CLK", and a 32-bit input "Divisor" and the single-bit output "CLKOUT". "CLK" is the system clock and "CLKOUT" is the resulting clock. The module also includes a NOT gate, which toggles signal "CLKTOG" when the count reaches the value of the divisor.

Step 4: Counting to Ten

The digit counter counts each digit from 0 to 10 and creates another clock for the next digit to function off of that oscillates when the count reaches 10. The module takes in 3 single-bit inputs "S", "RST", and "CLK" and results in a single-bit output "N" and a 4-bit output "D". Input "S" is the enable in input. The clock turns on when "S" is high and off when "S" is low. "RST" is the reset input so the clock resets when "RST" is high. "CLK" is the clock input for the digit counter. "N" is the clock output that becomes the input clock for the next digit. Output "D" presents the binary value of the digit the counter is at.

Step 5: Displaying Numbers

The seven-segment display encoder will encode the binary number received from the seven-segment display driver module and turn it into a stream of bits that will be interpreted as '1' or '0' values for each segment of the display. The binary number is received by the module as the 4-bit input "digit" and results in the 7-bit output "segments". The module consists of a single case process block that assigns a specific 7-bit stream for each possible input value from 0 to 9. Each bit in the seven-bit streams represent one of the seven segments of the digits on the display. The order of the segments in the stream is “abcdefg” with ‘0’s representing the segments that light up for the given number.

Step 6: How to Display the Stopwatch

In the seven-segment display driver module, there are four 4-bit inputs "D0", "D1", "D2", and "D3", each representing the four digits to be displayed. Input "CLK" is the clock input of the system. Single-bit output "DP" represents the decimal point on the seven-segment display. The 4-bit output "Anodes" determines which digit on the seven-segment display is shown and the 4-bit output "temp" depends on the state of the 2-bit control input "SEL". The module uses 4 multiplexers for the control input "SEL" and the three outputs; "Anodes", "temp", and "DP".

Step 7: Bringing It All Together

An 'if' process block running off of the 500Hz clock is used to create the start and pause buttons. Then link all of the submodules together in the stopwatch main module by declaring the components of each individual submodule and using various signals. The digit submodules take in the clock output of the previous digit submodule with the first one taking in the 100Hz clock. The "D" outputs of the digit submodules then become the "D" inputs of the seven segment display driver module. And lastly the "temp" output of the seven segment display driver module becomes the "temp" input of the seven segment encoder module.

Step 8: Constraints

Use 3 push buttons (W19, T17, and U18) for inputs "RST", "S1", and "S2". W19 is the reset button, T17 is the start button (S1), and U18 is the pause button (S2). A constraint for the clock input input is also required using port W5. Also, remember to add this line to the clock constraint:

create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {CLK}]

Also link the Anodes and segments to the board so the stopwatch is displayed on the seven-segment display as seen in the constraints file.

Step 9: Testing

Make sure your device works by playing with the three buttons: pushing and holding them in every possible order in order to find any possible problems with your code.