### How to Create an Accurate Delay in Verilog:

To make the stop watch an accurate device we need to be able to produce an accurate 0.1 second delay. I have already explained how to do this before in my decimal counter in verilog post. But since it is of great importance to the design will be explained in more detail here.

Since we know that the BASYS2 (the one I am using, yours may be different) has a 50 MHz clock which means that the clock cycle is repeated 50M times in one second. So to create a 0.1 second delay we multiply the clock with the required time:

50MHz * 0.1 sec = 5000000

So the clock cycle is repeated 5M times in 0.1 second. The next step is to calculate the size of the register that will hold this count. This is done by using the log formulas. Here x is the unknown:

2exp(x) = 5000000

Taking log on both sides:

log 2exp(x) = log 5000000

(x) log (2) = log 5000000

x = log 5000000 / log 2

x = 22.3

Hence a 23 bit wide register will be able to hold a count of 5000000.

The code for the stopwatch is given below, as with all other posts involving the seven segment display LED multiplexing is performed here. I will not comment or explain it here as I have already made a detailed post regarding that here: Display LED Multiplexing in Verilog

module stopwatch( input clock, input reset, input start, output a, b, c, d, e, f, g, dp, output [3:0] an ); reg [3:0] reg_d0, reg_d1, reg_d2, reg_d3; //registers that will hold the individual counts reg [22:0] ticker; //23 bits needed to count up to 5M bits wire click; //the mod 5M clock to generate a tick ever 0.1 second always @ (posedge clock or posedge reset) begin if(reset) ticker <= 0; else if(ticker == 5000000) //if it reaches the desired max value reset it ticker <= 0; else if(start) //only start if the input is set high ticker <= ticker + 1; end assign click = ((ticker == 5000000)?1'b1:1'b0); //click to be assigned high every 0.1 second always @ (posedge clock or posedge reset) begin if (reset) begin reg_d0 <= 0; reg_d1 <= 0; reg_d2 <= 0; reg_d3 <= 0; end else if (click) //increment at every click begin if(reg_d0 == 9) //xxx9 - the 0.1 second digit begin //if_1 reg_d0 <= 0; if (reg_d1 == 9) //xx99 begin // if_2 reg_d1 <= 0; if (reg_d2 == 5) //x599 - the two digit seconds digits begin //if_3 reg_d2 <= 0; if(reg_d3 == 9) //9599 - The minute digit reg_d3 <= 0; else reg_d3 <= reg_d3 + 1; end else //else_3 reg_d2 <= reg_d2 + 1; end else //else_2 reg_d1 <= reg_d1 + 1; end else //else_1 reg_d0 <= reg_d0 + 1; end end //The Circuit for Multiplexing - Look at my other post for details on this localparam N = 18; reg [N-1:0]count; always @ (posedge clock or posedge reset) begin if (reset) count <= 0; else count <= count + 1; end reg [6:0]sseg; reg [3:0]an_temp; reg reg_dp; always @ (*) begin case(count[N-1:N-2]) 2'b00 : begin sseg = reg_d0; an_temp = 4'b1110; reg_dp = 1'b1; end 2'b01: begin sseg = reg_d1; an_temp = 4'b1101; reg_dp = 1'b0; end 2'b10: begin sseg = reg_d2; an_temp = 4'b1011; reg_dp = 1'b1; end 2'b11: begin sseg = reg_d3; an_temp = 4'b0111; reg_dp = 1'b0; end endcase end assign an = an_temp; reg [6:0] sseg_temp; always @ (*) begin case(sseg) 4'd0 : sseg_temp = 7'b1000000; 4'd1 : sseg_temp = 7'b1111001; 4'd2 : sseg_temp = 7'b0100100; 4'd3 : sseg_temp = 7'b0110000; 4'd4 : sseg_temp = 7'b0011001; 4'd5 : sseg_temp = 7'b0010010; 4'd6 : sseg_temp = 7'b0000010; 4'd7 : sseg_temp = 7'b1111000; 4'd8 : sseg_temp = 7'b0000000; 4'd9 : sseg_temp = 7'b0010000; default : sseg_temp = 7'b0111111; //dash endcase end assign {g, f, e, d, c, b, a} = sseg_temp; assign dp = reg_dp; endmodule

Test bench below:

module test; // Inputs reg clock; reg reset; reg start; // Outputs wire [3:0] d0; wire [3:0] d1; wire [3:0] d2; // Instantiate the Unit Under Test (UUT) stopwatch uut ( .clock(clock), .reset(reset), .start(start), .d0(d0), .d1(d1), .d2(d2) ); initial begin clock = 0; forever #50 clock = ~clock; end initial begin // Initialize Inputs reset = 0; start = 0; // Wait 100 ns for global reset to finish #100; reset = 1; #100; reset = 0; #100; start = 1; // Add stimulus here end endmodule

Video demonstration below: