三段式状态机的优势:三段式描述方法与一段式和两段式状态机描述相比,虽然代码结构复杂了一些,但是换来的优势是使FSM(Finite State Machine)做到了同步寄存器输出,消除了组合逻辑输出的不稳定与毛刺的隐患,而且更利于时序路径分组,一般来说在FPGA/CPLD等可编程逻辑器件上的综合与布局布线效果更佳。
需要掌握的是三段式状态机的综合效果。通常,三段式状态机分成三个always过程块:
always过程块1:时序逻辑,将次态(next state)寄存器的内容迁移到现态(current state)寄存器。
always过程块2:纯组合逻辑,根据现态和状态机判断次态。
always过程块3:时序逻辑,根据次态给出状态机输出。
当一个clk上升沿到来时,时序逻辑方面,原来的次态变为现态,并根据次态给出状态机输出。组合逻辑方面根据现态和输入得到新的次态,并根据新的次态得到新的状态输出。
reg[3:0]cstate;
reg[3:0]nstate;
always@(posedge clk or negedge rst_n)
if(!rst_n) cstate<=IDLE;
else cstate<=nstate;
always@(cstate or wr_req or rd_req)
begin
case(cstate)
IDLE:if(wr_req) nstate=WR_S1;
else if(rd_req) nstate=RD_S1;
else nstate=IDLE;
WR_S1:nstate=WR_S2;
WR_S2:nstate=IDLE;
RD_S1:if(wr_req) nstate=WR_S1;
else nstate=RD_S2;
RD_S2:if(wr_req) nstate=WR_S1;
else nstate=IDLE;
default:nstate=IDLE;
endcase
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) cmd<=3'b111;
else
case(nstate)
IDLE:if(wr_req) cmd<=3'b011;
else if(rd_req) cmd<=3'b011;
else cmd<=3'b111;
WR_S1:cmd<=3'b101;
WR_S2:cmd<=3'b111;
RD_S1:if(wr_req) cmd<=3'b101;
else cmd<=3'b110;
RD_S2:if(wr_req) cmd<=3'b011;
else cmd<=3'b111;
default:;
endcase
end