此博客为个人博客,不涉及商业用途,仅提供学习参考,内容均来自个人原创以及互联网转载和摘录。
此博客上带有原创标识的文章、图片、文件等,未经本人允许,不得用于商业用途以及传统媒体。
本文首发于CSDN,版权所有,禁止转载。
如需转载,请在评论区留言或私信申请,经同意后可转载,否则属于侵权行为

原博客链接:https://blog.csdn.net/qq_38305370
原博主昵称:城外南风起
————————————————

目录

  • Lemmings1
  • Lemmings2
  • Lemmings3
  • Lemmings4

Lemmings1

原题目(波形demo见链接):

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运动描述。

实现思路:根据{bump_left,bump_right}确定下一状态。具体框架为常规的组合逻辑+时序逻辑
需要注意的是,题中说明If it’s bumped on both sides at the same time, it will still switch directions.
即{bump_left,bump_right} = 2’b11时,旅鼠仍需转换运动方向。

实现代码:

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 logiccase({bump_left,bump_right})2'b01: next_state = LEFT;2'b10: next_state = RIGHT; 2'b11: begincase(state)LEFT: next_state = RIGHT;RIGHT: next_state = LEFT;endcaseenddefault: next_state = state;endcaseendalways @(posedge clk, posedge areset) begin// State flip-flops with asynchronous resetif(areset)state <= LEFT;elsestate <= next_state;end// Output logicassign walk_left = (state == LEFT);assign walk_right = ~walk_left;endmodule

比较复杂的是Lemmings2。

Lemmings2

原题目(波形demo见链接):

在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.

与Lemmings1相比,增加了地面消失的情况,新的难点主要有三个:
1.坠落结束后,旅鼠延续坠落前的运动方向。
2.如果坠落时产生左右碰撞(哪怕地面恢复),旅鼠不改变运动方向;
3.如果碰撞时地面消失(哪怕还未坠落),旅鼠不改变运动方向;

这里需理清一个逻辑:地面消失后,旅鼠不会马上坠落,而是需等到clk上升沿才会坠落;地面恢复后,旅鼠也不会马上结束坠落,而是需等到clk上升沿才会结束坠落

针对难点1,引入reg变量old_state记录之前的运动方向,但需要注意的是,必须在时序逻辑里面进行记录,只有时序逻辑里面的状态更新才是必然会发生的状态。组合逻辑里面更新的next_state是不一定会发生的。如果在组合逻辑里面记录,那么记录的将是还未发生的状态,如果下一状态为FALL,那么将出现记录错误。坠落结束后延续运动方向时也会发生错误。如下图所示,Mismatch=1处发生了测试错误,该代码即是在组合逻辑里面记录旧状态。可以看到,错误处并没有成功延续之前的运动方向,而是因为t=1100时刻{bump_left,bump_right} = 2’b11 改变了之前的运动方向。但实际上,t=1100时刻正好处于坠落结束后(aaah刚好置零),所以这里应该延续walk_left。

同时,组合逻辑里只执行LEFT和RIGHT两种状态的判断,FALL状态的判断放在时序逻辑里,将两种运动状态和坠落这种特殊状态分开,便于old_state只记录运动状态。

同样,next_state = old_state这句话也只能放在组合逻辑中的状态判断块外面,因为如果放在里面,那么可能会被坠落开始前的{bump_left,bump_right}信号覆盖,就无法延续之前的状态了。例如,下图t=1080时刻的bump_left置高,会将next_state置位RIGHT,但是,这个状态还没来得及发生,就进入了FALL状态,所以FALL结束后,仍应延续LEFT而不是RIGHT。而如果放在外面,t=1080时刻next_state仍会被置为RIGHT,但是,后续在FALL的时段内,通过next_state=old_state又可以将其置为已经发生的LEFT。


针对难点2,在组合逻辑处给出了判断条件if(state != FALL)。

针对难点3,在时序逻辑里利用 if(!ground) 提高FALL的优先级。

此外,由于状态增加,方便起见,状态采用独热码进行编码。

实现代码:

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 LEFT=3'b000, RIGHT=3'b010, FALL=3'b100;reg [2:0] state, next_state, old_state;always @(*) begin// State transition logicnext_state = old_state;if(state != FALL) begin            case({bump_left,bump_right})2'b01: next_state = LEFT;2'b10: next_state = RIGHT; 2'b11: begincase(state)LEFT: next_state = RIGHT;RIGHT: next_state = LEFT;endcaseenddefault: next_state = state;endcase            end        endalways @(posedge clk, posedge areset) begin// State flip-flops with asynchronous resetif(areset) beginstate <= LEFT;endelse beginaaah <= ~ground;if(!ground)state <= FALL;else beginstate <= next_state;old_state <= next_state; //必须在时序逻辑里面进行记录endendend// Output logicassign walk_left = (state == LEFT);assign walk_right = (state == RIGHT);
endmodule

