If you just need to execute some states twice, make them two different states. You can put the common logic parts inside a function.
always_ff @(posedge clk or posedge reset)
if (reset) state <= IDLE else
case (STATE)
IDLE: if (start) STATE <= ST1;
ST1: begin STATE <= ST2; fST(); end
ST2: begin STATE <= IDLE; fST(); end
default: STATE <= IDLE;
endcase
function void fST;
// stuff that needs to be done
end function
If you need more than twice you can put in counter
always_ff @(posedge clk or posedge reset)
if (reset) STATE <= IDLE else
case (STATE)
IDLE: if (start) begin STATE <= ST; counter <=0; end
ST: begin
if (counter > N) STATE <= IDLE;
counter <= counter + 1;
// stuff that needs to be done
end
default: STATE <= IDLE;
endcase
If you are separating your FSM into always_comb
an always_ff
, you will need a next state and next counter variable.
always_ff @(posedge clk or posedge reset)
if (reset) STATE <= IDLE else
begin
STATE <= NXSTATE;
COUNTER <= NXCOUNTER;
end
always_comb
case (STATE)
IDLE: if (start) begin NXSTATE = ST; COUNTER <=0; end
ST: begin
if (COUNTER > N) NXSTATE = IDLE;
NXCOUNTER = NXCOUNTER + 1;
// stuff that needs to be done
end
default: NXSTATE = IDLE;
endcase