题解主体

1、确定题目要求

首先,序列为1011,因此存在5个态,命名为S0~S4

题目要求:

1 重叠检测,因此在状态转移中,判断非将不会直接返回S0

2 要求寄存器输出但延迟一拍输出结果,因此如果使用三段式描述,需要使用现态作为输出判断标准


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



三段式描述法状态转移逻辑

三段式包含三个进程:

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

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

第三个进程(同步时序always),描述状态的寄存器输出


摩尔机和米勒机的区别:主要区别在于状态机的输出与当前的状态是否有关,下面用两段式来描述两者的区别。

需要注意的是,如果使用三段式描述法,两者的区别主要聚焦于第三段的判断是基于现态还是次态。

摩尔状态机要比米勒状态机少一个状态,摩尔状态机慢一个周期;米勒状态机使用当前输入和当前状态共同判断,摩尔状态机不需要当前输入。


摩尔机

米勒机


2、画出状态转移


画一下状态转移表


现态

N=0

N=1

现态值

现态代号

次态值

次态代号

次态值

次态代号

0

S0

00

S0

01

S1

1

S1

10

S2

11

S1

10

S2

100

S0

101

S3

101

S3

1010

S2

1011

S4

1011

S4

10110

S2

10111

S1

3、按照状态转移写出三段式状态机



    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;

            end

            S1:begin

                next_state = data?  S1 : S2;

            end

            S2:begin

                next_state = data ? S3 : S0;

            end

            S3:begin

                next_state = data ? S4 : S2;

            end

            S4:begin

                next_state = data ? S1 : S2;

            end

             

            default:begin

                next_state = S0;

            end

        endcase

    end

   

    always@(posedge clk or negedge rst)begin

        if(rst == 1'b0)begin

            flag <= 1'b0;

        end

        else begin

            if(current_state == S4)begin

                flag <= 1'b1;

            end

            else begin

                flag <= 1'b0;

            end

        end

    end

 

endmodule

参考答案

`timescale 1ns/1ns



module sequence_test2(
	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;
            end
            S1:begin
                next_state = data?  S1 : S2;
            end
            S2:begin
                next_state = data ? S3 : S0;
            end
            S3:begin
                next_state = data ? S4 : S2;
            end
            S4:begin
                next_state = data ? S1 : S2;
            end
		
            default:begin
                next_state = S0;
            end
        endcase
    end
    
    always@(posedge clk or negedge rst)begin
        if(rst == 1'b0)begin
            flag <= 1'b0;
        end
        else begin
            if(current_state == S4)begin
                flag <= 1'b1;
            end
            else begin
                flag <= 1'b0;
            end
        end
    end
 
endmodule