原创 三段式状态机 VS 一段式状态机

2014-3-5 10:47 1406 11 11 分类: FPGA/CPLD 文集: FPGA

使用哪种方式的状态机,不能一概而论,切忌“一棍子打死”和“非黑即白”的思想!根据实际情况,选择合适的状态机方式。

三段式相比于一段式,简洁,方便维护,前提:输入输出比较多,比较复杂的状态机。这种情况下,一段式显得 冗长 ,用三段式就比较方便了,如下对比:

一段式:

module top(clk,rst_n,datain1,datain2,datain3,datain4,
     dataout1,dataout2,dataout3,dataout4,dataout5);

input      clk;
input      rst_n;
input      datain1;
input datain2;
input datain3;
input datain4;
output reg [3:0] dataout1,dataout2,dataout3,dataout4,dataout5;

parameter state0=4'd0,state1=4'd1,state2=4'd2,state3=4'd3,state4=4'd4;

reg [3:0] state;
reg [3:0] next_state;
     
always@(posedge clk or negedge rst_n)
if(!rst_n)
 begin
  dataout1<=4'b0;
  dataout2<=4'b0;
  dataout3<=4'b0;
  dataout4<=4'b0;
  dataout5<=4'b0;
  state<=state0;
 end   
else case(state)
     state0:  if(datain1)
                 begin
                 state<=state1;
                 dataout1<=4'd1;
                 dataout2<=4'd2;
                 dataout3<=4'd3;
                 dataout4<=4'd4;
                 dataout5<=4'd5;
                 end
              else if(datain2)
                 begin
                 state<=state2;
                 dataout1<=4'd2;
                 dataout2<=4'd3;
                 dataout3<=4'd4;
                 dataout4<=4'd5;
                 dataout5<=4'd6;
                 end
              else if(datain3)
                 begin
                 state<=state3;
                 dataout1<=4'd3;
                 dataout2<=4'd4;
                 dataout3<=4'd5;
                 dataout4<=4'd6;
                 dataout5<=4'd7;
                 end     
              else if(datain4)
                 begin
                 state<=state4;
                 dataout1<=4'd4;
                 dataout2<=4'd5;
                 dataout3<=4'd6;
                 dataout4<=4'd7;
                 dataout5<=4'd8;
                 end
     state1:  if(datain1)
                 begin
                 state<=state0;
                 dataout1<=4'd5;
                 dataout2<=4'd6;
                 dataout3<=4'd7;
                 dataout4<=4'd8;
                 dataout5<=4'd9;
                 end
              else if(datain2)
                 begin
                 state<=state2;
                 dataout1<=4'd2;
                 dataout2<=4'd3;
                 dataout3<=4'd4;
                 dataout4<=4'd5;
                 dataout5<=4'd6;

                 end
              else if(datain3)
                 begin
                 state<=state3;
                 dataout1<=4'd3;
                 dataout2<=4'd4;
                 dataout3<=4'd5;
                 dataout4<=4'd6;
                 dataout5<=4'd7;
                 end     
              else if(datain4)
                 begin
                 state<=state4;
                 dataout1<=4'd4;
                 dataout2<=4'd5;
                 dataout3<=4'd6;
                 dataout4<=4'd7;
                 dataout5<=4'd8;
                 end
     state2:  if(datain1)
                 begin
                 state<=state1;
                 dataout1<=4'd1;
                 dataout2<=4'd2;
                 dataout3<=4'd3;
                 dataout4<=4'd4;
                 dataout5<=4'd5;
                 end
              else if(datain2)
                 begin
                 state<=state0;
                 dataout1<=4'd5;
                 dataout2<=4'd6;
                 dataout3<=4'd7;
                 dataout4<=4'd8;
                 dataout5<=4'd9;
                 end
              else if(datain3)
                 begin
                 state<=state3;
                 dataout1<=4'd3;
                 dataout2<=4'd4;
                 dataout3<=4'd5;
                 dataout4<=4'd6;
                 dataout5<=4'd7;
                 end     
              else if(datain4)
                 begin
                 state<=state4;
                 dataout1<=4'd4;
                 dataout2<=4'd5;
                 dataout3<=4'd6;
                 dataout4<=4'd7;
                 dataout5<=4'd8;
                 end
     state3:  if(datain1)
                 begin
                 state<=state1;
                 dataout1<=4'd1;
                 dataout2<=4'd2;
                 dataout3<=4'd3;
                 dataout4<=4'd4;
                 dataout5<=4'd5;
                 end
              else if(datain2)
                 begin
                 state<=state2;
                 dataout1<=4'd2;
                 dataout2<=4'd3;
                 dataout3<=4'd4;
                 dataout4<=4'd5;
                 dataout5<=4'd6;
                 end
              else if(datain3)
                 begin
                 state<=state0;
                 dataout1<=4'd5;
                 dataout2<=4'd6;
                 dataout3<=4'd7;
                 dataout4<=4'd8;
                 dataout5<=4'd9;
                 end     
              else if(datain4)
                 begin
                 state<=state4;
                 dataout1<=4'd4;
                 dataout2<=4'd5;
                 dataout3<=4'd6;
                 dataout4<=4'd7;
                 dataout5<=4'd8;
                 end
     state4:  if(datain1)
                 begin
                 state<=state1;
                 dataout1<=4'd1;
                 dataout2<=4'd2;
                 dataout3<=4'd3;
                 dataout4<=4'd4;
                 dataout5<=4'd5;
                 end
              else if(datain2)
                 begin
                 state<=state2;
                 dataout1<=4'd2;
                 dataout2<=4'd3;
                 dataout3<=4'd4;
                 dataout4<=4'd5;
                 dataout5<=4'd6;
                 end
              else if(datain3)
                 begin
                 state<=state3;
                 dataout1<=4'd3;
                 dataout2<=4'd4;
                 dataout3<=4'd5;
                 dataout4<=4'd6;
                 dataout5<=4'd7;
                 end     
              else if(datain4)
                 begin
                 state<=state0;
                 dataout1<=4'd5;
                 dataout2<=4'd6;
                 dataout3<=4'd7;
                 dataout4<=4'd8;
                 dataout5<=4'd9;
                 end
   default:  state<=state0;
   endcase

