教材上的例子--有限狀態機,四種建模方式

下圖是教材中的例子,教材採用四種方法建模,具體隨後道來:



方法一:

(1)、建模

module fsm1(Clock,Reset,A,K1,K2);
  input Clock,Reset,A;
  output K1,K2;


  
  reg K1,K2;
  reg [1:0]state;
  
  //Gray碼
  parameter Idle=2'b00;
  parameter Start=2'b01;
  parameter Stop=2'b10;
  parameter Clear=2'b11;
 
            
  always @(posedge Clock)
  if(!Reset)
    begin
      state<=Idle;
      K1=0;
      K2=0;
    end
  else
    case(state)
      Idle:if (A) 
            begin
              state<=Start;
              K1<=0;
            end
          else
            begin
              state<=Idle;
              K1<=0;
              K2<=0;
            end
       Start:if (A) 
            begin
              state<=Start;
              K1<=0;
              K2<=0;
            end
            else
            begin
              state<=Stop;
            end 
        Stop:if (A) 
            begin
              state<=Clear;
              K2<=1;
            end
            else
            begin
              state<=Stop;
              K2<=0;
              K1<=0;
            end 
        Clear:if (A) 
            begin
              state<=Clear;
              K2<=0;
              K1<=0;
            end
            else
            begin
              state<=Idle;
              K2<=0;
              K1<=1;
            end
        default: state<=2'bxx;
      endcase 


endmodule


(2)仿真圖:



方法二:

module fsm2(Clock,Reset,A,K1,K2);
  input Clock,Reset,A;
  output K1,K2;


  
  reg K1,K2;

  //reg [1:0]state;

reg [1:0]state;

//這種方法與方法一,其實是一樣的,只是在對state狀態的編碼方法不同,方法一採取的是格雷碼,方法二採取的是獨熱碼,採用FPGA實現的有限狀態機更適合採用獨熱碼。但在此例中,開始不知爲何採用獨熱碼,k1和k2一直爲0,仿真不出來結果。後來才發現,是上面這行藍色代碼的錯誤,state採用獨熱碼編寫,總共有四位,但,[1:0]state只有兩位,仿真結果肯定錯誤。


 

  parameter Idle=4'1000;
  parameter Start=4'b0100;
  parameter Stop=4'b0010;
  parameter Clear=4'b0001;

 


 always @(posedge Clock)
  if(!Reset)
    begin
      state<=Idle;
      K1=0;
      K2=0;
    end
  else
    case(state)
      Idle:if (A) 
            begin
              state<=Start;
              K1<=0;
            end
          else
            begin
              state<=Idle;
              K1<=0;
              K2<=0;
            end
       Start:if (A) 
            begin
              state<=Start;
              K1<=0;
              K2<=0;
            end
            else
            begin
              state<=Stop;
            end 
        Stop:if (A) 
            begin
              state<=Clear;
              K2<=1;
            end
            else
            begin
              state<=Stop;
              K2<=0;
              K1<=0;
            end 
        Clear:if (A) 
            begin
              state<=Clear;
              K2<=0;
              K1<=0;
            end
            else
            begin
              state<=Idle;
              K2<=0;
              K1<=1;
            end
        default: state<=2'bxx;
      endcase 


endmodule

方法三:將state狀態也設置爲輸出,通過state輸出的編碼,反映k1和k2的變化,在狀態轉換建模上,方法三與方法二,方法一都是一致的:

