Verilog学习笔记HDLBits——Finite State Machines(1)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

有限状态机

一、Finite State Machines

1.Simple FSM 1(asychronous reset)

Practice:This is a Moore state machine with two states, one input, and one output. Implement this state machine. Notice that the reset state is B.
This exercise is the same as fsm1s, but using asynchronous reset.
翻译:实现下面这个2状态、1输入、1输出的摩尔型状态机(异步复位、复位状态为B)。
在这里插入图片描述
提示
状态机的实现首推三段式状态机,可能一开始觉得三段式状态机写起来太麻烦,但是相信我当你的状态机越来越复杂的时候,三段式状态机一定是写起来最简单的那种。
Solution(不唯一,仅供参考):

module top_module(
    input clk,
    input areset,    // Asynchronous reset to state B
    input in,
    output out);//  

    parameter A=0, B=1; 
    reg state;			//定义现抬寄存器
    reg next_state;		 //定义次态寄存器
	//三段式状态机第一段:同步时序描述状态转移
    always @(posedge clk, posedge areset) begin    // This is a sequential always block
        if(areset)begin
            state<=B;
        end
        else begin
            state<=next_state;
        end
    end
    //三段式状态机第二段:组合逻辑判断状态转移条件,描述转移规律以及输出
    always @(*) begin    // This is a combinational always block
        if(areset)begin
            next_state=B;
        end
        else begin
            case(state)
                A:begin
                    if(!in) next_state=B;
                    else    next_state=A;
                end
                B:begin
                    if(!in) next_state=A;
                    else 	next_state=B;
                end
                default:;
            endcase
        end
    end

	//三段式状态机第三段:时序逻辑描述输出
	always @(posedge clk or posedge areset) begin
        if(areset)begin
           out<=1'b1; 
        end
        else begin
            case(next_state)
                A: out<=0;
                B: out<=1;
                default: out<=1;
            endcase
        end
    end
endmodule

Timing Diagram
在这里插入图片描述

2.Simple FSM 1(synchronous reset)

Practice:This is a Moore state machine with two states, one input, and one output. Implement this state machine. Notice that the reset state is B.
This exercise is the same as fsm1, but using synchronous reset.
翻译: 实现下面这个2状态、1输入、1输出的摩尔型状态机(同步复位、复位状态为B)。
在这里插入图片描述

Solution(不唯一,仅供参考):

module top_module(clk, reset, in, out);
    input clk;
    input reset;    // Synchronous reset to state B
    input in;
    output out;//  
    reg out;
	
	parameter A=2'b01;
    parameter B=2'b00;
    reg [1:0] cur_state, next_state;
	//第一段
    always @(posedge clk) begin
        if (reset) begin  
            cur_state<=B;
        end
		else begin
           cur_state<=next_state; 
        end
    end
    //第二段
    always @(*)begin
        if(reset)begin
            next_state=B;
        end
        else begin
            case(cur_state)
                A:begin
                    if(!in) next_state=B;
                    else  	next_state=A;
                end
                B:begin
                    if(!in) next_state=A;
                    else   	next_state=B;
                end
                default:;
            endcase
        end     
    end
    //第三段
    always @(posedge clk)begin
        if(reset)begin
            out<=1;
        end
        else begin
            case(next_state)
                A: out<=0;
                B: out<=1;
                default: out<=1;
            endcase
        end
    end

endmodule

Timing Diagram
在这里插入图片描述

3.Simple FSM 2(asynchronous reset)

Practice:Build a 64-bit arithmetic shift register, with synchronous load. The shifter can shift both left and right, and by 1 or 8 bit positions, selected by amount.
翻译
实现下面这个2状态、2输入、1输出的摩尔型状态机(异步复位、复位状态为B)。
在这里插入图片描述

Solution(不唯一,仅供参考):

module top_module(
    input clk,
    input areset,    // Asynchronous reset to OFF
    input j,
    input k,
    output out); //  

    parameter OFF=0, ON=1; 
    reg [1:0] cur_state, next_state;
	
    always @(posedge clk or posedge areset)begin
        if(areset)begin
           cur_state<=OFF; 
        end
        else begin
           cur_state<=next_state;
        end
    end
    always @(*) begin
        if(areset)begin
           next_state=OFF;
        end
        else begin
            case(cur_state)
               OFF:begin
                   if(j) next_state=ON;
                   else  next_state=OFF;
               end
                ON:begin
                    if(k) next_state=OFF;
                    else  next_state=ON;
                end
                default:;
            endcase
        end
    end

    always @(posedge clk or posedge areset) begin
        if(areset)begin
           out<=0; 
        end
        else begin
            case(next_state)
                OFF: out<=0;
                ON:  out<=1;
                default: out<=0;
            endcase
        end
    end

endmodule

Timing Diagram
在这里插入图片描述

4.Simple FSM 2(synchronous reset)

Practice:Build a 64-bit arithmetic shift register, with synchronous load. The shifter can shift both left and right, and by 1 or 8 bit positions, selected by amount.
翻译
实现下面这个2状态、2输入、1输出的摩尔型状态机(同步复位、复位状态为B)。
在这里插入图片描述

Solution(不唯一,仅供参考):

