FPGA中有限状态机的设计原理

目录

1.有限状态机(FSM)原理

2.设计可综合状态机的指导原则


1.有限状态机(FSM)原理

有限状态机是由寄存器和组合逻辑构成的硬件时序电路。有限状态机的状态(即由寄存器组的1和0的组合所构成的有限个状态)只可能在同一时钟变沿情况下才能从一个状态跳转到另一个状态

有限状态机的下一个状态不但取决于各个输入值,还取决于当前所在状态。这里指的是米里Mealy型有限状态机,而莫尔Moore型有限状态机的下一个状态只取决于当前状态。

Verilog中可以使用许多种方法来描述有限状态机,最常用的方法是用always语句和case语句。如图所示:

如上图所示是一个四状态的有限状态机。它的同步时钟是Clock,输入信号是A和Reset,输出信号是F和G。状态的转移只能在同步时钟(Clock)的上升沿时发生,往哪个状态的转移则取决于目前所在的状态和输入的信号(Reset和A)。

Gray码有限状态机模型:

module    fsm(Clock,Reset,A,F,G);

input    Clock,Reset,A;
output    F,G;

reg    F,G;
reg [1:0] state;

parameter    Idle = 2'b00,Start = 2'b01,Stop = 2'b10, Clear = 2'b11;

always    @(posedge Clock)
    begin
        if(!Reset)
            begin
                state <= Idle;
                F <= 0;
                G <= 0; 
            end
        else
            begin
                case(state)
                    Idle:
                        begin
                            if(A)
                                begin
                                    state <= Start;
                                    G<=0;
                                end
                            else
                                state <= Idle;
                        end
                    
                    Start:
                        begin
                            if(!A)
                                state <= Stop;
                            else
                                state <= Start;
                        end
                

                    Stop:
                        begin
                            if(A)
                                begin
                                    state <= Clear;
                                    F <= 1;
                                end
                            else
                                state <= Stop;
                        end

                    Clear:
                        begin
                            if(!A)
                                begin
                                    state <= Idle;
                                    F <= 0;
                                    G <= 1;
                                end
                            else
                                state <= Clear;
                        end
                endcase
            end
    end

endmodule

使用独热码有限状态和模型:

module    fsm(Clock,Reset,A,F,G);

input    Clock,Reset,A;
output    F,G;

reg    F,G;
reg [1:0] state;

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

always    @(posedge Clock)
    begin
        if(!Reset)
            begin
                state <= Idle;
                F <= 0;
                G <= 0; 
            end
        else
            begin
                case(state)
                    Idle:
                        begin
                            if(A)
                                begin
                                    state <= Start;
                                    G<=0;
                                end
                            else
                                state <= Idle;
                        end
                    
                    Start:
                        begin
                            if(!A)
                                state <= Stop;
                            else
                                state <= Start;
                        end
                

                    Stop:
                        begin
                            if(A)
                                begin
                                    state <= Clear;
                                    F <= 1;
                                end
                            else
                                state <= Stop;
                        end

                    Clear:
                        begin
                            if(!A)
                                begin
                                    state <= Idle;
                                    F <= 0;
                                    G <= 1;
                                end
                            else
                                state <= Clear;
                        end
                    
                    deafult:state <= Idle;
                endcase
            end
    end

endmodule

上面两种主要不同在于状态码方式,对于用FPGA实现的有限状态机建议使用独热码。因为虽然采用独热码多用了两个触发器,但所用组合电路可以省下许多,因而使电路的速度和可靠性有显著提高,而总的单元数并无显著增加。采用了独热码后有了多余的状态,就有一些不可到达的状态,为此在case语句的最后需要增加default分支项,以确保多余状态能回到Idle状态。

另外还可以用另外一种风格的Verilog模型表示同一个有限状态。在这个模型中,用always语句和连续赋值语句把状态机的触发器部分和组合逻辑部分分成两部分来描述。即:

module    fsm(Clock,Reset,A,F,G);

input    Clock,Reset,A;
output    F,G;

reg    F,G;
reg [1:0] state;

wire    [1:0] Nextstate;

parameter    Idle = 2'b00,Start = 2'b01,Stop = 2'b10, Clear = 2'b11;

always @(posedge Clock)
    begin
        if(!Reset)
            begin
                state <= Idle;
            end
        else
            begin
                state <= Nextstate;
            end
    end

