HDLBits问题--Lemmings

今日份刷题

Lemmings1

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.

翻译:“旅鼠”游戏中的动物大脑相当简单。非常简单,我们将使用有限状态机对其建模。
在旅鼠的2D世界中,旅鼠可以处于两种状态之一:向左行走或向右行走。如果碰到障碍物,它会改变方向。特别是,如果旅鼠撞到左边,它就会向右走。如果它撞到右边,它就会向左走。如果它在两侧同时碰撞,它仍会切换方向。
实现一个具有两个状态、两个输入和一个输出的Moore状态机来模拟这种行为。

第一个基本上就是传统最简单的FSM,唯一的逻辑变换在于“如果旅鼠撞到左边,它就会向右走。如果它撞到右边,它就会向左走。如果它在两侧同时碰撞,它仍会切换方向”,分三种情况写就是只撞左边,只撞右边,都撞,分别对应往右走,往左走和反向。

写成代码就是:

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
        begin
            if(bump_left&&~bump_right) next_state=1;
            else if(bump_right&&~bump_left) next_state=0;
            else if(bump_right&&bump_left) next_state=~state;
            else next_state=state;
        end
    end

    always @(posedge clk, posedge areset) begin
        if(areset==1) state=0;
        else 
            begin
               state=next_state; 
            end
    end

    // Output logic
    assign walk_left = (~state)?1:0;
    assign walk_right = (state)?1:0;

endmodule

lemming2

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.

除了左右行走,旅鼠还会摔倒(大概还会“啊啊!”)如果他们下面的地面消失了。
除了左右行走和颠簸时改变方向外,当地面=0时,旅鼠还会跌倒并说“啊!”。当地面重新出现时(地面=1),旅鼠将恢复以与坠落前相同的方向行走。坠落时被碰撞并不影响行走方向,在地面消失(但尚未坠落)的同一周期内被碰撞,或者地面仍在坠落时重新出现,也不影响行走方向。
构建一个模拟这种行为的有限状态机。

这道题卡了我几个小时一直时序上快一个周期,最终能力不行没改掉这个BUG选择了重写。

定义四个状态分别是A向左B向右C向左掉下去D向右掉下去

向左走的时候遇到碰撞会转向但这时必须身处地面,不然就不会转向。同样的道理向右走也一样。

代码如下:

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 A=0,B=1,C=2,D=3;
    reg [1:0]state, next_state;
    always@(*)
        begin
            case(state)
                A:
                    if (bump_left&&ground) next_state=B;
                    else if (~ground) next_state=C;
                    else next_state=A;
                B:
                    if (bump_right&&ground) next_state=A;
                    else if (~ground) next_state=D;
                    else next_state=B;
                C:
                    if(ground) next_state=A;
                	else next_state=C;
                D:
                    if(ground) next_state=B;
                	else next_state=D;
            endcase
        end
    always@(posedge clk or posedge areset)
        begin
            if(areset==1) state=A;
            else state=next_state;
        end

    assign walk_left=(state==A);
    assign walk_right=(state==B);
    always@(posedge clk)
        aaah=(~ground);
    


endmodule

Lemmings3

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)。在那一点上,因为没有地面,它会掉下来(啊啊!),然后,当它再次触地时,继续沿着原来的方向行走。与坠落一样,挖掘时被撞击也没有影响,被告知在坠落时或没有地面时挖掘也会被忽略。
(换句话说,一只会走路的旅鼠可以坠落、挖掘或改变方向。如果满足以上条件之一,坠落的优先级高于挖掘,后者的优先级高于改变方向。)
扩展有限状态机来模拟此行为。

这个比上一个题只是加了一个旅鼠会挖掘

考虑额外的两个state E和F分别为向左走的时候开挖和向右走的时候开挖,逻辑上满足“坠落的优先级高于挖掘,后者的优先级高于改变方向”因此写case逻辑的时候优先写坠落然后写挖掘再写改变方向,不然要加入~dig和ground条件。

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 A=0,B=1,C=2,D=3,E=4,F=5;
    reg [2:0]state, next_state;
    always@(*)
        begin
            case(state)
                A:
                    if (~ground) next_state=C;
                	else if (dig) next_state=E;
                	else if (bump_left) next_state=B;
                    else next_state=A;
                B:
                    if (~ground) next_state=D;
                	else if (dig) next_state=F;
                	else if (bump_right) next_state=A;
                    else next_state=B;
                C:
                    if(ground) next_state=A;
                	else next_state=C;
                D:
                    if(ground) next_state=B;
                	else next_state=D;
                E: 
                    if(~ground) next_state=C;
                	else next_state=E;
                F: 
                    if(~ground) next_state=D;
                	else next_state=F;
            endcase
        end
    always@(posedge clk or posedge areset)
        begin
            if(areset==1) state=A;
            else state=next_state;
        end

    assign walk_left=(state==A);
    assign walk_right=(state==B);
    assign aaah = (state == C )|(state == D);
    assign digging = (state == E) | (state == F);

    

endmodule

Lemmings4

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:

虽然旅鼠可以行走、坠落和挖掘,但它们并非无懈可击。如果旅鼠摔倒的时间太长,然后撞到地面,它可能会飞溅。特别是,如果旅鼠跌落超过20个时钟周期,然后撞到地面,它将飞溅并停止行走、跌落或挖掘(所有4个输出都变为0),直到永远(或直到FSM重置)。旅鼠在落地前能掉多远没有上限。旅鼠只在落地时飞溅;它们不会在半空中飞溅。
扩展有限状态机来模拟此行为。
跌落20个周期是可以存活的:

这里就是加一个计数器每当到落下的状态C或D的时候cout++否则置零就可以统计时钟周期了。

注意定义的cout应该能存下20以内的数,因此至少要6位。

定义两个新的state是GG和Over,表示落下超过20个时间单位迟早要死 和 死了。

在下落的state中插入判断是否大于20的cout判断语句即可。

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 ); 
    wire [5:0]cout;
    initial cout=0;
    parameter A=0,B=1,C=2,D=3,E=4,F=5,GG=6,Over=7;
    reg [2:0]state, next_state;
    always@(*)
        begin
            case(state)
                A:
                    if (~ground) next_state=C;
                	else if (dig) next_state=E;
                	else if (bump_left) next_state=B;
                    else next_state=A;
                B:
                    if (~ground) next_state=D;
                	else if (dig) next_state=F;
                	else if (bump_right) next_state=A;
                    else next_state=B;
                C:
                    if(~ground && cout<20) next_state=C;
                	else if(~ground && cout>=20) next_state=GG;
                	else next_state=A;
                	
                D:
                    if(~ground && cout<20) next_state=D;
                	else if(~ground && cout>=20) next_state=GG;
                	else next_state=B;
                E: 
                    if(~ground) next_state=C;
                	else next_state=E;
                F: 
                    if(~ground) next_state=D;
                	else next_state=F;
                GG:
                    if(ground) next_state=Over;
                	else next_state=GG;
                Over: next_state=Over;
            endcase
        end
    always @(posedge clk,posedge areset)
        begin
            if(areset)
                cout = 0;
            else if((next_state == C) | (next_state == D))
               cout = cout+1;
            else
               cout = 0;
        end
    always@(posedge clk or posedge areset)
        begin
            if(areset==1) state=A;
            else state=next_state;
        end

    assign walk_left=(state==A);
    assign walk_right=(state==B);
    assign aaah = (state == C )|(state == D)|(state==GG);
    assign digging = (state == E) | (state == F);

endmodule

因为个人是软件转硬件可能一些逻辑比较奇怪,轻喷家人们

你可能感兴趣的:(fpga开发)