Author Topic: Reset in Verilog isn't working as planned  (Read 1595 times)

0 Members and 1 Guest are viewing this topic.

Offline AidanWTopic starter

  • Newbie
  • Posts: 5
  • Country: us
Reset in Verilog isn't working as planned
« on: March 18, 2023, 10:14:35 pm »
Hello all!

So I just started learning Verilog this semester, and I have coded a 4 bit counter to run on LEDs. The counter works great. The only problem is that the reset button does not work as anticipated. When I flip the reset switch, the counter simply stops on whichever number it is currently on. It is meant to set the count to 0 and reset the timer.

Does anyone know what I did wrong? Thank you!

Code below:

# This is my slow clock module. Not rly sure why I need the reset in here, but I am just following examples that I found online.

`timescale 1ns / 1ps

module slowClock(clk, reset, clk_1Hz);
input clk, reset;
output clk_1Hz;

reg clk_1Hz = 1'b0;
reg [27:0] counter;

always@(posedge reset or posedge clk)
begin
    if (reset == 1'b1)
        begin
            clk_1Hz <= 0;
            counter <= 0;
        end
    else
        begin
            counter <= counter + 1;
            if ( counter == 25_000_000)
                begin
                    counter <= 0;
                    clk_1Hz <= ~clk_1Hz;
                end
        end
end
endmodule   


# This is my counter module


`timescale 1ns / 1ps

module fourbitcounter(Q, clk, reset);
 
   input clk, reset; // Declare the inputs as the clock and reset
     output [3:0] Q; // Declare the outputs as 4 bit Q
 
     reg [3:0] Q;  // Declare Q as a variable

   wire clk_1Hz; // Declare the slow clock as a wire
 
    slowClock clock_generator(clk, reset, clk_1Hz); //Instatiate the slow clock
 

     always@(posedge clk_1Hz) // Check for the rising edge of the slow clock
     begin     
      if (reset == 1) // If the reset is high, set the output to 0
           Q <= 4'b0000;   // Not sure why it isn't setting the value to 0 when timer is high
       else            // Otherwise, increment the 4 bit Q by 1
           Q <= Q + 4'b1;
     end
endmodule

 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11803
  • Country: us
    • Personal site
Re: Reset in Verilog isn't working as planned
« Reply #1 on: March 18, 2023, 10:26:58 pm »
Your first part of the code is stopped by the reset, and it generates 1 Hz clock. The second part only has 1 Hz in the sensitivity list, so it would not see the reset until 1 Hz clock is back on (first posedge).

For learning it does not matter that much, but for a real project you would typically have a common always running high speed clock going to all the blocks and blocks would generate one clock cycle long enable signals to perform slower actions.
« Last Edit: March 18, 2023, 10:33:10 pm by ataradov »
Alex
 
The following users thanked this post: AidanW

Offline AK6DN

  • Regular Contributor
  • *
  • Posts: 55
  • Country: us
Re: Reset in Verilog isn't working as planned
« Reply #2 on: March 18, 2023, 11:54:37 pm »
Your slow clock module has an asynchronous reset, while your counter module has a synchronous reset.

When you assert reset, your slow clock module sets the clock low and holds it low.

Since your counter module has a synchronous reset, it needs to see a clock edge AND reset asserted to reset.

Your slow clock module is not providing a clock edge.

So change your counter module to use an async reset scheme. Or change your slow clock to be a sync reset scheme.
 
The following users thanked this post: AidanW

Offline AidanWTopic starter

  • Newbie
  • Posts: 5
  • Country: us
Re: Reset in Verilog isn't working as planned
« Reply #3 on: March 19, 2023, 12:14:23 am »
Your slow clock module has an asynchronous reset, while your counter module has a synchronous reset.

When you assert reset, your slow clock module sets the clock low and holds it low.

Since your counter module has a synchronous reset, it needs to see a clock edge AND reset asserted to reset.

Your slow clock module is not providing a clock edge.

So change your counter module to use an async reset scheme. Or change your slow clock to be a sync reset scheme.

I changed my counter to look for 1Hz or reset, which fixed it.
Thank you so much! That was really helpful.
 

Offline AidanWTopic starter

  • Newbie
  • Posts: 5
  • Country: us
Re: Reset in Verilog isn't working as planned
« Reply #4 on: March 19, 2023, 12:17:03 am »
Your first part of the code is stopped by the reset, and it generates 1 Hz clock. The second part only has 1 Hz in the sensitivity list, so it would not see the reset until 1 Hz clock is back on (first posedge).