module top_module(
    input clk,
    input reset,    // Synchronous reset to OFF
    input j,
    input k,
    output out); //  

    parameter OFF=0, ON=1; 
    reg cur_state, next_state;
	//第一段
    always @(posedge clk) begin
        if(reset)begin
           cur_state<=OFF; 
        end
        else begin
           cur_state<=next_state;
        end
    end
    //第二段
    always @(*) begin
        if(reset)begin
           next_state=OFF; 
        end
        else begin
            case(cur_state)
                OFF:begin
                    if(j) next_state=ON;
                    else  next_state=OFF;
                end
                ON:begin
                    if(k) next_state=OFF;
                    else  next_state=ON;
                end
                default:;
            endcase
        end
    end
	//第三段
    always @(posedge clk) begin
        if(reset)begin
           out<=0; 
        end
        else begin
            case(next_state)
                OFF: out<=0;
                ON:  out<=1;
                default:;
            endcase
        end
    end


endmodule

Timing Diagram
在这里插入图片描述

5.Simple state transition 3

Practice:Implement only the state transition logic and output logic (the combinational logic portion) for this state machine. Given the current state (state), compute the next_state and output (out) based on the state transition table.
翻译: 下面是具有一个输入、一个输出和四个状态的摩尔状态机的状态转移表。使用以下状态编码:A=2’b00, B=2’b01, C=2’b10, D=2’b11。

仅实现此状态机的状态转换逻辑和输出逻辑(组合逻辑部分)。给定当前状态(state),根据状态转换表计算next_state和输出(out)。
在这里插入图片描述
提示
这里使用2段式的状态机就行(题目要求),一段实现状态转移;另一端实现输出。
Solution(不唯一,仅供参考):

module top_module(
    input in,
    input [1:0] state,
    output [1:0] next_state,
    output out); //
	//状态机第一段:描述状态转移
    parameter A=2'b00, B=2'b01, C=2'b10, D=2'b11;
    always @(*)begin
        case(state)
            A:begin
                if(in) next_state=B;
                else   next_state=A;
            end
            B:begin
                if(in) next_state=B;
                else   next_state=C;
            end
            C:begin
                if(in) next_state=D;
                else   next_state=A;
            end
            D:begin
                if(in) next_state=B;
                else   next_state=C;
            end
            default:;
        endcase
    end
    //状态机第二段:组合逻辑实现输出  
    always @(*)begin
        case(state)
            A: out=0;
            B: out=0;
            C: out=0;
            D: out=1;
            default:;
        endcase
    end
endmodule

6.Simple one-hot state transition 3

Practice:The following is the state transition table for a Moore state machine with one input, one output, and four states. Use the following one-hot state encoding: A=4’b0001, B=4’b0010, C=4’b0100, D=4’b1000.

Derive state transition and output logic equations by inspection assuming a one-hot encoding. Implement only the state transition logic and output logic (the combinational logic portion) for this state machine. (The testbench will test with non-one hot inputs to make sure you’re not trying to do something more complicated).
翻译: 实现下面的摩尔状态机,下表是状态转移图,1输入1输出4状态。使用如下的独热码编码方式:A=4’b0001, B=4’b0010, C=4’b0100, D=4’b1000。
这个状态机只实现状态跳转逻辑和输出逻辑。已经给出了现态state,根据状态转移图计算出次态和输出。
在这里插入图片描述
提示
基本和上题一致,只是编码方式要求改成独热码方式。独热码是使用一位有效的编码方式,这意味着使用独热码编码,有几个状态,那么编码寄存器的位宽就有几位。这无疑多消耗了寄存器资源。
独热码:和格雷码相比,虽然独热码多用了触发器,但所用组合电路可以省一些(相当于进行了一次译码操作),因而使电路的速度和可靠性有显著提高,而总的单元数并无显著增加。因为独热码只有一位的变化,所以更适用于高速系统。

Solution(不唯一,仅供参考):

module top_module(
    input in,
    input [3:0] state,
    output [3:0] next_state,
    output out); //

    parameter A=0, B=1, C=2, D=3;

    // State transition logic: Derive an equation for each state flip-flop.
    assign next_state[A] = (state[A]&~in)|(state[C]&~in);
    assign next_state[B] = (state[A]&in)|(state[B]&in)|(state[D]&in);
    assign next_state[C] = (state[B]&~in)|(state[D]&~in);
    assign next_state[D] = state[C]&in;

    // Output logic: 
    assign out = state[D];

endmodule

7.Simple FSM 3(asynchronous reset)

Practice:The following is the state transition table for a Moore state machine with one input, one output, and four states. Implement this state machine. Include an asynchronous reset that resets the FSM to state A.
翻译:下面是具有一个输入、一个输出和四个状态的摩尔状态机的状态转移表。实现这个状态机。包括一个异步复位,将FSM复位到状态A。
在这里插入图片描述

Solution(不唯一,仅供参考):

module top_module(
    input clk,
    input in,
    input areset,
    output reg out); //
	
    parameter   A=4'b0001,
    		    B=4'b0010,
    			C=4'b0100,
    			D=4'b1000;
    reg [3:0]   cur_state,next_state;
    // 三段式状态机第一段:同步时序描述状态转移
    always @(posedge clk or posedge areset)begin
        if(areset)begin
            cur_state<=A;
        end
        else begin
            cur_state<=next_state;
        end
    end
    //三段式状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律以及输出
    always @(*)begin
        if(areset)begin 
        	next_state=A;
        end
        else begin
            case(cur_state)
                A:begin
                    if(in) next_state=B;
                    else   next_state=A;
                end
                B:begin
                    if(in) next_state=B;
                    else   next_state=C;
                end
                C:begin
                    if(in) next_state=D;
                    else   next_state=A;
                end
                D:begin
                    if(in) next_state=B;
                    else   next_state=C;
                end
                default:next_state=A;
            endcase
        end
    end
    // 三段式状态机第三段:时序逻辑描述输出
    always @(posedge clk or posedge areset)begin
        if(areset)begin
        	out<=0;
        end
        else begin
            case(next_state)
                A: out<=0;
                B: out<=0;
                C: out<=0;
                D: out<=1;
                default: out<=0;
            endcase
        end
    end