assign Nextstate = 
        (state == Idle)?(A?Start:Idle):
        (state == Start)?(!A?Stop:Start):
        (state == Stop)?(A?Clear:Stop):
        (state == Clear)?(!A?Idle:Clear):Idle;

assign  F = ((state == Stop) && A);        //状态输出
assign G = ((state == Clear) && (!A || !Reset));    //状态输出
endmodule

使用沿触发的always语句和电平敏感的always语句把状态机的触发器部分和组合逻辑部分分成两部分来描述。

module    fsm(Clock,Reset,A,F,G);

input Clock,Reset,A;

output F,G;

reg [1:0] state,Nextstate;

parameter    Idle = 2'b00,Start = 2'b01,Stop = 2'b10,Clear = 2'b11;

always @(posedge Clock)
    begin
        if(!Reset)
            begin
                state <= Idle;
            end
        else
            begin
                state <= Nextstate;
            end
    end

always @(state or A)
    begin
       F = 0;
       G = 0;
        if(state == Idle)
            begin
                if(A)
                    Nextstate = Start;
                else
                    Nextstate = Idle;
                G = 1;
            end 
        else if(state == Start)
            begin
                if(!A)
                    Nextstate = Stop;
                else
                    Nextstate = Start;
            end
        esle if(state == Stop)
            begin
                if(A)
                    Nextstate = Clear;
                else
                    Nextstate = Stop;
            end
        else if(state == Clear)
            begin
                if(!A)
                    Nextstate = Idle;
                else
                    Nextstate = Clear;
                F = 1;
            end
        else
            Nextstate = Idle;
    end
endmodule

上面四个例子是同一状态机的4种不同的Verilog模型,它们都是可综合的,在设计复杂程度不同的状态机时有它们各自的优势。如果不同的综合器对这4个例子进行综合,综合出来的逻辑电路可能会有些不同,但逻辑功能是相同的。

再来看一个简单的例子,代码为:

module    statmch1(launch_shuttle,land_shuttle,start_countdown,start_trip_meter,clk,Reset,all_systems_go,just_launched,is_landed,cnt,abort_mission);

//I/O说明
output lanuch_shuttle,land_shuttle,start_countdown,start_trip_meter;

input clk,Reset,just_launched,is_landed,abort_mission,all_systems_go;

input [3:0] cnt;

reg  launch_shuttle,land_shuttle,start_countdown,atart_trip_meter;
reg [4:0] present_state,next_state;
//设置独热码状态的参数
parameter HOLD = 5'h1, SEQUENCE = 5'h2, LAUNCH = 5'h4;
parameter ON_MISSION = 5'H8,LAND = 5'h10;

always @(posedge clk or posedge abort_mission)
    begin
        if(!Reset)
            begin
                launch_shuttle <= 0;
                land_shuttle <= 0;
                start_trip_meter <= 0;
                start_countdown <= 0;
            end
        else
            begin
                if(abort_mission)
                    next_state <= LAND;
                else
                    begin
                        next_state = present_state;//如果abort_mission为0,把 next_state赋值为present_state
//根据present_state和输入信号,设置next_state和输出output
                        case(present_state)
                            HOLD:
                                begin
                                    if(all_systems_go)
                                        begin
                                            next_state <= SEQUENCE;
                                            start_countdown = 1;
                                        end
                                end


                            SEQUENCE:
                                begin
                                    if(cnt==0)
                                        next_state <= LAUNCH;
                                end

                            LAUNCH:
                                begin
                                    next_state <= ON_MISSION;
                                    launch_shuttle <= 1;
                                end

                            ON_MISSION:
                                begin
                                    if(just_launched)
                                        start_trip_meter <= 1;
                                end

                            LAND:
                                begin
                                    if(is_landed)
                                        next_state <= HOLD;
                                    else
                                        land_shuttle <= 1;
                                end
                             default:next_state <='bx;
                        endcase
                    end
            end
present_state <= next_state;
    end

endmodule

2.设计可综合状态机的指导原则

(1)独热码

因为大多数FPGA内部的触发器数目相当多,又加上独热码状态机(one hot state machine)的译码逻辑最为简单,所以在设计采用FPGA实现状态机时,往往采用独热码状态机(即每个状态只有一个寄存器置位的状态机)。

(2)case语句

建议采用case、casex或casez语句来建立状态机的模型。因为这些语句表达清晰明白了,可以方便的从当前状态分支转向下一个状态并设置输出。

