关于有限状态机(FSM)

一、什么是状态机

        英文名为Finite State Machine,指的是在有限个状态之间按照一定规律进行转换的电路。

Mealy型状态机

输出由当前状态和初始输入共同决定

Moore型状态机

输出仅由当前状态决定

二、状态机的编码

二进制编码

        使用二进制的编码方式对状态进行编码,特点是编码简单,符合计数规则。例如要对S0,S1,S2,S3这四个状态进行编码,则可以编码为00  01  10  11。

        二进制编码的优点是定义状态时编码所占用的位宽小,缺点是状态变化时发生改变的比特位多,容易产生毛刺。

独热编码

        特点是状态寄存器在任何状态时都只有一个比特位为高位,其余全为低位。例如要对S0,S1,S2,S3这四个状态进行编码,则可以编码为0001  0010  0100  1000。

        优点是状态定义中只有一个比特位为1,其余全为0,缺点是有多少个状态就需要多少个位宽,比较占用资源。

格雷编码

        特点是相邻的两个状态寄存器的二进制数赋值只有一个比特位不同。例如要对S0,S1,S2,S3这四个状态进行编码,则可以编码为00  01  11  10。

        格雷编码的优点是状态转换时只有一比特发生改变,减少了毛刺的产生,但这种编码的可读性较低

三、如何构建状态机(三段式构建状态机)

第一段,使用时序逻辑对实现现态次态之间的跳转;第二段,使用组合逻辑实现状态转移;第三段使用时序逻辑实现输出。

以HDLBits上面的一题为例,下面是题目描述。题目就不翻译了,不难看懂。

首先画出他的状态转移图,如下:

第一段,格式化描述次态转移到现态

 //复位设定
    always@(posedge clk)
        begin
            if(reset)
                state<=state_1;
            else 
                state<=next_state;
        end
    

注意现态state要写在赋值语句左边,不然会出现以下报错(debug了半下午才找到错误,没用代码天赋的人是这样的,悲~~~)

第二段,描述状态间的转移。代码如下

always@(*)
        begin
            case(state)
                state_1:
                    begin
                        if(s[3:1]==3'b001)
                            next_state=state_2;
                        else 
                            next_state=state_1;
                    end
                state_2:
                    begin
                        if(s[3:1]==3'b011)
                            next_state=state_3;
                        else if(s[3:1]==3'b001)
                            next_state=state_2;
                        else
                            next_state=state_1;
                    end
                state_3:
                    begin
                        if(s[3:1]==3'b111)
                            next_state=state_4;
                        else if(s[3:1]==3'b001)
                            next_state=state_2;
                        else
                            next_state=state_3;
                    end
                state_4:
                    begin
                        if(s[3:1]==3'b111)
                            next_state	=	state_4;
                        else
                            next_state	=	state_3;
          		  end

第三段,输出设置,代码如下。

关于dfr的输出,一开始我写的注释块里面的,但是一直输出不正确,后面参考另一位大佬写的代码写成如下形式,这两种写法不是一样吗???没搞懂


    // always@(posedge clk)
    //    begin
     //       dfr=((state==state_1)||(next_state < state));
     //   end
    reg	state_lower;
    always@(posedge	clk)begin
        if(reset||state<next_state)
            state_lower	<=	1'b0;
        else	if(state>next_state)
            state_lower	<=	1'b1;

    end
	
    assign	dfr	=	(state==state_1)||(state_lower);
    
    
    
    //输出
    always@(*)
        begin
            if(state==state_1)
                begin
                    fr1=1;
                    fr2=1;
                    fr3=1;
                end
            else if(state==state_2)
                begin
                    fr1=1;
                    fr2=1;
                    fr3=0;
                end
            else if(state==state_3)
                begin
                    fr1=1;
                    fr2=0;
                    fr3=0;
                end
            else if(state==state_4)
                begin
                    fr1=0;
                    fr2=0;
                    fr3=0;
                end
        end 
    
endmodule

###参考正点原子视频,《FPGA大道至简的至简设计法》,HDLBits。如有侵权,请联系删除

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值