Lemmings3

原题目(波形demo见链接):

在Lemmings1和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.

与Lemmings2相比,增加了挖掘的情况,新的难点主要有两个:
1.挖掘中的碰撞无效;
2.坠落中和地面消失时挖掘信号无效。

针对难点1,在组合逻辑中的if判断中引入state != DIG。

针对难点2,在时序逻辑中引入判断if(!ground)和if(dig && state != FALL)。

最初的代码:

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=4'b0000, RIGHT=4'b0010, FALL=4'b0100, DIG=4'b1000;reg [3:0] state, next_state, old_state;always @(*) begin// State transition logicnext_state = old_state;if(state != FALL && state != DIG) begin            case({bump_left,bump_right})2'b01: next_state = LEFT;2'b10: next_state = RIGHT; 2'b11: begincase(state)LEFT: next_state = RIGHT;RIGHT: next_state = LEFT;endcaseenddefault: next_state = state;endcase            end        endalways @(posedge clk, posedge areset) begin// State flip-flops with asynchronous resetif(areset) beginstate <= LEFT;endelse beginaaah <= ~ground;            if(!ground)state <= FALL;else if(dig && state != FALL)state <= DIG;else if(state != DIG) beginstate <= next_state;old_state <= next_state; //必须在时序逻辑里面进行记录endendend// Output logicassign walk_left = (state == LEFT);assign walk_right = (state == RIGHT);assign digging = (state == DIG);endmodule

但上述代码在测试向量中仍有12个mismatch。


由于HDLBits没有提供t=860时刻前的波形,我无法看出bug。

因此,我决定换一种实现方式。事实上,当情况变得复杂后,还是应该先画出状态机,分析清楚各个状态的转换情况。

状态机如图所示。共有六个状态,FALL_L和FALL_R分别表示从左行坠落和右行坠落。DIG_L和DIG_R分别表示左行挖掘和右行挖掘。DIG_L只会转换到FALL_L,FALL_L只会转换到LEFT,都不会转换到右行。可以看到,状态机中有很多无关项,这在之前的思路和代码中很难体现完全。

实现代码:

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=3'b000, RIGHT=3'b001, FALL_L=3'b010, FALL_R=3'b011, DIG_L=3'b100, DIG_R=3'b101;reg [2:0] state, next_state;always @(*) begin// State transition logiccase(state)LEFT: next_state = ground ? (dig ? DIG_L : (bump_left ? RIGHT : LEFT)) : FALL_L;RIGHT: next_state = ground ? (dig ? DIG_R : (bump_right ? LEFT : RIGHT)) : FALL_R;DIG_L: next_state = ground ? DIG_L : FALL_L;DIG_R: next_state = ground ? DIG_R : FALL_R;FALL_L: next_state = ground ? LEFT : FALL_L;FALL_R: next_state = ground ? RIGHT : FALL_R;endcase            end    always @(posedge clk, posedge areset) begin// State flip-flops with asynchronous resetif(areset) beginstate <= LEFT;endelse state <= next_state;end// Output logicassign walk_left = (state == LEFT);assign walk_right = (state == RIGHT);assign aaah = (state == FALL_L || state == FALL_R);assign digging = (state == DIG_L || state == DIG_R);endmodule

可以发现,代码结构和思路都清晰许多。通过三目运算符?:可以确保坠落、挖掘和前进的优先级顺序。

Lemmings4

原题目(波形demo见链接):

在Lemmings1、Lemmings2和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.

与Lemmings3相比,增加了粉碎的情况,所以引入新的状态SPLATTER。SPLATTER仅发生在坠落超过20个周期且地面恢复时。

计数放在时序逻辑中,如果next_state为坠落,则计数加一,否则置零。

