Reset in Verilog isn't working as planned - Page 1
Forum section: electronics / general

author: AidanW
author_rank: Newbie
timestamp: March 18, 2023, 10:14:35 pm
content: 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 / 1psmodule 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)beginif (reset == 1'b1)beginclk_1Hz <= 0;counter <= 0;endelsebegincounter <= counter + 1;if ( counter == 25_000_000)begincounter <= 0;clk_1Hz <= ~clk_1Hz;endendendendmodule# This is my counter module`timescale 1ns / 1psmodule fourbitcounter(Q, clk, reset);input clk, reset; // Declare the inputs as the clock and resetoutput [3:0] Q; // Declare the outputs as 4 bit Qreg [3:0] Q; // Declare Q as a variablewire clk_1Hz; // Declare the slow clock as a wireslowClock clock_generator(clk, reset, clk_1Hz); //Instatiate the slow clockalways@(posedge clk_1Hz) // Check for the rising edge of the slow clockbeginif (reset == 1) // If the reset is high, set the output to 0Q <= 4'b0000; // Not sure why it isn't setting the value to 0 when timer is highelse // Otherwise, increment the 4 bit Q by 1Q <= Q + 4'b1;endendmodule

author: ataradov
author_rank: Super Contributor
timestamp: March 18, 2023, 10:26:58 pm
content: 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.

author: AK6DN
author_rank: Regular Contributor
timestamp: March 18, 2023, 11:54:37 pm
content: 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.

author: AidanW
author_rank: Newbie
timestamp: March 19, 2023, 12:14:23 am
content: Quote from: AK6DN on March 18, 2023, 11:54:37 pmI changed my counter to look for 1Hz or reset, which fixed it.Thank you so much! That was really helpful.

author: AidanW
author_rank: Newbie
timestamp: March 19, 2023, 12:17:03 am
content: Quote from: ataradov on March 18, 2023, 10:26:58 pmSo 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?

author: ataradov
author_rank: Super Contributor
timestamp: March 19, 2023, 12:22:24 am
content: Quote from: AidanW on March 19, 2023, 12:17:03 amNo need to slow down anything. Your 1 Hz generator would look something like this:Code:wire en_1Hz = (counter == 25_000_000);always@(posedge clk)beginif (reset == 1'b1)counter <= 0;else if (en_1Hz)counter <= 0;elsecounter <= counter + 1;endAnd then the other part:Code:always@(posedge clk)beginif (reset == 1) // If the reset is high, set the output to 0Q <= 4'b0000; // Not sure why it isn't setting the value to 0 when timer is highelse if (en_1Hz)Q <= Q + 4'b1;enden_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.

author: BrianHG
author_rank: Super Contributor
timestamp: March 19, 2023, 10:45:46 pm
content: Quote from: ataradov on March 19, 2023, 12:22:24 amOk, maybe something more like this:Code:wire en_1Hz = (counter == 25_000_000);always@(posedge clk)beginif (reset == 1'b1) begincounter <= 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 highend else if (en_1Hz) begincounter <= 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

author: ataradov
author_rank: Super Contributor
timestamp: March 19, 2023, 10:57:36 pm
content: 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.

author: AidanW
author_rank: Newbie
timestamp: March 20, 2023, 01:36:08 pm
content: 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!

author: tchiwam
author_rank: Regular Contributor
timestamp: March 25, 2023, 07:22:25 pm
content: 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@