endmodule

Timing Diagram
在这里插入图片描述

8.Simple FSM 3(synchronous reset)

Practice
The following is the state transition table for a Moore state machine with one input, one output, and four states. Implement this state machine. Include a synchronous reset that resets the FSM to state A. (This is the same problem as Fsm3 but with a synchronous reset.)

翻译:与上题一样,把异步改为同步。
在这里插入图片描述
Solution(不唯一,仅供参考):

module top_module(
    input clk,
    input in,
    input reset,
    output reg out); //
	
    parameter   A=4'b0001,
    		    B=4'b0010,
    			C=4'b0100,
    			D=4'b1000;
    reg [3:0]   cur_state,next_state;
    // 三段式状态机第一段:同步时序描述状态转移
    always @(posedge clk)begin
        if(reset)begin
            cur_state<=A;
        end
        else begin
            cur_state<=next_state;
        end
    end
    //三段式状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律以及输出
    always @(*)begin
        if(reset)begin 
        	next_state=A;
        end
        else begin
            case(cur_state)
                A:begin
                    if(in) next_state=B;
                    else   next_state=A;
                end
                B:begin
                    if(in) next_state=B;
                    else   next_state=C;
                end
                C:begin
                    if(in) next_state=D;
                    else   next_state=A;
                end
                D:begin
                    if(in) next_state=B;
                    else   next_state=C;
                end
                default:next_state=A;
            endcase
        end
    end
    // 三段式状态机第三段:时序逻辑描述输出
    always @(posedge clk )begin
        if(reset)begin
        	out<=0;
        end
        else begin
            case(next_state)
                A: out<=0;
                B: out<=0;
                C: out<=0;
                D: out<=1;
                default: out<=0;
            endcase
        end
    end
endmodule

Timing Diagram
在这里插入图片描述

9.Desgin a Moore FSM

Practice
在这里插入图片描述

翻译
根据水位变化情况输出不同状态,有三个传感器S1,S2,S3,可以将水库分成四部分,低于S1时,输出FR1,FR2,FR3;水位介于S1S2时,输出输出FR1,FR2;水位介于S2S3时,输出输出FR1;水位高于S3时,可以认为FR1,FR2,FR3全为零;同时还会将上一刻水位状态和现在的水位状态进行比较,如果高于现在水位,需要打开(三角)FR,否则不需要打开。
提示
题目首先建立在所有传感器能正常工作的基础上,所以请别关注诸如S1传感器无效但S2传感器有效这种情况(别杠)。

首先应该设计4个状态,状态的变化应该都发生在临近状态之间:

  • S0:水位低于S1。当检测到S1传感器有效时,说明水位超过了S1,状态跳转到S1;其他情况则保持水位不变。
  • *S1:水位在S1~S2。当检测到S2传感器有效时,说明水位超过了S2,状态跳转到S2;当检测到S1传感器无效时,说明水位在S1之下,状态跳转到S0;其他情况则保持水位不变。
  • S2:水位在S2~S3。当检测到S3传感器有效时,说明水位超过了S3,状态跳转到S3;当检测到S2传感器无效时,说明水位在S2之下,状态跳转到S1;其他情况则保持水位不变。
  • S3:水位超过S3。当检测到S3传感器无效时,说明水位在S3之下,状态跳转到S2;其他情况则保持水位不变。*

输出FR1、FR2、FR3根据所在状态对照上图进行输出即可。

dfr的输出原则是水位发生了下降则dfr输出1,所以需要比较次态和现态的关系。举例,若现态为S1,次态为S0,则说明水位下降,dfr输出1;若现态为S1,次态为S2,则说明水位上升,dfr输出0;若现态为S1,次态为S1,则说明水位不变,dfr输出不变(dfr <= dfr)。

Solution(不唯一,仅供参考):

