Forum Discussion
Verilog FSM stuck on one State forever
- 1 year ago
You have nextstate in your case statement, but state never updates to nextstate.
Fix it by adding a sequential block to update state at every clock edge.
always @(posedge clk) begin
if (~rst)
state <= idle;
else
state <= nextstate;
endI would recommend to checkout 'Two Always Block FSM coding style' from the article below.
It uses two separate always blocks:
- State Register Block: A sequential (always_ff ) block that updates the current state (state_reg) on the clock edge.
- Next State & Output Logic Block: A combinational (always_comb) block that determines the next state and the outputs based on the current state and inputs.
http://www.sunburst-design.com/papers/CummingsSNUG2019SV_FSM1.pdf
Regards,
Richard Tan
You have nextstate in your case statement, but state never updates to nextstate.
Fix it by adding a sequential block to update state at every clock edge.
always @(posedge clk) begin
if (~rst)
state <= idle;
else
state <= nextstate;
end
I would recommend to checkout 'Two Always Block FSM coding style' from the article below.
It uses two separate always blocks:
- State Register Block: A sequential (always_ff ) block that updates the current state (state_reg) on the clock edge.
- Next State & Output Logic Block: A combinational (always_comb) block that determines the next state and the outputs based on the current state and inputs.
http://www.sunburst-design.com/papers/CummingsSNUG2019SV_FSM1.pdf
Regards,
Richard Tan
- Fpga_Egr_20251 year ago
Occasional Contributor
HI Richard,
Yes changed the fsm to have two separate always block :
////////////////////////////////////always @ (posedge clk) beginif (~rst) beginstate <= idle;endelse beginstate <= nextstate;endend////////////////////////////////////always @(*) beginnextstate <= idle;case(state)idle:beginif(vld)beginrdy_sig <= 1'b1;nextstate <= buffer_data;endelse if (last)beginrdy_sig <= 1'b0;valid_no_reg <= valid_no;nextstate <= filter_data_state;end