实现代码:

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=3'b000, RIGHT=3'b001, FALL_L=3'b010, FALL_R=3'b011, DIG_L=3'b100, DIG_R=3'b101, SPLATTER=3'b110;reg [2:0] state, next_state;reg [7:0] count;always @(*) begin// State transition logiccase(state)LEFT: next_state = ground ? (dig ? DIG_L : (bump_left ? RIGHT : LEFT)) : FALL_L;RIGHT: next_state = ground ? (dig ? DIG_R : (bump_right ? LEFT : RIGHT)) : FALL_R;DIG_L: next_state = ground ? DIG_L : FALL_L;DIG_R: next_state = ground ? DIG_R : FALL_R;FALL_L: next_state = ground ? (count > 8'd20 ? SPLATTER: LEFT) : FALL_L;FALL_R: next_state = ground ? (count > 8'd20 ? SPLATTER: RIGHT) : FALL_R;SPLATTER: next_state = SPLATTER;endcase            end    always @(posedge clk, posedge areset) begin// State flip-flops with asynchronous resetif(areset) beginstate <= LEFT;count <= 8'd0;endelse beginstate <= next_state;count <= (next_state == FALL_L | next_state == FALL_R) ? count + 8'd1 : 8'd0;                endend// Output logicassign walk_left = (state == LEFT);assign walk_right = (state == RIGHT);assign aaah = (state == FALL_L || state == FALL_R);assign digging = (state == DIG_L ||  state == DIG_R);endmodule

————————————————
感谢您的阅读,如果您有收获,请给我一个三连吧!
如果您觉得这还不够,可以点击 打赏 按钮,告诉我: 你币有了!

verilog实现Lemmings(疯狂小旅鼠)游戏相关推荐

  1. codevs 1052:地鼠游戏

    http://codevs.cn/problem/1052/ 题目描述 Description 王钢是一名学习成绩优异的学生,在平时的学习中,他总能利用一切时间认真高效地学习,他不但学习刻苦,而且善于 ...

  2. codevs 1052 地鼠游戏

    1052 地鼠游戏  http://codevs.cn/problem/1052/ 题目描述 Description 王钢是一名学习成绩优异的学生,在平时的学习中,他总能利用一切时间认真高效地学习,他 ...

  3. 【codevs1052】地鼠游戏,标签不都是对的

    1052 地鼠游戏 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 王钢是一名学习成绩优异的学生,在平时的学习中,他总能 ...

  4. android地鼠游戏,非常地鼠手游

    非常地鼠,极端考验手速与眼力的砸地鼠游戏,游戏中玩家需要准确判断地鼠的落地位置,按照自身的规划掌握地鼠的出现规律,在地鼠出现的瞬间将其砸中,游戏玩法趣味性极强,感兴趣的玩家可以下载体验! 非常地鼠官方 ...

  5. 《疯狂杀戮》NDS游戏完工

    <疯狂杀戮>NDS游戏完工,但是没有彻底完工,以后还会继续修改它. 不管怎么样先告一段落,马上开学了,我的英语再不过,我爸真的要疯了--  游戏截图: 游戏ROM下载地址: http:// ...

  6. 疯狂怪物城html5游戏,《疯狂怪物城》评测:轻松射击 老少咸宜

    原标题:<疯狂怪物城>评测:轻松射击 老少咸宜 虽然与电影<疯狂动物城>有着一字之差,但是吉祥鸟最新电视游戏<疯狂怪物城>同样讲述了一个疯狂的故事--某一天,全城的 ...

  7. BZOJ 1022 [SHOI2008]小约翰的游戏John AntiNim游戏

    1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 1475  Solved: 932 [Submit ...

  8. 【BZOJ1022】小约翰的游戏(博弈论)

    [BZOJ1022]小约翰的游戏(博弈论) 题面 BZOJ 题解 \(Anti-SG\)游戏的模板题目. #include<iostream> #include<cstdio> ...

  9. codevs地鼠游戏(贪心)

    1052 地鼠游戏  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description 王钢是一名学习成绩优异的学生,在平时的学习中,他总能 ...

最新文章

  1. Jenkins Pipeline动态使用Git分支名称的技巧
  2. php防止模拟请求,php防止伪造跨站请求实现程序_PHP教程
  3. 405: HTTP method GET is not supported by this URL
  4. 前端学习(2617):删除品牌
  5. LeetCode 1391. 检查网格中是否存在有效路径(BFS)
  6. 【python教程入门学习】两道关于递归的练习题
  7. 雷军谈小米10的3999元起售价:定价比华为苹果厚道
  8. iOS开发UI调试神器----Reveal
  9. Centos中yum方式安装java
  10. apriori关联规则
  11. 今晚20:00整!中国首个量子计算操作系统即将发布
  12. 逆思维:GAN不能生成什么?Seeing What a GAN Cannot Generate
  13. (8)安装适合cuda10.0的显卡驱动(显卡940M升级驱动)
  14. 看完这篇操作系统,和面试官扯皮就没问题了
  15. MySQL数据库修改名称的三种方法
  16. 比较基因组学分析(Comparative Genomics Analysis)
  17. discuz!内置代码 (收藏)
  18. css是button和输入框保持在同一行
  19. 【工具】一些不错的思维导图工具
  20. openh264解码h264视频帧主流程

热门文章

  1. 通过nginx日志统计一段时间内ip的访问次数进行排序访问量统计
  2. DragonBoard 410c开发套件试用上手报告-搭建一个家庭智能管家的大脑
  3. 传奇登录器自动获取服务器,gom引擎配置登录器补丁读取规则的说明
  4. 宝塔平台配置JeecgBoot
  5. ableton live10中文版|音乐制作软件 附安装教程
  6. VMD确定分解个数K(matlab)
  7. VC 6.0在链接Link时经常卡死问题
  8. N: 无法安全地用该源进行更新,所以默认禁用该源
  9. 读书笔记:《漫画生理学》
  10. 利用pot播放器将视频的音频文件抽离。