24-bit state counter

I am trying to create a counter in verilog that counts how many hours were there, and after ten million it will reset and start again.

I created a module with four four bits along with another module containing twenty-four D Flip flops to keep track of the loops output from the adder.

Then I want to have a state machine that is in count state until ten million cycles have passed, then it goes into reset state.

Does this sound right? The problem is that I'm not sure how to implement the state machine.

Can someone point me to a website / book that could help me with this?

thanks

+4
source share
3 answers

As Paul S already mentioned, there is no need for a final machine if you want your counter to continue counting after overflow. You can do something like this (unverified, may contain typos):

module overflow_counter ( clk, reset, enable, ctr_out ); // Port definitions input clk, reset, enable; output [23:0] ctr_out; // Register definitions reg [23:0] reg_ctr; // Assignments assign ctr_out = reg_ctr; // Counter behaviour - Asynchronous active-high reset initial reg_ctr <= 0; always @ (posedge clk or posedge reset) begin if (reset) reg_ctr <= 0; else if (enable) begin if (reg_ctr == 10000000) reg_ctr <= 0; else reg_ctr <= reg_ctr + 1; end end endmodule 

Of course, you should usually use parameters, so you do not need to create a custom module every time you want to overflow the counter. I will leave it to you;).

[Edit] And here are some documents to help you with FSM. I just searched Google for the "verilog state machine":

I have not read the first article, so I can not comment on this. The second shows various types of FSM encoding, among which 3 always blocks the style, which I highly recommend, because it is much easier to debug (the state transition and FSM output are neatly separated). The link does not seem to work, so the cached result is Google .

+4
source

You do not need a state machine. You already have a standing condition. All you have to do is determine the value you want to wrap and load 0 into your counter at that moment.

In pseudo code:

 if count == 10000000 then nextCount = 0; else nextCount = count + 1; 

... or...

 nextCount = count + 1; if count == 10000000 then resetCount = 1; 
+3
source

State cars are not too complicated. Use localparam (with a width, don't forget the width not shown here because it is just one bit) to define labels for your states. Then create two reg variables ( state_reg , state_next ). The _reg variable is your actual case. The _next variable is a "wired river" (a wire that can be assigned inside a combinational always block). Two things to remember are to do X_next = X_reg; always in a combinational block (and then the rest of the combinational logic) and X_reg <= X_next; always in sequential block. You may get imagination for special occasions, but if you follow these simple rules, then everything should work. I try not to use the instance for very simple things like adders, since Verilog is great at adding support.

Since I work with FPGA, I assign initial values ​​to my registers, and I do not use the reset signal. I'm not sure, but for ASIC design, I think it's the other way around.

 localparam STATE_RESET = 1'b0, STATE_COUNT = 1'b1; reg [23:0] cntr_reg = 24'd0, cntr_next; reg state_reg = STATE_COUNT, state_next; always @* begin cntr_next = cntr_reg; // statement not required since we handle all cases if (cntr_reg == 24'd10_000_000) cntr_next = 24'd0; else cntr_next = cntr_reg + 24'd1; state_next = state_reg; // statement required since we don't handle all cases case (state_reg) STATE_COUNT: if (cntr_reg == 24'd10_000_000) state_next = STATE_RESET; endcase end always @(posedge clk) begin cntr_reg <= cntr_next; state_reg <= state_next; end 

I found this book to be very useful. There is also a version of the VHDL book, so you can use both side by side and Rosetta Stone to learn VHDL.

+2
source

All Articles