# 三段状态机的思维陷阱

405人阅读 评论(0)

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

0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：98166次
• 积分：1714
• 等级：
• 排名：千里之外
• 原创：60篇
• 转载：125篇
• 译文：0篇
• 评论：0条
阅读排行