+ Post New Thread
Results 1 to 3 of 3
  1. #1
    Newbie level 5
    Points: 191, Level: 2

    Join Date
    Feb 2015
    Posts
    8
    Helped
    0 / 0
    Points
    191
    Level
    2

    Stop Watch on Xilinx FPGA board Verilog

    Hi I tried to use verilog to develop a stop watch on a fpga board seven segment display. It doesn't count correctly (See the video: https://www.youtube.com/watch?v=uHqJeKxjPrA) I guess the problem is from the counter.v and top.v? However, I can't figure what's wrong with the code. Hopefully, someone can give some hints.

    Code:
    // 4 digit enable module
    
    module enable_sr(
    input         clk,
    output        enable_D1,
    output        enable_D2,
    output        enable_D3,
    output        enable_D4
    );
    
    reg [3:0] pattern = 4'b0111;
    
    assign enable_D1 = pattern[3];
    assign enable_D2 = pattern[2];
    assign enable_D3 = pattern[1];
    assign enable_D4 = pattern[0];
    
    always @(posedge clk) begin
      pattern <= {pattern[0],pattern[3:1]};
    end
    
    endmodule
    
    // counter module
    
    module counter(
    input button0,
    input button1,
    input clk_point1hz,
    output reg reg_d0,
    output reg reg_d1,
    output reg reg_d2,
    output reg reg_d3
        );
    
    reg stop;
    wire reset;
    
    
    assign reset = button1;
    
    always @(posedge button0)
    stop <= ~stop;
    
    
    always @(posedge clk_point1hz)
    
    if (stop == 1 && reset ==1) begin 
    
    reg_d0 <= 0;
    reg_d1 <= 0;
    reg_d2 <= 0;
    reg_d3 <= 0;
    
    end else if (stop == 1) begin
    
    reg_d0 <= reg_d0;
    reg_d1 <= reg_d1;
    reg_d2 <= reg_d2;
    reg_d3 <= reg_d3;
    
    end else if (stop != 1) //if no stop
       begin
       if(reg_d0 == 9) //xxx9 
          begin //if_0
          reg_d0 <= 0;
    
        if (reg_d1 == 9) //xx99
           begin  // if_1
           reg_d1 <= 0;
    
           if (reg_d2 == 9) //x999 
               begin //if_2
               reg_d2 <= 0;
    
               if(reg_d3 == 9) //9999
                  reg_d3 <= 0;
                  else
                  reg_d3 <= reg_d3 + 1;
                 end    // end if-2
    
           else //else_2
            reg_d2 <= reg_d2 + 1;
        end
    
        else //else_1
          reg_d1 <= reg_d1 + 1;
       end
    
       else //else_0
         reg_d0 <= reg_d0 + 1;
    end
    
    
    
    endmodule
    
    // seven segment display module
    
    module ssd(
        input [3:0] hex,
        output reg [6:0] segment,
         output dp
        );
    
    always @ (*)
    
       case (hex) // use little endian, so need to reverse the ucf segment as it uses big endian
            0: segment = 7'b0000001;
            1: segment = 7'b1001111;
            2: segment = 7'b0010010;
            3: segment = 7'b0000110;
            4: segment = 7'b1001100;
            5: segment = 7'b0100100;
            6: segment = 7'b0100010;
            7: segment = 7'b0001101;
            8: segment = 7'b0000000;
            9: segment = 7'b0000100;
          default: segment = 7'b0000001;
    
       endcase
    
    assign dp = 4'b1111;
    
    endmodule
    
    
    // top module
    
    module top(
    input clk,
    input button_n,
    input reset_n,
    output [6:0] segment,
    output enable_D1,//right most digit
    output enable_D2,
    output enable_D3,
    output enable_D4,//left most digit
    output dp,
    output reg_d0,
    output reg_d1,
    output reg_d2,
    output reg_d3
        );
    
    wire clk_point1hz;
    wire refreshClk;
    reg [3:0] hex;
    
    
    clock_gen Uclk_gen(
    .clk(clk),
    .refreshClk(refreshClk),
    .clk_point1hz(clk_point1hz)
    );
    
    enable_sr Uenable(
    .clk(refreshClk),
    .enable_D1(enable_D1),
    .enable_D2(enable_D2),
    .enable_D3(enable_D3),
    .enable_D4(enable_D4)
    );
    
    counter Ucounter(
    .button0(button_n),
    .button1(reset_n),
    .clk_point1hz(clk_point1hz),
    .reg_d0(reg_d0),
    .reg_d1(reg_d1),
    .reg_d2(reg_d2),
    .reg_d3(reg_d3)
    );
    
    ssd Ussd(
    .hex(hex),
    .segment(segment),
    .dp(dp)
    );
    
    always @ (*)
    
    begin
    
    if (enable_D1 == 1 && enable_D2 == 1 && enable_D3 == 1 && enable_D4 == 0) 
    assign hex = reg_d0;
    
    else if (enable_D1 == 1 && enable_D2 == 1 && enable_D3 == 0 && enable_D4== 1) 
    assign hex = reg_d1;
    
    else if(enable_D1 == 1 && enable_D2 == 0 && enable_D3 == 1 && enable_D4 == 1) 
    assign hex = reg_d2;
    
    else if(enable_D1 == 0 && enable_D2 == 0 && enable_D3 == 0 && enable_D4 == 1) 
    assign hex = reg_d3;
    
    end
    
    
    endmodule

    •   AltAdvertisment

        
       

  2. #2
    Advanced Member level 5
    Points: 37,091, Level: 47
    Achievements:
    7 years registered

    Join Date
    Jun 2010
    Posts
    6,756
    Helped
    1975 / 1975
    Points
    37,091
    Level
    47

    Re: Stop Watch on Xilinx FPGA board Verilog

    The problem is probably more a system design problem. There are a few poor design practices in the code.

    1. You generate clocks with logic. Instead you should generate clock enable signals and use the same system clock all over.

    2. Using buttons without debouncing them. When you press a button it actually bounces back and forth between 0 and 1 got a short period.

    3. Are you sure you meant a all your counters to be nested inside each other?



    •   AltAdvertisment

        
       

  3. #3
    Newbie level 5
    Points: 191, Level: 2

    Join Date
    Feb 2015
    Posts
    8
    Helped
    0 / 0
    Points
    191
    Level
    2

    Re: Stop Watch on Xilinx FPGA board Verilog

    Hi thanks for the advice. For the first one, it is required and provided in the project assignment. The second one yes thanks I will pay attention to the denouncing. The reason I used nested if to check the lsb to msb one by one. That is the only way I can think of. It will be great if there is any hints on the counter.



--[[ ]]--