题解主体

1、确定题目要求

首先,存在S0~S4的四个态,需要注意的是S4到S0的转换和S4到S1的转换,发现对于S4输出flag为1的时候输入是什么无所谓,说明最后的输出控制是由现态单独控制的,因此是摩尔机。



1

0

现态代号

次态代号

次态代号

S0

S1

S0

S1

S2

S1

S2

S3

S2

S3

S4

S3

S4

S1

S0

蓝色代表输出,摩尔机最后添加了状态S4,从状态转移上看输出节拍会晚一拍,但由于是组合逻辑输出,因此实际上并没有晚一拍



知识补充:

一般来说,两段式和三段式的描述方法主要是针对摩尔机来讲的,个人认为,写硬件代码不需要纠结于具体是哪一种状态机和哪一种段式分布,而应该注意实际需求:1、是否要求检测到后同步输出结果(否则结果晚一拍) 2、是否需要寄存器输出

摩尔机二段式描述法状态转移逻辑

二段式包含二个进程:


第一个进程(同步时序always),描述次态到现态的转移

第二个进程(组合逻辑always),描述状态转移条件的判断,组合逻辑输出



2、按照状态转移写出二段式状态机



    parameter S0 = 'd0, S1 = 'd1, S2 = 'd2, S3 = 'd3 ,S4 = 'd4 ;

    reg [2:0]  current_state;

    reg [2:0]  next_state;

      

    always@(posedge clk or negedge rst)begin

        if(rst == 1'b0)begin

            current_state <= S0;

        end

        else begin

            current_state <= next_state;

        end

    end  

   

    always@(*)begin

        case(current_state)

            S0:begin

                next_state = data ? S1 : S0;

                            flag = 1'b0;

            end

            S1:begin

                next_state = data ? S2 : S1;

                            flag = 1'b0;

            end

            S2:begin

                next_state = data ? S3 : S2;

                            flag = 1'b0;

            end

            S3:begin

                next_state = data ? S4 : S3;

                            flag = 1'b0;

            end

                     S4:begin

                         next_state = data ? S1 : S0;

                            flag = 1'b1;

                     end

            default:begin 

                            next_state = S0;

                            flag = 1'b0;                        

                     end

        endcase

    end


endmodule

参考答案

`timescale 1ns/1ns


module fsm2(
	input wire clk  ,
	input wire rst  ,
	input wire data ,
	output reg flag
);

    parameter S0 = 'd0, S1 = 'd1, S2 = 'd2, S3 = 'd3 ,S4 = 'd4 ;
    reg [2:0]	current_state;
    reg [2:0]	next_state;
	
    always@(posedge clk or negedge rst)begin
        if(rst == 1'b0)begin
            current_state <= S0;
        end
        else begin
            current_state <= next_state;
        end
    end   
    
    always@(*)begin
        case(current_state)
            S0:begin
                next_state = data ? S1 : S0;
				flag = 1'b0; 
            end
            S1:begin
                next_state = data ? S2 : S1;
				flag = 1'b0;
            end
            S2:begin
                next_state = data ? S3 : S2;
				flag = 1'b0;
            end
            S3:begin
                next_state = data ? S4 : S3;
				flag = 1'b0;
            end
			S4:begin
			    next_state = data ? S1 : S0;
				flag = 1'b1;
			end
            default:begin  
				next_state = S0;
				flag = 1'b0;				
			end
        endcase
    end

endmodule