分享

零基础学FPGA(八)浅谈状态机

 果宝战士书屋 2015-04-26
     module fsm (clk,rst_n,A,k1,k2,State);
input clk;
input rst_n;
input A;
output k1,k2;
output [1:0] State;
reg k1;
reg k2;
reg [1:0] State;   //当前状态寄存器
parameter     Idle = 2'b00,
                       Start = 2'b01,
                       Stop = 2'b10,
                       Clear = 2'b11;            //编码 ,注意,只有在最后一句用分号,其他地方用逗号
always @(posedge clk or negedge rst_n)
  if(!rst_n)  
  begin 
     State <= Idle;
 k1 <=1'b0;
 k2 <=1'b0;
  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) State <= Stop;
       else State  <=  Start;
Stop  :if(A) begin
       State <=Clear;
 k2 <= 1;
 end
else State <= Stop;
Clear :if(!A) begin 
       State <= Clear;
 k2 <= 0;
 k1 <= 1;
 end
 else State <= Clear;
 default : State <= 2'bxx;     //告诉综合器 case语句已经指定了所有状态,这样综合器就会删除不需要的译码电路,使生成的电路简单
endcase  
endmodule 
 //************************小墨品牌,你值得拥有~**************************
下面是另一种写法,叫做输出指定的码表示状态的状态机
//***********************************************************
//**********************小墨笔记*****************************
//由输出指定的码表示状态的状态机
//小墨同学于2014年5月21日在金翰林宿舍作
//用于高速状态机的设计
//************************小墨笔记,留作回忆**********************
module fsm2(clk,rst_n,A,k1,k2,State);
input clk;
input rst_n;
input A;
output k1,k2;
output [4:0] State;
reg [4:0] State;   //当前状态寄存器
assign k1 =State[0];
assign k2 =State[4];
parameter    Idle = 5'b00000,            //采用毒热编码(每个状态只有一个寄存器置位的状态机这样用的组合电路省一些,而且速度也快)
                      Start = 5'b00010,
                      Stop = 5'b00100,
                      StoptoClear = 5'b11000,
                      Clear = 5'b01010,
  CleartoIdle  = 5'b00111;          //编码 ,注意,只有在最后一句用分号,其他地方用逗号
always @(posedge clk or negedge rst_n)
  if(!rst_n)  
     State <= Idle;
  else case (State)                   //状态判断与组合逻辑赋值
       Idle :if(A)  
      State <= Start;
else 
State <= Idle;
Start :if(!A) State <= Stop;
       else State  <=  Start;
Stop  :if(A) 
       State <=StoptoClear;
else State <= Stop;
StoptoClear :State <= Stop;
Clear :if(!A) 
       State <= Clear;
 else State <= Clear;
CleartoIdle :State <= Idle;
 default : State <= Idle;//告诉综合器 case语句已经指定了所有状态,这样综合器就会删除不需要的译码电路,使生成的电路简单
endcase  
endmodule 
 //************************小墨品牌,你值得拥有~**************************
 这样写就是把状态码的指定与状态机控制的输出联系起来,把状态的变化直接作用于输出,这样做可以提高输出信号的开关素的并节省电路器件。但这种方法也有缺点,就是快关的维持时间必须与状态维持的时间一致,这种设计方法常用在告诉状态机中。
下面这种写法应该是以后我们经常要用到的,即三段式状态机写法,比较适合于多输出的状态机设计。
//***********************************************************
//**********************小墨笔记*****************************
//多输出状态时的状态机
//小墨同学于2014年5月31日在金翰林宿舍作
//用于多输出时的状态机设计,也即三段式状态机的常见写法,推荐!
//************************小墨笔记,留作回忆**********************
module fsm3 (clk,rst_n,A,k1,k2,state);
input clk,rst_n,A;
output k1,k2;
output [1:0] state;
reg k1,k2;
reg [1:0] state;
reg [1:0] xiaomo;
parameter Idle = 2'b00,
                    start = 2'b01,
                    stop = 2'b10,
                    clear = 2'b11;
always @ (posedge clk or negedge rst_n)    
       if(!rst_n) state <= Idle;
else state <= xiaomo;      //每一个时钟产生一个可能的变化,即时序逻辑部分
always @ (state or A)      //组合逻辑部分
       begin 
 case (state)
    Idle : if(A) xiaomo = start;
        else  iaomo = Idle;
 start : if(!A)xiaomo = stop;
               else iaomo = start;
 stop  : if(A)xiaomo = clear;
            else iaomo = stop;
 clear : if(!A) xiaomo =Idle;
               else iaomo = clear;
 default : xiaomo = 2'bxx;
     endcase
end
always @ (state or A or rst_n)    //产生输出k1的组合逻辑
      if(!rst_n) k1=0;
else if(state ==clear && !A)
   k1=1;
else k1=0;
always @(state or A or rst_n)      //产生输出k2的组合逻辑
      if(!rst_n) k2=0;
else if(state ==stop && A)
    k2=1;
else k2=0;
endmodule  
 //************************小墨品牌,你值得拥有~**************************

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多