采用这些语句设计状态机时,不要忘记写上case语句的最后一个分支default,并将状态变量设为'bx。这就等于告知综合器;case语句已经指定了所有状态。这样综合器就可以删除不需要的译码电路,使生成的电路简洁,并与设计要求一致。

如果缺省状态设置为某一确定的转改(例如:设置为default:state=statel),行不行呢?这样做有一个问题需要注意:因为尽管综合器产生的逻辑和设置“default:state='bx”时相同,但是状态机的Verilog模型综合前和综合后的仿真结果会不一致。

为什么会这样呢?因为启动仿真器时,状态机所有的输入都不确定,因此立即进入default状态。如果通过设置将状态变量设为statel,但是实际硬件电路的状态机在通电之后,进入的状态是不确定的,很可能不是statel的状态,这样就会产生不必要的冲突。因此设置“default:state='bx”与实际硬件电路相一致。但在有多余状态的情况下还是应将缺省状态设置为某一确定的有效状态,因为这样做能使状态机若偶然进入多余状态后仍能在下一时钟跳变沿时返回正常的工作状态,否则会引起死锁。

(3)复位

状态机应该有一个异步或同步复位端,以便在通电时将硬件电路复位到有效状态,也可以在操作中将硬件电路复位(大多数FPGA结构都允许使用异步复位端)。

(4)惟一触发

目前大多数综合器往往不支持在一个always块中由多个事件触发的状态机(即隐含状态机,implicit state manchines)。因此为了能综合出有效电路,用Verilog描述的状态机应明确的由惟一时钟触发。

(5)异步状态机

异步状态机是没有确定时钟的状态机,它的状态转移不是由惟一的时钟跳变沿所触发。目前大多数综合器不能综合采用Verilog描述的异步状态机。

因此应尽量不要使用综合工具来设计异步状态机。因为目前大多数综合工具对异步状态机进行逻辑优化时会胡乱的简化逻辑,是综合后的异步状态机不能正常工作。如果一定要设计异步状态机,建议采用电路图输入的方法,而不要用Verilog输入的方法。

(6)状态赋值

Verilog中,状态必须明确赋值,通常使用参数parameter或宏定义define语句加上赋值语句来实现。

使用参数parameter语句赋值状态如下:

parameter state1 = 2'h1,state2 = 2'h2;
...
curretn_state = state2;//把current_state设置为2'h2
...

使用宏定义define语句赋状态值如下所示:

'define state1 2'h1
'define state2 2'h2
...
'define state = state2; //把current_state设置成2'h2

 

 

 

 

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FPGA的VHDL编程有限状态机(Finite State Machine,FSM)是一种常用的设计方法。有限状态机是一种具有有限个状态和状态转移规则的计算模型,可以用来描述电路或系统的行为。 在VHDL实现有限状态机,通常需要定义状态信号(state signal)来表示当前的状态,以及一个状态转移过程来定义状态之间的转换规则。可以使用if-then-else结构、case语句或者when-else结构来实现状态转移逻辑。 以下是一个简单的例子,展示了一个基于VHDL的有限状态机的实现: ```vhdl entity fsm_example is port ( clk : in std_logic; reset : in std_logic; input : in std_logic; output : out std_logic ); end fsm_example; architecture behavioral of fsm_example is type state_type is (StateA, StateB, StateC); signal current_state, next_state : state_type; begin process(clk) begin if rising_edge(clk) then if reset = '1' then current_state <= StateA; -- 初始状态 else current_state <= next_state; -- 更新当前状态 end if; end if; end process; process(current_state, input) begin case current_state is when StateA => if input = '1' then next_state <= StateB; -- 状态转移 else next_state <= StateA; -- 保持当前状态 end if; when StateB => if input = '1' then next_state <= StateC; -- 状态转移 else next_state <= StateB; -- 保持当前状态 end if; when StateC => if input = '1' then next_state <= StateA; -- 状态转移 else next_state <= StateC; -- 保持当前状态 end if; end case; end process; output <= '1' when current_state = StateC else '0'; -- 根据状态输出结果 end behavioral; ``` 在这个例子,有三个状态(StateA、StateB和StateC),输入信号为input,输出信号为output。根据输入信号和当前状态,通过状态转移逻辑来更新下一个状态。 当输入信号为'1'时,状态从StateA转移到StateB,然后转移到StateC,最后循环回到StateA;当输入信号为'0'时,状态保持不变。 这只是一个简单的例子,实际应用有限状态机可能更加复杂。但基本思路都是类似的,通过定义状态变量和状态转移逻辑来实现所需的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值