# 三段状态机的思维陷阱

reference:  http://bbs.ednchina.com/BLOG_ARTICLE_3003230.HTM

1.将组合逻辑和时序逻辑分开，利于综合器分析优化和程序维护;
2.更符合设计的思维习惯;
3.代码少，比一段式状态机更简洁。

assign end = (count == 10);
always @(posedge clk)
begin
case(state)
wr_st:  if(end) begin
q      <= 1;
state <= rd_st;
end
else  begin
q      <= 0;
state <= wr_st;
end
rd_st:  if(jump) begin
p     <= 1;
state <= erase_st;
end
else if(end) begin
p     <=  0;
state <= rd_st;
end
else  begin
p     <=  1;
state <= rd_st;
end
...
endcase
end

always @(posedge clk or negedge rst)
begin
if(!rst) state <= wr_st;
else     state <= nextstate;
end
always @(*)
begin
case(state)
wr_st: if(end)  nextstate = rd_st;
else      nextstate = wr_st;
rd_st: if(jump) nextstate = erase_st
else      nextstate = rd_st;
...
end
endcase
always @(posedge clk)
begin
case(nextstate)
wr_st: if(end) q <= 1;
else    q <= 0;
rd_st:  if(end) p <= 0;
else    p <= 1;
...
endcase
end

1.书本网上大部分状态机例程的第三段都是基于nextstate输出的，很少看到有基于state输出的，这就形成了一种思维定势，认为三段式的第三段只能基于nextstate描述。
2.当三段式状态机的输出基于nextstate描述时，无法用同一个输入信号即触发当前状态跳转，又控制当前状态输出正确逻辑，上述例子中A时刻q的错误输出印证了这一点，end可以触发状态从wr_st跳转到rd_st，但无法同时让q输出1。

always @(*)
begin
case(state)
wr_st0: if(end)  nextstate = wr_st1;
else      nextstate = wr_st0;
wr_st1:             nextstate = rd_st;
rd_st:  if(jump) nextstate = erase_st;
else       nextstate = rd_st;
...
end
endcase
always @(posedge clk)
begin
case(nextstate)
wr_st0:          q <= 0;
wr_st1:          q <= 1;
rd_st: if(end) p <= 0;
else    p <= 1;
...
endcase
end

always @(posedge clk)
begin
case(state)
wr_st: if(end) q <= 1;
else       q <= 0;
rd_st: if(end)  p <= 0;
else       p <= 1;
...
endcase
end

case(cstate)
...
RD_S1: if(wr_req) nstate <= WR_S2;
else          nstate <= RD_S2;
RD_S2: if(wr_req) nstate <= WR_S1;
else          nstate <= IDLE;
...
endcase
...
case(nstate)
...
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;
...
endcase

case (next)
S0, S2, S4, S5 : ; // default outputs
S7             :   y3 <= 1'b1;
S1             :   y2 <= 1'b1;
S3             : begin
y1 <= 1'b1;
y2 <= 1'b1;
end
S8             : begin
y2 <= 1'b1;
y3 <= 1'b1;
end
S6, S9         : begin
y1 <= 1'b1;
y2 <= 1'b1;
y3 <= 1'b1;
end
endcase

• 本文已收录于以下专栏：

举报原因： 您举报文章：三段状态机的思维陷阱 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)