module fsm3(Clock,Reset,A,K1,K2,state);
  input Clock,Reset,A;
  output K1,K2;
  output [4:0]state;
  
  reg [4:0]state;
  
  //???k1?k2??wire???
  assign K1=state[0];
  assign K2=state[4];
  
  //k1,k2????????state?
  parameter Idle=5'b0_0_0_0_0;
  parameter Start=5'b0_0_0_1_0;
  parameter Stop=5'b0_0_1_0_0;
  parameter Clear=5'b0_1_0_1_0;
  //??????????k1?k2?????state?????
  parameter Stop_Clear=5'b1_1_0_0_0;
  parameter Clear_Idle=5'b0_0_1_1_1;
 
            
  always @(posedge Clock)
  if(!Reset)
    begin
      state<=Idle;
    
    end
  else
    //?????????k1?k2????????????
    //???k2?k1???????state????
    case(state)
      Idle:if (A) 
            begin
              state<=Start;
              //K1<=0;
            end
          else
            begin
              state<=Idle;
              //K1<=0;
              //K2<=0;
            end
       Start:if (A) 
            begin
              state<=Start;
              //K1<=0;
              //K2<=0;
            end
            else
            begin
              state<=Stop;
            end 
        Stop:if (A) 
            begin
              state<=Stop_Clear;
              //K2<=1;
            end
            else
            begin
              state<=Stop;
              //K2<=0;
              //K1<=0;
            end
        
        Stop_Clear:state<=Clear;
         
        Clear:if (A) 
            begin
              state<=Clear;
              //K2<=0;
              //K1<=0;
            end
            else
            begin
              state<=Clear_Idle;
              //K2<=0;
              //K1<=1;
            end
         Clear_Idle: state<=Idle;  
            
        default: state<=2'bxx;
      endcase 


endmodule
      
(2)仿真圖:



方法四:

(1)、建模:這種方法相對前面幾種一個方法添加了一個nextstate變量,然後建模時,一個always過程反映當前的state狀態改變,即上升沿到來時,state<=nextstate;但沒有指明這個nextstate具體是什麼。第二個always過程是根據state和A的變化,設定nextstate變量值的變化。第三個always過程是反映k1的變化,第四個always過程是反映k2的變化。(分過程快反映個變量的變化,而前面方面都是在一個過程塊中反映所有變量的變化)

module fsm4(Clock,Reset,A,K1,K2);

  input Clock,Reset,A;
  output K1,K2;


  
  reg K1,K2;
  reg [1:0]state,nextstate;
  
  //Gray????
  parameter Idle=2'b00;
  parameter Start=2'b01;
  parameter Stop=2'b10;
  parameter Clear=2'b11;
 
 //????????????????
  always @(posedge Clock)
  if(!Reset)
    state<=Idle;
  else
    state<=nextstate;
  
  //??state?A???????????????
            
  always @(state,A)
    case(state)
      Idle:if (A) 
            begin
              nextstate<=Start;
              //K1<=0;
            end
          else
            begin
              nextstate<=Idle;
              //K1<=0;
              //K2<=0;
            end
       Start:if (A) 
            begin
              nextstate<=Start;
              //K1<=0;
              //K2<=0;
            end
            else
            begin
              nextstate<=Stop;
            end 
        Stop:if (A) 
            begin
              nextstate<=Clear;
              //K2<=1;
            end
            else
            begin
              nextstate<=Stop;
              //K2<=0;
              //K1<=0;
            end 
        Clear:if (A) 
            begin
              nextstate<=Clear;
              //K2<=0;
              //K1<=0;
            end
            else
            begin
              nextstate<=Idle;
              //K2<=0;
              //K1<=1;
            end
        default: nextstate<=2'bxx;
      endcase 
  
  //????K1??????
    always @(state,A,Reset)
    if(!Reset)
      K1=0;
    else
      if(state==Clear&&!A)
        K1=1;
      else
        K1=0;
        
        
  //????K2??????
    always @(state,A,Reset)
    if(!Reset)
      K2=0;
    else
      if(state==Stop&&A)
        K2=1;
      else
        K2=0;

endmodule
      

(2)仿真波形:



2、testbench編碼:

`timescale 1ns/1ns


`include "fsm3.v"


module Stimulus_fsm;
  reg Clock,Reset,A;
  wire K1,K2;
  wire [4:0]state;
  
  //fsm2 ff(Clock,Reset,A,K1,K2);
  fsm3 ff(Clock,Reset,A,K1,K2,state);
  
  
  initial
  begin
    A=0;
    Reset=1;
    Clock=0;
    #22 Reset=0;
    #133 Reset=1;
  end
  
  always #50 Clock=~Clock;
  
  always @(posedge Clock )
  begin
    #30 A={$random}%2;
   
  end
  
endmodule
  
  

      

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