endmodule


改为三段式:

............

...........

always@(posedge clk or negedge rst_n)
if(!rst_n)
 state<=state0;
else state<=next_state;


always@(state or datain1 or datain2 or datain3 or datain4)
case(state)
       state0: if(datain1)       next_state=state1;
               else if(datain2)  next_state=state2;
               else if(datain3)  next_state=state3;
               else if(datain4)  next_state=state4;
               else next_state=state0;
       state1: if(datain1)       next_state=state0;
               else if(datain2)  next_state=state2;
               else if(datain3)  next_state=state3;
               else if(datain4)  next_state=state4;
               else next_state=state1;      
       state2: if(datain1)       next_state=state1;
               else if(datain2)  next_state=state0;
               else if(datain3)  next_state=state3;
               else if(datain4)  next_state=state4;
               else next_state=state2;
       state3: if(datain1)       next_state=state1;
               else if(datain2)  next_state=state2;
               else if(datain3)  next_state=state0;
               else if(datain4)  next_state=state4;
               else next_state=state3;                 
       state4: if(datain1)       next_state=state1;
               else if(datain2)  next_state=state2;
               else if(datain3)  next_state=state3;
               else if(datain4)  next_state=state0;
               else next_state=state4;         
      default: next_state=state0;
 endcase         
                 
 always@(posedge clk or negedge rst_n)
 if(!rst_n)
  begin
  dataout1<=4'b0;
  dataout2<=4'b0;
  dataout3<=4'b0;
  dataout4<=4'b0;
  dataout5<=4'b0;
 end
 else case(next_state)
   state0:
    begin
     dataout1<=4'd5;
     dataout2<=4'd6;
     dataout3<=4'd7;
     dataout4<=4'd8;
     dataout5<=4'd9;
    end     
    state1:
    begin
     dataout1<=4'd1;
     dataout2<=4'd2;
     dataout3<=4'd3;
     dataout4<=4'd4;
     dataout5<=4'd5;
    end
           state2:
                 begin
                 dataout1<=4'd2;
                 dataout2<=4'd3;
                 dataout3<=4'd4;
                 dataout4<=4'd5;
                 dataout5<=4'd6;
                 end
           state3:
                 begin
                 dataout1<=4'd3;
                 dataout2<=4'd4;
                 dataout3<=4'd5;
                 dataout4<=4'd6;
                 dataout5<=4'd7;
                 end
           state4: 
                 begin
                 dataout1<=4'd4;
                 dataout2<=4'd5;
                 dataout3<=4'd6;
                 dataout4<=4'd7;
                 dataout5<=4'd8;
                 end   
      default:   begin
                 dataout1<=4'd5;
                 dataout2<=4'd6;
                 dataout3<=4'd7;
                 dataout4<=4'd8;
                 dataout5<=4'd9;
                 end
      endcase
   endmodule

程序减少了100多行,简洁了很多 !

可以看到三段式与一段式的最大区别在于:使用一段式建模FSM的寄存器输出的时候,必须要综合考虑现态在何种状态转移条件下会进入哪些次态,然后在每个现态的case分支下分别描述每个次态的输出,这显然不符合思维习惯;而三段式建模描述FSM的状态机输出时,只需指定case 敏感表为次态寄存器,然后直接在每个次态的case分支中描述该状态的输出即可,根本不用考虑状态转移条件。

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
11
关闭 站长推荐上一条 /3 下一条