module top_module (
    input clk,
    input reset,
    input [3:1] s,
    output fr3,
    output fr2,
    output fr1,
    output dfr
); 
	parameter	S0=4'b0001,
    			S1=4'b0010,
    			S2=4'b0100,
    			S3=4'b1000;
    reg [3:0] cur_state,next_state;
    
    //第一段
    always @(posedge clk)begin
        if(reset)begin
           cur_state<=S0;
        end
        else begin
           cur_state<=next_state;
        end
    end
    //第二段
    always @(*)begin
        if(reset)begin
           next_state=S0; 
        end
        else begin
            case(cur_state)
                S0:begin
                    if(s==3'b001) 	   next_state=S1;
                    else 			   next_state=S0;
                end
                S1:begin
                    if(s==3'b011)      next_state=S2;
                    else if(s==3'b000) next_state=S0;
                    else 		       next_state=S1;
                end
                S2:begin
                    if(s==3'b111) 	   next_state=S3;
                    else if(s==3'b001) next_state=S1;
                    else 		       next_state=S2;
                end
                S3:begin
                    if(s==3'b011)      next_state=S2;
                    else 		       next_state=S3;
                end
                default: next_state=S0;
            endcase
        end
    end
    //第三段
    always @(posedge clk)begin
        if(reset)begin 
        	fr1<=1;
            fr2<=1;
            fr3<=1;
            dfr<=1;
        end
        else begin
            case(next_state)
                S0:begin
                    fr1<=1;
                    fr2<=1;
                    fr3<=1;
                    dfr<=1;
                end
                S1:begin
                   	fr1<=1;
                    fr2<=1;
                    fr3<=0;
                    if(cur_state==S0)begin
                        dfr<=0;             
                    end
                    else if(cur_state==S1)begin
                        dfr<=dfr;
                    end
                    else begin
                        dfr<=1;
                    end
                end
                S2:begin
                   	fr1<=1; 
                    fr2<=0;
                    fr3<=0;
                    if(cur_state==S1)begin
                        dfr<=0;              
                    end
                    else if(cur_state==S2)begin
                        dfr<=dfr;
                    end
                    else begin
                        dfr<=1;
                    end
                end
                S3:begin
                    fr1<=0;
                    fr2<=0;
                    fr3<=0;
                    if(cur_state==S2)begin
                        dfr<=0;              
                    end
                    else if(cur_state==S3)begin
                        dfr<=dfr;
                    end
                    else begin
                        dfr<=1;
                    end
                end
                default:begin
                    fr1<=1;
                    fr2<=1;
                    fr3<=1;
                    dfr<=1;
                end
            endcase
        end
        
    end
endmodule

Timing Diagram
在这里插入图片描述

10.Lemmings 1

Practice
The game Lemmings involves critters with fairly simple brains. So simple that we are going to model it using a finite state machine.

In the Lemmings’ 2D world, Lemmings can be in one of two states: walking left or walking right. It will switch directions if it hits an obstacle. In particular, if a Lemming is bumped on the left, it will walk right. If it’s bumped on the right, it will walk left. If it’s bumped on both sides at the same time, it will still switch directions.

Implement a Moore state machine with two states, two inputs, and one output that models this behaviour.
翻译
旅鼠有以下两个状态:向左走向右走。遇到障碍物它就会调转方向。如果旅鼠向左遇到障碍物就会向右走;旅鼠向右遇到障碍物就会向左走;如果两边都有障碍物,就会调转方向。
实现一个具有两个状态、两个输入和一个输出的摩尔状态机来模拟这种行为。
在这里插入图片描述

提示
2个状态(复位到向左状态):

  • 向左LEFT:向左遇到障碍物则跳转到状态RIGHT;不然没有遇到障碍物则保持状态。
  • 向右RIGHT:向右遇到障碍物则跳转到状态LEFT;不然没有遇到障碍物则保持状态。

Solution(不唯一,仅供参考):

module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    output reg walk_left,
    output reg walk_right); //  
	
    //利用独热码进行定义
    parameter	LEFT=2'b01,		//向左移动
    			RIGHT=2'b10;	//向右移动
   
    reg [1:0] cur_state, next_state;
    //第一段
    always @(posedge clk, posedge areset) begin
        if(areset)begin
           cur_state<=LEFT; 
        end
        else begin
           cur_state<=next_state;
        end
    end
    //第二段
    always @(*) begin
        if(areset)begin
           next_state=LEFT; 
        end
        else begin
            case(cur_state)
                LEFT:begin
                    if(bump_left) next_state=RIGHT;
                    else 		  next_state=LEFT;
                end
                RIGHT:begin
                    if(bump_right) next_state=LEFT;
                    else 		   next_state=RIGHT;
                end
                default: next_state=LEFT;
            endcase
        end
    end
	//第三段
    always @(posedge clk, posedge areset) begin
        if(areset)begin
           walk_left<=1; 
           walk_right<=0; 
        end
        else begin
            case(next_state)
               LEFT:begin
                   walk_left<=1;
                   walk_right<=0;
               end
               RIGHT:begin
                   walk_left<=0;
                   walk_right<=1;
               end
               default:begin
                   walk_left<=1; 
           		   walk_right<=0; 
               end
            endcase
        end
    end

endmodule

Timing Diagram
在这里插入图片描述

11.Lemmings 2

Practice
In addition to walking left and right, Lemmings will fall (and presumably go “aaah!”) if the ground disappears underneath them.

In addition to walking left and right and changing direction when bumped, when ground=0, the Lemming will fall and say “aaah!”. When the ground reappears (ground=1), the Lemming will resume walking in the same direction as before the fall. Being bumped while falling does not affect the walking direction, and being bumped in the same cycle as ground disappears (but not yet falling), or when the ground reappears while still falling, also does not affect the walking direction.

Build a finite state machine that models this behaviour.
翻译
除了左右行走,旅鼠还会在地面消失时摔倒(大概会发出“啊!”的声音)。

在上题的基础上增加了输入ground和输出ahhh,当ground为1,旅鼠的行动和上题一致,当ground为0,代表旅鼠处于掉落状态,此时不再移动,同时ahhh为1。

ground的优先级最高。
在这里插入图片描述
提示
4个状态(复位到向左状态):

  • 向左LEFT:ground为0则跳转到状态FALL_L;不然向左遇到障碍物则跳转到状态RIGHT;不然没有遇到障碍物则保持状态。
  • 向右RIGHT:ground为0则跳转到状态FALL_R;不然向右遇到障碍物则跳转到状态LEFT;不然没有遇到障碍物则保持状态。
  • 向左走的时候掉落FALL_L:ground为1则跳转到状态LEFT;ground为0则保持状态。
  • 向右走的时候掉落FALL_R:ground为1则跳转到状态RIGHT;ground为0则保持状态。

Solution(不唯一,仅供参考):

module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    input ground,
    output reg walk_left,
    output reg walk_right,
    output reg aaah ); 
	//利用独热码进行定义
    parameter	LEFT=4'b0001,		//向左移动
    			RIGHT=4'b0010,		//向右移动
    			FALL_L=4'b0100,		//向左移动时掉落
    			FALL_R=4'b1000;		//向右移动时掉落
    
    reg [3:0] cur_state,next_state;
    //第一段
    always @(posedge clk or posedge areset)begin
        if(areset)begin
           cur_state<=LEFT; 
        end
        else begin
           cur_state<=next_state;
        end
    end
    //第二段
    always @(*)begin
        if(areset)begin 
           next_state=LEFT;
        end
        else begin
            case(cur_state)
                LEFT:begin
                    if(!ground) 		next_state=FALL_L;
                    else if(bump_left)  next_state=RIGHT;
                    else 				next_state=LEFT;
                end
                RIGHT:begin
                    if(!ground) 		next_state=FALL_R;
                    else if(bump_right) next_state=LEFT;
                    else 				next_state=RIGHT;
                end
                FALL_L:begin
                    if(ground)			next_state=LEFT;
                    else				next_state=FALL_L;
                end
                FALL_R:begin
                    if(ground)			next_state=RIGHT;
                    else				next_state=FALL_R;
                end
                default: 				next_state=LEFT;
            endcase
        end
    end
    //第三段
                always @(posedge clk or posedge areset)begin
                    if(areset)begin
                        walk_left<=1;
                        walk_right<=0;
                        aaah<=0;
                    end
                    else begin
                        case(next_state)
                            LEFT:begin
                                walk_left<=1;
                                walk_right<=0;
                                aaah<=0;
                            end
                            RIGHT:begin
                                walk_left<=0;
                                walk_right<=1;
                                aaah<=0;
                            end
                            FALL_L:begin
                                walk_left<=0;
                                walk_right<=0;
                                aaah<=1; 
                            end
                            FALL_R:begin
                                walk_left<=0;
                                walk_right<=0;
                                aaah<=1;  
                            end
                            default:begin
                                walk_left<=1;
                                walk_right<=0;
                                aaah<=0;
                            end
                        endcase
                    end
                end               
endmodule

Timing Diagram
在这里插入图片描述

12.Lemmings3

Practice
In addition to walking and falling, Lemmings can sometimes be told to do useful things, like dig (it starts digging when dig=1). A Lemming can dig if it is currently walking on ground (ground=1 and not falling), and will continue digging until it reaches the other side (ground=0). At that point, since there is no ground, it will fall (aaah!), then continue walking in its original direction once it hits ground again. As with falling, being bumped while digging has no effect, and being told to dig when falling or when there is no ground is ignored.

(In other words, a walking Lemming can fall, dig, or switch directions. If more than one of these conditions are satisfied, fall has higher precedence than dig, which has higher precedence than switching directions.)

Extend your finite state machine to model this behaviour.

翻译
除了走路和摔倒,旅鼠有时还会被告知做一些有用的事情,比如挖(当挖=1时它就开始挖)。旅鼠在地面上行走(地面=1且没有掉落)时可以挖掘,并且会继续挖掘直到到达另一边(地面=0)。在那个点,因为没有地面,它会下落(啊啊!),然后继续沿着原来的方向走,一旦它再次撞上地面。和摔倒一样,在挖掘时被撞到也不会有任何影响,而在摔倒或没有地面时被告知挖掘也不会受到影响。ground的优先级最高。
在上题的基础上增加了输入dig以及输出digging。当旅鼠处于地面(ground为1)走动时,一旦dig为1则旅鼠处于挖掘状态,digging输出1;直到ground为0则旅鼠处于掉落状态(aaah为1).
在这里插入图片描述
提示
6个状态(复位到向左状态):

  • 向左LEFT:ground为0则跳转到状态FALL_L;不然挖掘就跳转到DIG_L状态;不然向左遇到障碍物则跳转到状态RIGHT;不然没有遇到障碍物则保持状态。
  • 向右RIGHT:ground为0则跳转到状态FALL_R;不然挖掘就跳转到DIG_R状态;不然向右遇到障碍物则跳转到状态LEFT;不然没有遇到障碍物则保持状态。
  • 向左走的时候掉落挖掘DIG_L:ground为0(挖空了)则跳转到FALL_L状态;不然则保持状态。
  • 向右走的时候掉落挖掘DIG_R:ground为0(挖空了)则跳转到FALL_R状态;不然则保持状态。
  • 向左走的时候掉落FALL_L:ground为1则跳转到状态LEFT;ground为0则保持状态。
  • 向右走的时候掉落FALL_R:ground为1则跳转到状态RIGHT;ground为0则保持状态。

Solution(不唯一,仅供参考):

module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    input ground,
    input dig,
    output reg walk_left,
    output reg walk_right,
    output reg aaah,
    output reg digging ); 
	
    //利用独热码定义
    parameter		LEFT=6'b000001,
    				RIGHT=6'b000010,
    				FALL_L=6'b000100,
    				FALL_R=6'b001000,
    				DIG_L=6'b010000,
    				DIG_R=6'b100000;
    
    reg[5:0] cur_state,next_state;
    //第一段
    always @(posedge clk or posedge areset)begin
        if(areset)begin
           cur_state<=LEFT; 
        end
        else begin
            cur_state<=next_state;
        end
    end
    //第二段
    always @(*)begin
        if(areset)begin
            next_state=LEFT;
        end
        else begin
            case(cur_state)
                LEFT:begin
                    if(!ground) 			next_state=FALL_L;
                    else if(dig&&ground)	next_state=DIG_L;
                    else if(bump_left)		next_state=RIGHT;
                    else					next_state=LEFT;
                end
                RIGHT:begin
                    if(!ground) 			next_state=FALL_R;
                    else if(dig&&ground)	next_state=DIG_R;
                    else if(bump_right)		next_state=LEFT;
                    else					next_state=RIGHT;
                end
                FALL_L:begin
                    if(ground)				next_state=LEFT;
                    else 					next_state=FALL_L;
                end
                FALL_R:begin
                    if(ground)				next_state=RIGHT;
                    else 					next_state=FALL_R;
                end
                DIG_L:begin
                    if(!ground)				next_state=FALL_L;
                    else 					next_state=DIG_L;
                end
                DIG_R:begin
                    if(!ground)				next_state=FALL_R;
                    else					next_state=DIG_R;
                end
                default: 					next_state=LEFT;
            endcase
        end
    end
    //第三段
                    always @(posedge clk or posedge areset)begin
                        if(areset)begin
                           	walk_left<=1;
                            walk_right<=0;
                            aaah<=0;
                            digging<=0;
                        end
                        else begin
                            case(next_state)
                                LEFT:begin
                                    walk_left<=1;
                                    walk_right<=0;
                                    aaah<=0;
                                    digging<=0;
                                end
                                RIGHT:begin
                                    walk_left<=0;
                                    walk_right<=1;
                                    aaah<=0;
                                    digging<=0;
                                end
                                FALL_L:begin
                                    walk_left<=0;
                                    walk_right<=0;
                                    aaah<=1;
                                    digging<=0;
                                end
                                FALL_R:begin
                                    walk_left<=0;
                                    walk_right<=0;
                                    aaah<=1;
                                    digging<=0;
                                end
                                DIG_L:begin
                                	walk_left<=0;
                                    walk_right<=0;
                                    aaah<=0;
                                    digging<=1;   
                                end
                                DIG_R:begin
                                	walk_left<=0;
                                    walk_right<=0;
                                    aaah<=0;
                                    digging<=1;   
                                end
                                default:begin
                                    walk_left<=1;
                                    walk_right<=0;
                                    aaah<=0;
                                    digging<=0;
                                end
                            endcase
                        end
                    end
endmodule

Timing Diagram
在这里插入图片描述

13.Lemmings 4

Practice
Although Lemmings can walk, fall, and dig, Lemmings aren’t invulnerable. If a Lemming falls for too long then hits the ground, it can splatter. In particular, if a Lemming falls for more than 20 clock cycles then hits the ground, it will splatter and cease walking, falling, or digging (all 4 outputs become 0), forever (Or until the FSM gets reset). There is no upper limit on how far a Lemming can fall before hitting the ground. Lemmings only splatter when hitting the ground; they do not splatter in mid-air.

Extend your finite state machine to model this behaviour.
翻译
虽然旅鼠会走路、摔倒、挖洞,但它们并非无懈可击。如果旅鼠摔倒太久,然后撞到地面,它会飞溅。特别是,如果旅鼠掉落超过20个时钟周期,然后落到地面,它就会飞溅并停止行走、掉落或挖掘(所有4个输出都变成0),直到永远(或直到FSM重置)。旅鼠落地前的落差没有上限。旅鼠只有在着地时才会飞溅;它们不会在半空中溅落。
在上题的基础上增加了一个掉落时间的判断,当旅鼠处于ground==0的状态超过20个时钟周期则判定为”死亡“(splatter),此时所有输出都为0.
下降20次可以存活:
在这里插入图片描述
下降21次发生飞溅:
在这里插入图片描述
提示

7个状态(复位到向左状态):

  • 向左LEFT:ground为0则跳转到状态FALL_L;不然挖掘就跳转到DIG_L状态;不然向左遇到障碍物则跳转到状态RIGHT;不然没有遇到障碍物则保持状态。

  • 向右RIGHT:ground为0则跳转到状态FALL_R;不然挖掘就跳转到DIG_R状态;不然向右遇到障碍物则跳转到状态LEFT;不然没有遇到障碍物则保持状态。

  • 向左走的时候掉落挖掘DIG_L:ground为0(挖空了)则跳转到FALL_L状态;不然则保持状态。

  • 向右走的时候掉落挖掘DIG_R:ground为0(挖空了)则跳转到FALL_R状态;不然则保持状态。

  • 向左走的时候掉落FALL_L:ground为1且计数器小于等于20则跳转到状态LEFT;ground为1且计数器大于20则跳转到状态SPLAT;不然ground为0则保持状态。

  • 向右走的时候掉落FALL_R:ground为1且计数器小于等于20则跳转到状态RIGHT;ground为1且计数器大于20则跳转到状态SPLAT;不然ground为0则保持状态。

  • SPLAT:一直保持这个状态(直到复位)。

Solution(不唯一,仅供参考):

module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    input ground,
    input dig,
    output walk_left,
    output walk_right,
    output aaah,
    output digging ); 

        //利用独热码定义
    parameter		LEFT=7'b0000001,
    				RIGHT=7'b0000010,
    				FALL_L=7'b0000100,
    				FALL_R=7'b0001000,
    				DIG_L=7'b0010000,
    				DIG_R=7'b0100000,
    				SPLAT=7'b1000000;				
    
    reg[6:0] cur_state,next_state;
    reg[9:0] cnt;
    //第一段
    always @(posedge clk or posedge areset)begin
        if(areset)begin
           cur_state<=LEFT; 
        end
        else begin
            cur_state<=next_state;
        end
    end
    //第二段
    always @(*)begin
        if(areset)begin
            next_state=LEFT;
        end
        else begin
            case(cur_state)
                LEFT:begin
                    if(!ground) 			next_state=FALL_L;
                    else if(dig&&ground)	next_state=DIG_L;
                    else if(bump_left)		next_state=RIGHT;
                    else					next_state=LEFT;
                end
                RIGHT:begin
                    if(!ground) 			next_state=FALL_R;
                    else if(dig&&ground)	next_state=DIG_R;
                    else if(bump_right)		next_state=LEFT;
                    else					next_state=RIGHT;
                end
                FALL_L:begin
                    if(ground)begin
                        if(cnt<=10'd20)
                        					next_state=LEFT;
                        else 
                           					next_state=SPLAT;
                    end
                    else 					next_state=FALL_L;
                end
                FALL_R:begin
                    if(ground)begin
                        if(cnt<=20)
                        					next_state=RIGHT;
                        else
                            				next_state=SPLAT;
                    end
                    else 					next_state=FALL_R;
                end
                DIG_L:begin
                    if(!ground)				next_state=FALL_L;
                    else 					next_state=DIG_L;
                end
                DIG_R:begin
                    if(!ground)				next_state=FALL_R;
                    else					next_state=DIG_R;
                end
                SPLAT:begin
                    						next_state=SPLAT;
                end
                default: 					next_state=LEFT;
            endcase
        end
    end
    //第三段
                    always @(posedge clk or posedge areset)begin
                        if(areset)begin
                           	walk_left<=1;
                            walk_right<=0;
                            aaah<=0;
                            digging<=0;
                            cnt<=0;
                        end
                        else begin
                            case(next_state)
                                LEFT:begin
                                    walk_left<=1;
                                    walk_right<=0;
                                    aaah<=0;
                                    digging<=0;
                                    cnt<=0;
                                end
                                RIGHT:begin
                                    walk_left<=0;
                                    walk_right<=1;
                                    aaah<=0;
                                    digging<=0;
                                    cnt<=0;
                                end
                                FALL_L:begin
                                    walk_left<=0;
                                    walk_right<=0;
                                    aaah<=1;
                                    digging<=0;
                                    cnt<=cnt+1;
                                end
                                FALL_R:begin
                                    walk_left<=0;
                                    walk_right<=0;
                                    aaah<=1;
                                    digging<=0;
                                    cnt<=cnt+1;
                                end
                                DIG_L:begin
                                	walk_left<=0;
                                    walk_right<=0;
                                    aaah<=0;
                                    digging<=1; 
                                    cnt<=0;
                                end
                                DIG_R:begin
                                	walk_left<=0;
                                    walk_right<=0;
                                    aaah<=0;
                                    digging<=1; 
                                    cnt<=0;
                                end
                                SPLAT:begin
                                    walk_left<=0;
                                    walk_right<=0;
                                    aaah<=0;
                                    digging<=0; 
                                    cnt<=0;
                                end
                                default:begin
                                    walk_left<=1;
                                    walk_right<=0;
                                    aaah<=0;
                                    digging<=0;
                                    cnt<=0;
                                end
                            endcase
                        end
                    end
endmodule

Timing Diagram
在这里插入图片描述

14.One-hot FSM

Practice
Given the following state machine with 1 input and 2 outputs:
翻译
用独热码实现下图中一输入两输出的状态机,实现状态机的状态转换逻辑和输出逻辑部分(但不包括状态触发器)。在state[9:0]中给定当前状态,并且必须生成next_state[9:0]和两个输出。假设一热编码,通过检验推导出逻辑方程。(测试平台将使用非一个热输入进行测试,以确保您不会尝试执行更复杂的操作)。
在这里插入图片描述

Solution(不唯一,仅供参考):

module top_module(
    input in,
    input [9:0] state,
    output [9:0] next_state,
    output out1,
    output out2);
	
    parameter		S0 = 4'd0,
                    S1 = 4'd1,
                    S2 = 4'd2,
                    S3 = 4'd3,
                    S4 = 4'd4,
                    S5 = 4'd5,
                    S6 = 4'd6,
                    S7 = 4'd7,
                    S8 = 4'd8,
                    S9 = 4'd9;

    
    assign next_state[S0] = ~in & (state[S0] | state[S1] | state[S2] | state[S3] | state[S4] | state[S7] | state[S8] | state[S9]);
    assign next_state[S1] = in & (state[S0] | state[S8] | state[S9]);
    assign next_state[S2] = in & state[S1];
    assign next_state[S3] = in & state[S2];
    assign next_state[S4] = in & state[S3];
    assign next_state[S5] = in & state[S4];
    assign next_state[S6] = in & state[S5];
    assign next_state[S7] = in & (state[S6] | state[S7]);
    assign next_state[S8] = ~in & state[S5];
    assign next_state[S9] = ~in & state[S6];

    assign out1 = state[S8]|state[S9];
    assign out2 = state[S9]|state[S7];
endmodule

Timing Diagram
在这里插入图片描述

15.PS/2 packet parser

Practice
We want a finite state machine that will search for message boundaries when given an input byte stream. The algorithm we’ll use is to discard bytes until we see one with bit[3]=1. We then assume that this is byte 1 of a message, and signal the receipt of a message once all 3 bytes have been received (done).
翻译
本质上是个序列检测。检测到in[3]为高电平后,认定该字节为因为接收的第一个字节,共接收三个字节后,将指示位done拉高一个周期。

提示

  • S0:初始状态,一直检测in[3]是否为高电平,若是,则代表接收了第一个字节跳转到状态S1,则不是则继续检测
  • S1:接收第一个字节,仅维持一个时钟周期后跳转到状态S2
  • S2:接收第二个字节,仅维持一个时钟周期后跳转到状态S3
  • S3:检测in[3]是否为高电平,若是则接收了第三个字节跳转到状态S1,若不是则跳转到状态S0。在这个字节输出done信号,表示3个字节接收完成

Solution(不唯一,仅供参考):

module top_module(
    input clk,
    input [7:0] in,
    input reset,    // Synchronous reset
    output reg done); //
	
    parameter		S0=4'b0001,
    				S1=4'b0010,
    				S2=4'b0100,
    				S3=4'b1000;
    
    reg [3:0] cur_state,next_state;
    // 第一段
    always @(posedge clk)begin
        if(reset)begin
           cur_state<=S0; 
        end
        else begin
            cur_state<=next_state;
        end
    end
    // 第二段
    always @(*)begin
        if(reset)begin
           next_state=S0; 
        end
        else begin
            case(cur_state)
               S0:begin
                   if(in[3])  next_state=S1;
                   else 	  next_state=S0;
               end
                S1:begin
                    next_state=S2;
                end
                S2:begin
                    next_state=S3;
                end
                S3:begin
                    if(in[3]) next_state=S1;
                    else 	  next_state=S0;
                end
                default: next_state=S0;
            endcase
        end
    end
    // 第三段
    always @(posedge clk)begin
        if(reset)begin
           done<= 0;
        end
        else begin
            case(next_state)
                S0: done<=0;
                S1: done<=0;
                S2: done<=0;
                S3: done<=1;
                default: done<=0;
            endcase
        end
    end
endmodule

16.PS/2 packet parser and datapath

Practice
Now that you have a state machine that will identify three-byte messages in a PS/2 byte stream, add a datapath that will also output the 24-bit (3 byte) message whenever a packet is received (out_bytes[23:16] is the first byte, out_bytes[15:8] is the second byte, etc.).
out_bytes needs to be valid whenever the done signal is asserted. You may output anything at other times (i.e., don’t-care).
翻译
现在您已经有了一个状态机,它将在PS/2字节流中识别三个字节的消息,添加一个数据路径,当接收到一个包时,它也将输出24位(3字节)消息(out_bytes[23:16]是第一个字节,out_bytes[15:8]是第二个字节,等等)。
和上题基本相同,增加了一个输出out_bytes,out_bytes就是接收到的三个数据,当三个数据输出完成后,与done信号同时输出,其他时候不关心。
在这里插入图片描述

提示

  • S0:初始状态,一直检测in[3]是否为高电平,若是,则代表接收了第一个字节跳转到状态S1,则不是则继续检测
  • S1:接收第一个字节,仅维持一个时钟周期后跳转到状态S2
  • S2:接收第二个字节,仅维持一个时钟周期后跳转到状态S3
  • S3:检测in[3]是否为高电平,若是则接收了第三个字节跳转到状态S1,若不是则跳转到状态S0。在这个字节输出done信号,表示3个字节接收完成

Solution(不唯一,仅供参考):

module top_module(
    input clk,
    input [7:0] in,
    input reset,    // Synchronous reset
    output 	[23:0] 	out_bytes	,   
    output reg done); //
	
    parameter		S0=4'b0001,
    				S1=4'b0010,
    				S2=4'b0100,
    				S3=4'b1000;
    
    reg [3:0] cur_state,next_state;
    // 第一段
    always @(posedge clk)begin
        if(reset)begin
           cur_state<=S0; 
        end
        else begin
            cur_state<=next_state;
        end
    end
    // 第二段
    always @(*)begin
        if(reset)begin
           next_state=S0; 
        end
        else begin
            case(cur_state)
               S0:begin
                   if(in[3])  next_state=S1;
                   else 	  next_state=S0;
               end
                S1:begin
                    next_state=S2;
                end
                S2:begin
                    next_state=S3;
                end
                S3:begin
                    if(in[3]) next_state=S1;
                    else 	  next_state=S0;
                end
                default: next_state=S0;
            endcase
        end
    end
    // 第三段
    always @(posedge clk)begin
        if(reset)begin
           done<= 0;
        end
        else begin
            case(next_state)
                S0: begin 
                    done<=0;
                    out_bytes<={out_bytes[15:0],in[7:0]};
                end
                S1: begin 
                    done<=0;
                    out_bytes<={out_bytes[15:0],in[7:0]};
                end
                S2: begin 
                    done<=0;
                    out_bytes<={out_bytes[15:0],in[7:0]};
                end
                S3: begin 
                    done<=1;
                    out_bytes<={out_bytes[15:0],in[7:0]};
                end
                default: done<=0;
            endcase
        end
    end
endmodule

总结

继续加油!!!!!

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值