Table of Contents
Overview
design features
The purpose of digital stopwatch design
Module simulation
design code
Overview
This design is a digital stopwatch for sports competitions. It is programmed using VHDL language based on FPGA under the Quartus II 9.0sp2 software. Computer simulation is carried out using the EP2C8Q208 chip of ALTRA’s CycloneII series, and the corresponding simulation results are given. This design effectively overcomes the shortcomings of the traditional digital stopwatch and adopts EDA technology to adopt a top-down design idea. The specific logic circuit was drawn, and finally it was debugged and verified on hardware. This circuit can achieve good timing function, high timing accuracy, and the longest timing time can reach one hour.
Design function
1. Complete a digital stopwatch with hours, minutes and seconds display;
2, 12, and 24 hours can be adjusted;
3. Can be used as a stopwatch;
4. Able to display countdown;
The purpose of digital stopwatch design
The purpose of this design is to understand EDA technology on the basis of mastering the preliminary use of the EDA experimental development system, further understand the clock control system in the computer system, master the working principle of the state machine, and understand how computer clock pulses are generated and work. (omitted here)
Module Simulation
Design Code
(The code is long, complete The project is shared for free, if you need to obtain it, please follow: FPGA Garden)
module time_clock( clk, reset_n, hour_select_key, second_counter_key, second_countdown_key, pause_key, Duan, wei ); input clk; //clk:50MHZ clock input; input reset_n; //Reset signal input, low level is active; input hour_select_key; //The key can be adjusted for 12 and 24 hours. When it is '1', it is 24, and when it is '0', it is 12 hours; input second_counter_key; //When the key is '1', it is the stopwatch timing function, and when '0', it is the normal function; input second_countdown_key; //When the key is '1', it is the countdown function, and when '0', it is the normal function; input pause_key; //Pause function button, you can use this button to pause when performing stopwatch timing and countdown, '1' pauses, '0' continues output [7:0] duan; //duan: digital tube segment code; output [7:0] wei; //wei: digital tube bit code; reg [7:0] duan; //duan: digital tube segment code; reg [7:0] wei; //wei: digital tube bit code; reg [24:0] count; //1HZ clock counter reg [13:0] count2; //Scan clock counter reg clk_1hz; //1HZ clock signal reg [3:0] miao_ge; //Second single digit BCD code reg [2:0] miao_shi; //Ten-digit second BCD binary code reg [3:0] fen_ge; //Single digit number of minutes reg [2:0] fen_shi; //tens of minutes reg [1:0] shi_ge; //clock single digit reg [1:0] shi_shi; //clock ten digits reg [1:0] shi_select_ge; //clock selection single digit, used to adjust the time system reg [1:0] shi_select_shi; //Clock selects ten digits, used to adjust the time system reg clk_scan; //Nigital tube scan clock reg [2:0] select; //Used to select display bitcode when scanning //************************************************ *************************************************** ** //Module name: second clock frequency division module // Function description: //************************************************ *************************************************** ** always @(posedge clk or negedge reset_n)//1HZ clock process begin if(reset_n == 1'b0) begin count <= 25'd0; clk_1hz <= 1'b0; end else if(count == 25'd25000000) begin clk_1hz <= ~clk_1hz; count <= 25'd0; end else count <= count + 1'b1; end reg [17:0] counter_count; reg clk_100hz; always @(posedge clk or negedge reset_n)//100HZ clock process begin if(reset_n == 1'b0) begin counter_count <= 18'd0; clk_100hz <= 1'b0; end else if(~pause_key == 1'b0) if(counter_count == 18'd250000) begin clk_100hz <= ~clk_100hz; counter_count <= 18'd0; end else counter_count <= counter_count + 1'b1; else begin clk_100hz <= 1'b0; counter_count <= 18'd0; end end //************************************************ *************************************************** ** //Module name: timing adjustment module // Function description: //************************************************ *************************************************** ** always @(posedge clk or negedge reset_n)//1HZ clock process begin if(reset_n == 1'b0) begin shi_select_ge <= 2'd3; shi_select_shi <= 2'd2; end else if(hour_select_key == 1'b1)//The key can be adjusted for 12 and 24 hours. When it is '1', it is 24, and when it is '0', it is 12 hours begin shi_select_ge <= 2'd3; shi_select_shi <= 2'd2; end else begin shi_select_ge <= 2'd1; shi_select_shi <= 2'd1; end end //************************************************ *************************************************** ** //Module name: Second timing module // Function description: //************************************************ *************************************************** ** always @(posedge clk_1hz or negedge reset_n)//Every second and minute accumulation function process begin if(reset_n == 1'b0) begin miao_ge <= 4'd9; miao_shi <= 3'd5; fen_ge <= 4'd9; fen_shi <= 3'd5; shi_ge <= 2'd3; shi_shi <= 2'd2; end else if(miao_ge ==4'd9) begin miao_ge <= 4'd0; if(miao_shi == 3'd5) begin miao_shi <= 3'd0; if(fen_ge == 4'd9) begin fen_ge <= 4'd0; if(fen_shi == 3'd5) begin fen_shi <= 3'd0; if(shi_ge == shi_select_ge)//The 24-hour format corresponds to 3, and the 12-hour format corresponds to 1 begin shi_ge <= 2'd0; if(shi_shi == shi_select_shi)//The 24-hour clock corresponds to 2, and the 12-hour clock corresponds to 1 shi_shi <= 2'd0; else shi_shi <= shi_shi + 1'b1; end else shi_ge <= shi_ge + 1'b1; end else fen_shi <= fen_shi + 1'b1; end else fen_ge <= fen_ge + 1'b1; end else miao_shi <= miao_shi + 1'b1; end else miao_ge <= miao_ge + 1'b1; end //************************************************ *************************************************** ** //Module name: Digital tube bit selection clock generation module // Function description: //************************************************ *************************************************** ** always @(posedge clk or negedge reset_n)//Nigital tube scanning clock generation process begin if(reset_n == 1'b0) begin count2 <= 14'd0; clk_scan <= 1'b0; end else if(count2 == 14'd10000) begin count2 <= 14'd0; clk_scan <= ~clk_scan; end else count2 <= count2 + 1'b1; end //************************************************ *************************************************** ** //Module name: digital tube bit selection generation signal module // Function description: //************************************************ *************************************************** ** always @(posedge clk_scan or negedge reset_n) begin if(reset_n == 1'b0) select <= 3'b000; else select <= select + 1'b1; end //************************************************ *************************************************** ** //Module name: Stopwatch timing // Function description: Stopwatch timing //************************************************ *************************************************** ** reg [3:0] counter_haomiao_ge; //Stopwatch timing, millisecond single digit BCD code reg [3:0] counter_haomiao_shi; //Stopwatch timing, millisecond ten-digit BCD code reg [3:0] counter_miao_ge; //Stopwatch timing, second single digit BCD code reg [2:0] counter_miao_shi; //Stopwatch timing, seconds ten-digit BCD binary code reg [3:0] counter_fen_ge; //Stopwatch timing, minute digits reg [2:0] counter_fen_shi; //Stopwatch timing, ten digits of minutes reg [1:0] counter_shi_ge; //Stopwatch timing, clock single digits reg [1:0] counter_shi_shi; //Stopwatch timing, clock ten digits always @(posedge clk_100hz or negedge reset_n) begin if(reset_n == 1'b0) begin counter_haomiao_ge <= 4'd0; counter_haomiao_shi <= 4'd0; counter_miao_ge <= 4'd0; counter_miao_shi <= 3'd0; counter_fen_ge <= 4'd0; counter_fen_shi <= 3'd0; counter_shi_ge <= 2'd0; counter_shi_shi <= 2'd0; end else if(~second_counter_key == 1'b1) if(counter_haomiao_ge == 4'd9) begin counter_haomiao_ge <= 4'd0; if(counter_haomiao_shi == 4'd9) begin counter_haomiao_shi <= 4'd0; if(counter_miao_ge ==4'd9) begin counter_miao_ge <= 4'd0; if(counter_miao_shi == 3'd5) begin counter_miao_shi <= 3'd0; if(counter_fen_ge == 4'd9) begin counter_fen_ge <= 4'd0; if(counter_fen_shi == 3'd5) begin counter_fen_shi <= 3'd0; if(counter_shi_ge == 2'd3)//The 24-hour clock corresponds to 3, the 12-hour clock corresponds to 1 begin counter_shi_ge <= 2'd0; if(counter_shi_shi == 2'd2)//The 24-hour clock corresponds to 2, the 12-hour clock corresponds to 1 counter_shi_shi <= 2'd0; else counter_shi_shi <= counter_shi_shi + 1'b1; end else counter_shi_ge <= counter_shi_ge + 1'b1; end else counter_fen_shi <= counter_fen_shi + 1'b1; end else counter_fen_ge <= counter_fen_ge + 1'b1; end else counter_miao_shi <= counter_miao_shi + 1'b1; end else counter_miao_ge <= counter_miao_ge + 1'b1; end else counter_haomiao_shi <= counter_haomiao_shi + 1'b1; end else counter_haomiao_ge <= counter_haomiao_ge + 1'b1; else begin counter_haomiao_ge <= 4'd0; counter_haomiao_shi <= 4'd0; counter_miao_ge <= 4'd0; counter_miao_shi <= 3'd0; counter_fen_ge <= 4'd0; counter_fen_shi <= 3'd0; counter_shi_ge <= 2'd0; counter_shi_shi <= 2'd0; end end //************************************************ *************************************************** ** //Module name: countdown module // Function description: //************************************************ *************************************************** ** reg [3:0] countdown_haomiao_ge; //Countdown, millisecond single digit BCD code reg [3:0] countdown_haomiao_shi; //Countdown, ten-digit millisecond BCD code reg [3:0] countdown_miao_ge; //Countdown, second single digit BCD code reg [2:0] countdown_miao_shi; //Countdown, ten-digit second BCD binary code always @(posedge clk_100hz or negedge reset_n)//Second and minute accumulation function process begin if(reset_n == 1'b0) begin countdown_haomiao_ge <= 4'd9; countdown_haomiao_shi <= 4'd9; countdown_miao_ge <= 4'd9; countdown_miao_shi <= 3'd5; end else if(~second_countdown_key == 1'b1) if(countdown_haomiao_ge == 4'd0) begin countdown_haomiao_ge <= 4'd9; if(countdown_haomiao_shi == 4'd0) begin countdown_haomiao_shi <= 4'd9; if(countdown_miao_ge ==4'd0) begin countdown_miao_ge <= 4'd9; if(countdown_miao_shi == 3'd0) begin countdown_miao_shi <= 3'd5; end else countdown_miao_shi <= countdown_miao_shi - 1'b1; end else countdown_miao_ge <= countdown_miao_ge - 1'b1; end else countdown_haomiao_shi <= countdown_haomiao_shi - 1'b1; end else countdown_haomiao_ge <= countdown_haomiao_ge - 1'b1; else begin countdown_haomiao_ge <= 4'd9; countdown_haomiao_shi <= 4'd9; countdown_miao_ge <= 4'd9; countdown_miao_shi <= 3'd5; end end //************************************************ *************************************************** ** //Module name: function selection module // Function description: //************************************************ *************************************************** ** reg [3:0] reg_haomiao_ge; //Millisecond single digit BCD code reg [3:0] reg_haomiao_shi; //Millisecond ten-digit BCD code reg [3:0] reg_miao_ge; //Second single digit BCD code reg [2:0] reg_miao_shi; //Ten-digit second BCD binary code reg [3:0] reg_fen_ge; //Single digit number of minutes reg [2:0] reg_fen_shi; //tens of minutes reg [3:0] reg_shi_ge; //clock single digit reg [1:0] reg_shi_shi; //clock ten digits always @(posedge clk or negedge reset_n) begin if(reset_n == 1'b0) begin reg_haomiao_ge <= 4'd9; reg_haomiao_shi <= 4'd9; reg_miao_ge <= 4'd9; reg_miao_shi <= 3'd5; reg_fen_ge <= 4'd9; reg_fen_shi <= 3'd5; reg_shi_ge <= 4'd3; reg_shi_shi <= 2'd2; end else begin case({~second_counter_key,~second_countdown_key}) 2'b10://Stopwatch function begin reg_haomiao_ge <= counter_haomiao_ge; reg_haomiao_shi <= counter_haomiao_shi; reg_miao_ge <= counter_miao_ge; reg_miao_shi <= counter_miao_shi; reg_fen_ge <= counter_fen_ge; reg_fen_shi <= counter_fen_shi; reg_shi_ge <= counter_shi_ge; reg_shi_shi <= counter_shi_shi; end 2'b01://Countdown function begin reg_haomiao_ge <= countdown_haomiao_ge; reg_haomiao_shi <= countdown_haomiao_shi; reg_miao_ge <= countdown_miao_ge; reg_miao_shi <= countdown_miao_shi; reg_fen_ge <= 4'hf; //Do not display reg_fen_shi <= 3'b111; //Do not display reg_shi_ge <= 4'b1111; //Do not display reg_shi_shi <= 2'b11; //Do not display end default://Normal function, display hours, minutes and seconds begin reg_haomiao_ge <= 4'hf; //Do not display reg_haomiao_shi <= 4'hf; //Do not display reg_miao_ge <= miao_ge; reg_miao_shi <= miao_shi; reg_fen_ge <= fen_ge; reg_fen_shi <= fen_shi; reg_shi_ge <= shi_ge; reg_shi_shi <= shi_shi; end endcase end end //************************************************ *************************************************** ** //Module name: decoding circuit // Function description: //************************************************ *************************************************** ** always @(posedge clk)//Sensitive signal list reg_haomiao_ge or miao_ge or miao_shi or fen_ge or fen_shi or shi_ge or shi_shi or select begin if(select == 3'd0) begin wei <= 8'b11111110; //Millisecond single digit display case(reg_haomiao_ge) 4'b0000:duan <= 8'b1100_0000;//0 4'b0001:duan <= 8'b1111_1001;//1 4'b0010:duan <= 8'b1010_0100;//2 4'b0011:duan <= 8'b1011_0000;//3 4'b0100:duan <= 8'b1001_1001;//4 4'b0101:duan <= 8'b1001_0010;//5 4'b0110:duan <= 8'b1000_0010;//6 4'b0111:duan <= 8'b1111_1000;//7 4'b1000:duan <= 8'b1000_0000;//8 4'b1001:duan <= 8'b1001_0000;//9 default:duan <= 8'hff; endcase end else if(select == 3'd1) begin wei <= 8'b11111101;//Tens digit display of milliseconds case(reg_haomiao_shi) 4'b0000:duan <= 8'b1100_0000;//0 4'b0001:duan <= 8'b1111_1001;//1 4'b0010:duan <= 8'b1010_0100;//2 4'b0011:duan <= 8'b1011_0000;//3 4'b0100:duan <= 8'b1001_1001;//4 4'b0101:duan <= 8'b1001_0010;//5 4'b0110:duan <= 8'b1000_0010;//6 4'b0111:duan <= 8'b1111_1000;//7 4'b1000:duan <= 8'b1000_0000;//8 4'b1001:duan <= 8'b1001_0000;//9 default:duan <= 8'hff; endcase end else if(select == 3'd2) begin wei <= 8'b11111011;//Single digit display of seconds case(reg_miao_ge) 4'b0000:duan <= 8'b1100_0000;//0 4'b0001:duan <= 8'b1111_1001;//1 4'b0010:duan <= 8'b1010_0100;//2 4'b0011:duan <= 8'b1011_0000;//3 4'b0100:duan <= 8'b1001_1001;//4 4'b0101:duan <= 8'b1001_0010;//5 4'b0110:duan <= 8'b1000_0010;//6 4'b0111:duan <= 8'b1111_1000;//7 4'b1000:duan <= 8'b1000_0000;//8 4'b1001:duan <= 8'b1001_0000;//9 default:duan <= 8'hff; endcase end else if(select == 3'd3) begin wei <= 8'b11110111;//Ten digit display of seconds case(reg_miao_shi) 3'b000:duan <= 8'b1100_0000; 3'b001:duan <= 8'b1111_1001; 3'b010:duan <= 8'b1010_0100; 3'b011:duan <= 8'b1011_0000; 3'b100:duan <= 8'b1001_1001; 3'b101:duan <= 8'b1001_0010; 3'b110:duan <= 8'b1000_0010; default:duan <= 8'hff; endcase end else if(select == 3'd4) begin wei <= 8'b11101111;//Single digit display of minutes case(reg_fen_ge) 4'b0000:duan <= 8'b1100_0000; 4'b0001:duan <= 8'b1111_1001; 4'b0010:duan <= 8'b1010_0100; 4'b0011:duan <= 8'b1011_0000; 4'b0100:duan <= 8'b1001_1001; 4'b0101:duan <= 8'b1001_0010; 4'b0110:duan <= 8'b1000_0010; 4'b0111:duan <= 8'b1111_1000; 4'b1000:duan <= 8'b1000_0000; 4'b1001:duan <= 8'b1001_0000; default:duan <= 8'hff; endcase end else if(select == 3'd5) begin wei <= 8'b11011111;//Ten digit display of minutes case(reg_fen_shi) 3'b000:duan <= 8'b1100_0000; 3'b001:duan <= 8'b1111_1001; 3'b010:duan <= 8'b1010_0100; 3'b011:duan <= 8'b1011_0000; 3'b100:duan <= 8'b1001_1001; 3'b101:duan <= 8'b1001_0010; 3'b110:duan <= 8'b1000_0010; default:duan <= 8'hff; endcase end else if(select == 3'd6) begin wei <= 8'b10111111; //clock single digit display case(reg_shi_ge) 4'b0000:duan <= 8'b1100_0000; 4'b0001:duan <= 8'b1111_1001; 4'b0010:duan <= 8'b1010_0100; 4'b0011:duan <= 8'b1011_0000; default:duan <= 8'hff; endcase end else begin wei <= 8'b01111111;//clock ten digit display case(reg_shi_shi) 3'b000:duan <= 8'b1100_0000; 3'b001:duan <= 8'b1111_1001; 3'b010:duan <= 8'b1010_0100; default:duan <= 8'hff; endcase end end endmodule