有限狀態機--優化版

1、在前面《有限狀態機--更正版》的建模模塊中,我採取了左圖方法建模,得出下圖一正確結果

module fsm5(clock,reset,coin,news_out);

  input clock,reset;
  input [1:0]coin;
  output news_out;
  
  reg [1:0]pres_state;
  reg rnews_out;
  
  
  parameter s0=2'd0;
  parameter s1=2'd1;
  parameter s2=2'd2;
  parameter s3=2'd3;
  
  
  
  always @(posedge clock)
  begin
    if(!reset)
      pres_state<=s0;
    else
    case(pres_state) 
      s0 :
        case(coin)
          2'd0 : 
          begin
            pres_state<=s0;
            rnews_out<=0;
          end
          2'd1 : 
          begin
            pres_state<=s1;
            rnews_out<=0;
          end
          2'd2 : 
          begin
            pres_state<=s2;
            rnews_out<=0;
          end
        endcase
    
      s1 :
        case(coin)
          2'd0 :
          begin
            pres_state<=s1;
            rnews_out<=0;
          end
          2'd1 :
          begin
            pres_state<=s2;
            rnews_out<=0;
          end
          2'd2 : 
          begin
            pres_state<=s0;
            rnews_out<=1;
          end
        endcase
    
      s2 :
        case(coin)
          2'd0 :
          begin
            pres_state<=s2;
            rnews_out<=0;
          end
          2'd1 : 
          begin
            pres_state<=s0;
            rnews_out<=1;
          end
          2'd2 : 
          begin
            pres_state<=s0;
            rnews_out=1;
          end
        endcase
      s3 :
        begin
          rnews_out=1;
          pres_state<=s0;
        end
    endcase
  end

  

圖一


2、但我若添加一個next_state中間寄存器,編寫代碼。出現下面圖2結果:

module finite_state_module(clock,reset,coin,news_out);
  input clock,reset;
  input [1:0]coin;
  output news_out;
  
  reg [1:0]pres_state,next_state;
  reg rnews_out;
  
  
  parameter s0=2'd0;
  parameter s1=2'd1;
  parameter s2=2'd2;
  parameter s3=2'd3;
  
  
  always @(posedge clock,negedge reset)
  begin
    if(!reset)
     begin
        pres_state<=s0;
       
     end
    else
      pres_state<=next_state;
  end
   

//這種建模方式與方法一的差別即是方法二採用兩個過程塊,並設置了中間變量next_state,第一個always過程塊是根據時鐘變化,將 pres_state置爲next_state,而第二個always過程塊是根據 pres_state,coin的變化,更改next_state和news_out。而方法一種採用一個always過程塊,當上升沿到來時,根據coin的變化,直接更改pres_state和news_out的狀態。
  always @(pres_state,coin)

  begin
    case(pres_state) 
      s0 :
        case(coin)
          2'd0 : 
          begin
            next_state=s0;
            rnews_out=0;
          end
          2'd1 : 
          begin
            next_state=s1;
            rnews_out=0;
          end
          2'd2 : 
          begin
            next_state=s2;
            rnews_out=0;
          end
        endcase
    
      s1 :
        case(coin)
          2'd0 :
          begin
            next_state=s1;
            rnews_out=0;
          end
          2'd1 :
          begin
            next_state=s2;
            rnews_out=0;
          end
          2'd2 : 
          begin
            next_state=s0;
            rnews_out=1;
          end
        endcase
    
      s2 :
        case(coin)
          2'd0 :
          begin
            next_state=s2;
            rnews_out=0;
          end
          2'd1 : 
          begin
            next_state=s0;
            rnews_out=1;
          end
          2'd2 : 
          begin
            next_state=s0;
            rnews_out=1;
          end
        endcase
      s3 :
        begin
          rnews_out=1;
          next_state=s0;
        end
    endcase
  end
    
  assign news_out=rnews_out;
    
endmodule


       圖二


圖一圖一對比可知,圖二在仿真時刻30ns,news_out就變成了“1”,但此時暫時只輸入了兩個“01”,即投入兩個5毛,還沒達到一塊五狀態。除此之外,後面的仿真波形都是對的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章