HDLBits学习笔记——状态机(中)

1.Lemmings 1

题目:

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,表示当前走的方向,当向左碰壁时(bump_left=1),状态变为RIGHT,当向右碰壁时,状态变为LEFT。

代码:

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

    parameter LEFT=0, RIGHT=1;
    reg state, next_state;

    always @(*) begin
        // State transition logic
        case(state)
            0: next_state = bump_left?RIGHT:LEFT;
            1: next_state = bump_right?LEFT:RIGHT;
        endcase
    end

    always @(posedge clk, posedge areset) begin
        // State flip-flops with asynchronous reset
        if(areset)
            state <= LEFT;
        else
            state <= next_state;
    end

    // Output logic
    assign walk_left = (state == LEFT);
    assign walk_right = (state == RIGHT);

endmodule

2.Lemmings 2

题目:

See also: Lemmings1.

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.

思路:

《旅鼠》游戏2.0,与1.0相比丰富了地形的玩法,新添加了变量ground,当ground=1时表示地形平坦,ground=0时表示有坑,此时旅鼠会啊啊大叫。

根据题意,此时具有4个状态,往左走LEFT0,往右走RIGHT0,往走的坑里LEFT1,往右的坑里RIGHT1,画出状态转换图可以简单的写出代码。

代码:

module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    input ground,
    output walk_left,
    output walk_right,
    output aaah ); 
	parameter LEFT0=0,RIGHT0=1,LEFT1=2,RIGHT1=3;
    reg [1:0] state,next_state;
    always@(posedge clk,posedge areset) begin
        if(areset)
            state <= LEFT0;
        else 
            state <= next_state;
    end
    always@(*) begin
        if(ground) begin
            case(state)
                LEFT0: next_state = bump_left?RIGHT0:LEFT0;
                RIGHT0:next_state = bump_right?LEFT0:RIGHT0;
                LEFT1: next_state = LEFT0;
                RIGHT1:next_state = RIGHT0;
            endcase
        end
        else begin
            case(state) 
                LEFT0: next_state = LEFT1;
                RIGHT0:next_state = RIGHT1;
                LEFT1: next_state = LEFT1;
                RIGHT1:next_state = RIGHT1;
            endcase
        end
    end
    assign walk_left=(state==LEFT0);
    assign walk_right=(state==RIGHT0);
    assign aaah = (state==LEFT1|state==RIGHT1);
endmodule

3.Lemmings 3

题目:

See also: Lemmings1 and Lemmings2.

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.

思路:

3.0公测,玩法又升级了。新增挖掘动作,当dig=1时且ground=1时旅鼠开始挖掘,持续挖掘直到ground=0。

相比2.0,状态由4个变为6个,分别时向左走,向左的坑里,向左挖,向右走,向右的坑里,向右挖。由于掉落(ground=0)的优先级高于挖掘(dig),因此if先分为两个分支,ground=0与ground=1,ground=1分支内再分为dig=0与dig=1两个分支,依次更新状态(next_state)即可。

需要注意的是,当state=LEFT1|RIGHT1时(在坑里),下一个状态不会变为digging(LEFTDIG/RIGHTDIG),即状态只可能转换为LEFT1/RIGHT1(仍在坑里)或LEFT0/RIGHT0(地面)。

代码:

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 LEFT0=0,LEFT1=1,RIGHT0=2,RIGHT1=3,LEFTDIG=4,RIGHTDIG=5;
    reg [2:0] state,next_state;
    always@(posedge clk,posedge areset) begin
        if(areset)
            state <= LEFT0;
        else 
            state <= next_state;
    end
    always@(*) begin
        if(ground) begin
            if(~dig) begin
                case(state)
                    LEFT0:next_state = bump_left?RIGHT0:LEFT0;
                    RIGHT0:next_state = bump_right?LEFT0:RIGHT0;
                    LEFT1:next_state = LEFT0;
                    RIGHT1:next_state = RIGHT0;
                    LEFTDIG:next_state = LEFTDIG;
                    RIGHTDIG:next_state = RIGHTDIG;
                endcase
            end
            else if(dig) begin
                case(state)
                    LEFT0:next_state = LEFTDIG;
                    RIGHT0:next_state = RIGHTDIG;
                    LEFT1:next_state = LEFT0;
                    RIGHT1:next_state = RIGHT0;
     				default:next_state = state;
                endcase
            end
        end
        else begin
            case(state)
            	LEFT0:next_state = LEFT1;
            	RIGHT0:next_state = RIGHT1;
            	LEFT1:next_state = LEFT1;
            	RIGHT1:next_state = RIGHT1;
            	LEFTDIG:next_state = LEFT1;
            	RIGHTDIG:next_state = RIGHT1;
            endcase
        end
    end
    assign walk_left = (state==LEFT0);
    assign walk_right = (state==RIGHT0);
    assign aaah = (state==LEFT1|state==RIGHT1);
    assign digging = (state==LEFTDIG|state==RIGHTDIG);
endmodule

4.Lemmings 4

题目:

See also: Lemmings1Lemmings2, and Lemmings3.

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.

Falling for 20 cycles is survivable:

思路:

4.0添加了惩罚条件,如果旅鼠下落超过20个时钟周期的话,在遇到地面时会飞溅,并且无法恢复(除非复位)。

这次由于if的分支太多,尝试先用case(state)根据状态进行分支,再分别用IF判断状态转换。整体思路会比先IF判断输入再用CASE判断状态更直观。