For learning it does not matter that much, but for a real project you would typically have a common always running high speed clock going to all the blocks and blocks would generate one clock cycle long enable signals to perform slower actions.

So for a real project (which I am planning to start soon), I would instead slow the clock down within the counter module instead of using a different module? What does a one clock cycle long enable signal mean?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11803
  • Country: us
    • Personal site
Re: Reset in Verilog isn't working as planned
« Reply #5 on: March 19, 2023, 12:22:24 am »
I would instead slow the clock down within the counter module instead of using a different module?
No need to slow down anything. Your 1 Hz generator would look something like this:

Code: [Select]
wire en_1Hz = (counter == 25_000_000);

always@(posedge clk)
begin
    if (reset == 1'b1)
      counter <= 0;
    else if (en_1Hz)
       counter <= 0;
    else
       counter <= counter + 1;
end

And then the other part:
Code: [Select]
always@(posedge clk)
     begin     
      if (reset == 1) // If the reset is high, set the output to 0
           Q <= 4'b0000;   // Not sure why it isn't setting the value to 0 when timer is high
       else if (en_1Hz)
           Q <= Q + 4'b1;
     end

en_1Hz woud be asserted for one cycle of "clk". And the whole design runs on one clock - "clk".

This way you don't need to think about resets as something special, they are just like any other synchronous signal. And running the design on one (or as few as possible) clocks is always a good idea.

Note that you technically need to compare with 25M-1. Does not matter for indication and general timeouts, but would matter for timekeeping.
« Last Edit: March 19, 2023, 01:03:13 am by ataradov »
Alex
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8178
  • Country: ca
    • LinkedIn
Re: Reset in Verilog isn't working as planned
« Reply #6 on: March 19, 2023, 10:45:46 pm »

Code: [Select]
wire en_1Hz = (counter == 25_000_000);

always@(posedge clk)
begin
    if (reset == 1'b1)
      counter <= 0;
    else if (en_1Hz)
       counter <= 0;
    else
       counter <= counter + 1;
end

And then the other part:
Code: [Select]
always@(posedge clk)
     begin     
      if (reset == 1) // If the reset is high, set the output to 0
           Q <= 4'b0000;   // Not sure why it isn't setting the value to 0 when timer is high
       else if (en_1Hz)
           Q <= Q + 4'b1;
     end

en_1Hz woud be asserted for one cycle of "clk". And the whole design runs on one clock - "clk".

This way you don't need to think about resets as something special, they are just like any other synchronous signal. And running the design on one (or as few as possible) clocks is always a good idea.

Note that you technically need to compare with 25M-1. Does not matter for indication and general timeouts, but would matter for timekeeping.

Ok, maybe something more like this:

Code: [Select]
wire en_1Hz = (counter == 25_000_000);

always@(posedge clk)
begin
    if (reset == 1'b1) begin
        counter <= 1 ; // assuming a 25MHz clock, counting from 0 to 25000000, then back to 0 is a count of 25000001...  I'm also assuming you want a 1 second clock.
        Q       <= 4'b0000 ;   // Not sure why it isn't setting the value to 0 when timer is high
    end else if (en_1Hz) begin
        counter <= 1 ; // assuming a 25MHz clock, counting from 0 to 25000000, then back to 0 is a count of 25000001...
        Q       <= Q + 4'b1 ;
    end else counter <= counter + 1;
end
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11803
  • Country: us
    • Personal site
Re: Reset in Verilog isn't working as planned
« Reply #7 on: March 19, 2023, 10:57:36 pm »
It is a matter of preference and overall design. I would not separate very simple things into separate modules, but I also would not combine things this way. It is fine to have two separate always blocks here. It clearly shows the separation of logic and avoids annoying begin/end pairs.
Alex
 
The following users thanked this post: AidanW

Offline AidanWTopic starter

  • Newbie
  • Posts: 5
  • Country: us
Re: Reset in Verilog isn't working as planned
« Reply #8 on: March 20, 2023, 01:36:08 pm »
Ahh okay that makes sense. I'm trying to learn better / alternate ways of designing modules so thank you so much for the input! Using separate modules is helpful for me to keep things separate in my head, but it is good to learn the simpler ways to do it.

Thank you!
 

Offline tchiwam

  • Regular Contributor
  • *
  • Posts: 134
  • Country: ca
Re: Reset in Verilog isn't working as planned
« Reply #9 on: March 25, 2023, 07:22:25 pm »
https://www.eevblog.com/forum/fpga/and-the-warning-is-gone-simple-divclk-by-n/

I got this to "work", even If I am suspicious of the last clk edge (might generate a glitch IMO)

So I use a register and 2 always@

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf