0
votes

I am working on a stopwatch and reaction timer in verilog. I have my stopwatch working, but I am having trouble with one part of the reaction timer. The goal is to hit a button, and a random amount of time later an led turns on and starts the timer, and you time yourself how long it takes you to stop the timer after the led turns on. Anyways, I have it so when I hit the reaction timer start button (when Cen == 2'b10), the timer starts counting. I am wondering how I can add a delay in between the button press and the timer starting. You can see right now when Cen == 2'b10, there is my attempt at a delay using the register "count," but it doesn't seem to work. I am just trying to do a fixed delay for now, then i'll implement the randomizer later, but the delay using my "count" method doesn't work. Any ideas? Let me know if you need any clarification. Thanks!

module Counter4dig(
    input [1:0] Cen,
    //input incIn,
    input clk, rst, inc,
    output reg[3:0] Dig0,
    output reg[3:0] Dig1,
    output reg[3:0] Dig2, 
    output reg[3:0] Dig3
);

reg ReactionCounter;
reg RandomValue;
reg [30:0] count = 1'b0;

always @ (posedge(clk), posedge(rst))
begin 

if (rst == 1'b1)begin
        Dig0 <= 4'b0000;
        Dig1 <= 4'b0000;
        Dig2 <= 4'b0000;
        Dig3 <= 4'b0000;
    end 

//increment if inc
else if(inc == 1'b1) 
begin
   Dig0 <= Dig0 + 1'b1;

   if(Dig0 == 4'b1001)
   begin
       Dig0 <= 4'b0000;

       //add 1 to second digit (when first resets) up till 9
       Dig1 <= Dig1 + 1'b1;
   end
   //reset if == 10
   if(Dig1 == 4'b1001 && Dig0 == 4'b1001)
   begin
       Dig1 <= 4'b0000;

       //add 1 to third digit (when second reset) up till 9
       Dig2 <= Dig2 + 1'b1;
   end
   //reset if == 10
   if(Dig2 == 4'b1001 && Dig1 == 4'b1001 && Dig0 == 4'b1001)
   begin
       Dig2 <= 4'b0000;

       //add 1 to fourth digit (when third reset) up till 9
       Dig3 <= Dig3 + 1'b1;
   end

   //reset if == 10
   if(Dig3 > 4'b1001)
   begin
       Dig3 <= 4'b0000;
   end            

end

else if (Cen == 2'b10)
begin
  if (count != 50000)
    count <= count + 1;

  else
  begin
    Dig0 <= Dig0 + 1'b1;

       if(Dig0 == 4'b1001)
       begin
           Dig0 <= 4'b0000;

           //add 1 to second digit (when first resets) up till 9
           Dig1 <= Dig1 + 1'b1;
       end
       //reset if == 10
       if(Dig1 == 4'b1001 && Dig0 == 4'b1001)
       begin
           Dig1 <= 4'b0000;

           //add 1 to third digit (when second reset) up till 9
           Dig2 <= Dig2 + 1'b1;
       end
       //reset if == 10
       if(Dig2 == 4'b1001 && Dig1 == 4'b1001 && Dig0 == 4'b1001)
       begin
           Dig2 <= 4'b0000;

           //add 1 to fourth digit (when third reset) up till 9
           Dig3 <= Dig3 + 1'b1;
       end

       //reset if == 10
       if(Dig3 > 4'b1001)
       begin
           Dig3 <= 4'b0000;
       end    
end
end

//only continue if Cen is 01 & not inc
else if(Cen == 2'b01)
begin   

    //add 1 to first digit up till 9
    Dig0 <= Dig0 + 1'b1;

    //reset if == 10    
        if(Dig0 == 4'b1001)
        begin
            Dig0 <= 4'b0000;

            //add 1 to second digit (when first resets) up till 9
            Dig1 <= Dig1 + 1'b1;
        end
            //reset if == 10
            if(Dig1 == 4'b1010)
            begin
                Dig1 <= 4'b0000;

                //add 1 to third digit (when second reset) up till 9
                Dig2 <= Dig2 + 1'b1;
            end
                //reset if == 10
                if(Dig2 == 4'b1010)
                begin
                    Dig2 <= 4'b0000;

                    //add 1 to fourth digit (when third reset) up till 9
                    Dig3 <= Dig3 + 1'b1;
                end

                    //reset if == 10
                if(Dig3 > 4'b1001)
                begin
                    Dig3 <= 4'b0000;
                end         
    end 
//end

end

endmodule

1
It seems like you have written verilog code,as if you are writing a C code. Think from hardware prospective and use different always blocks for different signal assignments (like Dig1 and so on). By that way your code would be more clear to me and to others as wellKaran Shah

1 Answers

0
votes

You assign the reg [30:0] count = 1'b0; First of all, you are only assigning one bit, instead of 31 bits. Use 31'b0. Next, you are assigning count outside of an always statement with a blocking assignment and then inside the statement with a non-blocking assignment. I am not sure this is synthesizeable.

Would it be fair to say that you need the counter to reset to zero right as the button press occurs and then starting counting? Assuming that it would continue counting while the button was still pressed, you might try this.

reg[1:0] Cen_d;  // Used to capture the Cen for use in a making a pulse 
reg      Cen_pulse;
generator

always @ (posedge clk)
begin 
   Cen_d <= Cen; // capture the old Cen value
   Cen_pulse <= Cen == 2'b10 & (Cen != Cen_d); // Look for Cen == 2'b01 and
                                               // the old Cen (in Cen_d) is
                                               // is not current Cen.  If so
                                               // pulse once.
end

always @ (posedge clk or posedge reset)
begin 
   if (reset)
      count <= 31'h0000_0000;
   else
      begin 
      count = Cen_pulse      ? 31'h0000_0000 : // Return to zero on pulse
              count >= 50000 ? 31'd500000    : // Stop counting at 50000
              count = count + 1;               // Otherwise increment
      end
end