假设状态L,R,FL,FR,DL,DR,SP分别表示向左走,向右走,向左掉落,向右掉落,向左挖,向右挖,以及飞溅。

根据状态转换图,

L:可能转换到L、FL、R、DL。

R:可能转换到R、FR、L、DR。

FL:可能转换到FL、L、SP。

FR:可能转换到FR、R、SP。

DL:可能转换为DL、FL。

DR:可能转换到DR、FR。

SP:只能转换到SP,当复位时STATE—>L。

代码:

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 L=0,R=1,FL=2,FR=3,DL=4,DR=5,SP=6;
    reg [3:0] state,next_state;
    integer count;
    always@(posedge clk,posedge areset) begin
        if(areset) 
            state <= L;
        else
            state <= next_state;
    end
    always@(posedge clk,posedge areset) begin
        if(areset)
            count<=0;
        else if(state==FL||state==FR)
            count <= count+1'b1;
        else 
            count <= 0;
    end
    always@(*) begin
        case(state)
            L: begin
                if(ground) begin
                    if(dig) next_state = DL;
                    else if(bump_left) next_state = R;
                    else next_state = L;
                end
                else if(~ground) next_state = FL;
            end
            R: begin
                if(ground) begin
                    if(dig) next_state = DR;
                    else if(bump_right) next_state = L;
                    else next_state = R;
                end
                else if(~ground) next_state = FR;
            end
            FL:begin
                if(ground) begin
                    if(count>5'd19) begin
                        next_state = SP;
                    end
                    else
                        next_state = L;
                end
                else next_state = FL;
            end
            FR:begin
                if(ground) begin
                    if(count>5'd19) begin
                        next_state = SP;
                    end
                    else
                        next_state = R;
                end
                else next_state = FR;
            end
            DL:begin
                if(ground) next_state = DL;
                else next_state = FL;
            end
            DR:begin
                if(ground) next_state = DR;
                else next_state = FR;
            end
            SP: next_state = SP;
        endcase
    end
    assign walk_left = (state == L);
    assign walk_right = (state == R);
    assign aaah = (state == FL | state == FR);
    assign digging = (state == DL | state == DR);
endmodule

5.One-hot FSM

题目:

Given the following state machine with 1 input and 2 outputs:

Suppose this state machine uses one-hot encoding, where state[0] through state[9] correspond to the states S0 though S9, respectively. The outputs are zero unless otherwise specified.

Implement the state transition logic and output logic portions of the state machine (but not the state flip-flops). You are given the current state in state[9:0] and must produce next_state[9:0] and the two outputs. Derive the logic equations by inspection assuming a one-hot encoding. (The testbench will test with non-one hot inputs to make sure you're not trying to do something more complicated).

思路:

独热码FSM,跟状态机(上)的题6解法类似。

代码:

module top_module(
    input in,
    input [9:0] state,
    output [9:0] next_state,
    output out1,
    output out2);
    assign next_state[0] = (state[0]&~in)|(state[1]&~in)|(state[2]&~in)|(state[3]&~in)|(state[4]&~in)|(state[7]&~in)|(state[8]&~in)|(state[9]&~in);
    assign next_state[1] = (state[0]&in)|(state[8]&in)|(state[9]&in);
    assign next_state[2] = state[1]&in;
    assign next_state[3] = state[2]&in;
    assign next_state[4] = state[3]&in;
    assign next_state[5] = state[4]&in;
    assign next_state[6] = state[5]&in;
    assign next_state[7] = (state[6]&in)|(state[7]&in);
    assign next_state[8] = state[5]&~in;
    assign next_state[9] = state[6]&~in;
    
    assign out1 = (state[8]|state[9]);
    assign out2 = (state[9]|state[7]);
endmodule

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,关于 jQuery 的事件,我可以和你分享一些学习笔记。 1. 绑定事件 在 jQuery ,我们可以通过以下方式来绑定事件: ``` $(selector).event(function(){ // 事件处理程序 }) ``` 其,`selector` 表示要绑定事件的元素,`event` 表示要绑定的事件类型,比如 `click`、`mouseover` 等等。事件处理程序则是在事件触发时要执行的代码块。 2. 多个事件绑定 我们可以通过 `on()` 方法来同时绑定多个事件: ``` $(selector).on({ event1: function(){ // 事件处理程序1 }, event2: function(){ // 事件处理程序2 } }) ``` 这样,当 `event1` 或 `event2` 任意一个事件触发时,对应的处理程序都会被执行。 3. 解除事件 如果需要解除某个元素的事件处理程序,可以使用 `off()` 方法: ``` $(selector).off(event); ``` 其,`event` 表示要解除的事件类型。如果不指定事件类型,则会解除该元素上所有的事件处理程序。 4. 事件委托 在 jQuery ,我们可以使用事件委托来提高性能。事件委托是指将事件绑定到父元素上,而不是绑定到子元素上,然后通过事件冒泡来判断是哪个子元素触发了该事件。这样,当子元素数量较多时,只需要绑定一次事件,就可以监听到所有子元素的事件。 ``` $(selector).on(event, childSelector, function(){ // 事件处理程序 }) ``` 其,`selector` 表示父元素,`event` 表示要绑定的事件类型,`childSelector` 表示要委托的子元素的选择器,事件处理程序则是在子元素触发事件时要执行的代码块。 以上是 jQuery 事件的一些基本操作,希望对你有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值