欢迎光临散文网 会员登陆 & 注册

FPGA学习笔记-三段式状态机

2023-06-30 11:38 作者:snow_404  | 我要投稿

        类似多分支语句,更自由一些可以自定义多个分支的跳转条件和每个分支下的行为,每一个分支叫做一个状态。

        状态机四要素:现态,次态,条件,动作。

        优:方便纠错,逻辑清晰。                缺:费时序逻辑资源。

通用格式

        由三个always语句构成,一般第一段和第三段为时序逻辑,第二段为组合逻辑。

        第一段为定义当前状态到下一个状态的转换。(现态与次态的状态切换)

        第二段描述状态转换的条件。(根据现态和条件确定次态)

        第三段表现当前状态下的行为。(根据现态和条件确定每个状态的动作)

状态转换图

        写状态机之前最好提前决定好需要多少个状态,每个状态之间切换的条件是什么理清思路再写。

        例如让4个led灯每隔1s切换一个亮,就需要一个空闲态加上4个led灯分别亮的4个状态一共5个状态。(并不是一定要按照顺序切换状态也不是一定要有空闲态,根据实际情况来)

状态编码

二进制编码:节省位宽。(十进制的0,1,2,3)

例如:2'd0 2'd1 2'd2 2'd3 

独热码:简单,译码快。(每个状态一个高电平)

例如:4'b0001  4'b0010  4'b0100  4'b1000

格雷码:减少竞争冒险的概率。(相邻状态之间仅有一位变化)

例如:3'b000  3'b001  3'b011  3'b111  3'b110  3'b100  3'b101 

竞争冒险

        竞争:在同一个逻辑门中,有两路相反的信号到达目标门的时间有先有后导致在时间上产生的差异现象。

        冒险:由竞争产生的尖峰脉冲的现象。

解决办法:并联滤波电容(通交流,阻直流) 接入选通脉冲(使能信号) 修改逻辑设计(增加冗余项)三种办法。

//状态机实现流水灯

`timescale 1ns / 1ps

module biji_1(

    input sysclk,

    input rst_n,

    output reg [3:0]led

    );

    

localparam idle=3'd0;//状态编码

localparam s1=3'd1;  //状态编码

localparam s2=3'd2;  //状态编码

localparam s3=3'd3;  //状态编码

localparam s4=3'd4;  //状态编码

reg [3:0] cur_state;//当前状态

reg [3:0] next_state;//下一个状态

localparam delay=50_000_000;//1s

reg [31:0] cnt;//计时器


always@(posedge sysclk)//1s计时器

    if (!rst_n)

        cnt<=0;

    else if (cnt == delay-1)

        cnt<=0;

    else

        cnt<=cnt+1;


always@(posedge sysclk)//一段

    if (!rst_n)

        cur_state<=idle;

    else

        cur_state<=next_state;


always@(*)//二段

    if (!rst_n)

        next_state=idle;

    else

        case(cur_state)

            idle:begin

                if (cnt == delay-1)//条件

                    next_state=s1;

                else

                    next_state=idle;

            end

            s1:begin

                if (cnt == delay-1)

                    next_state=s2;

                else

                    next_state=s1;

            end  

            s2:begin

                if (cnt == delay-1)

                    next_state=s3;

                else

                    next_state=s2;

            end

            s3:begin

                if (cnt == delay-1)

                    next_state=s4;

                else

                    next_state=s3;

            end

            s4:begin

                if (cnt == delay-1)

                    next_state=s1;

                else

                    next_state=s4;

            end

        default next_state=idle;

        endcase


always@(posedge sysclk)

    if (!rst_n)

        led<=4'b0000;

    else

        case(cur_state)

            idle:led<=4'b0000;

            s1:led<=4'b1000;

            s2:led<=4'b0100;

            s3:led<=4'b0010;

            s4:led<=4'b0001;

        default led<=4'b0000;

        endcase

endmodule

FPGA学习笔记-三段式状态机的评论 (共 条)

分享到微博请遵守国家法律