教材上的例子--有限状态机,四种建模方式

来源:互联网 发布:淘宝卖家怎样优化标题 编辑:程序博客网 时间:2024/04/28 15:06

下图是教材中的例子,教材采用四种方法建模,具体随后道来:



方法一:

(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
  
  

      

0 0
原创粉丝点击