HDLbits答案更新系列13(3.2.5|HDLbits答案更新系列13(3.2.5 Finite State Machines 3.2.5.10 Lemmings 1等)

目录
前言
3.2.5 Finite State Machines
3.2.5.10 Lemmings 1(Lemmings1)
3.2.5.11 Lemmings 2(Lemmings2)
3.2.5.12 Lemmings 3(Lemmings3)
3.2.5.13 Lemmings 4(Lemmings4)
结语
HDLbits网站链接
前言 今天更新几道题目,这几道题目是旅鼠游戏,这个游戏层层递进,状态机的思想体现地淋漓尽致,希望大家可以做一做,很有趣。
3.2.5 Finite State Machines 3.2.5.10 Lemmings 1(Lemmings1) HDLbits答案更新系列13(3.2.5|HDLbits答案更新系列13(3.2.5 Finite State Machines 3.2.5.10 Lemmings 1等)
文章图片
HDLbits答案更新系列13(3.2.5|HDLbits答案更新系列13(3.2.5 Finite State Machines 3.2.5.10 Lemmings 1等)
文章图片

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=1'b0, RIGHT=1'b1; reg state, next_state; always@(posedge clk or posedge areset)begin if(areset)begin state <= LEFT; end else begin state <= next_state; end endalways @(*) begin case(state) LEFT:begin if(bump_left)begin next_state = RIGHT; end else begin next_state = LEFT; end end RIGHT:begin if(bump_right)begin next_state = LEFT; end else begin next_state = RIGHT; end end endcase end// Output logic assign walk_left = (state == LEFT); assign walk_right = (state == RIGHT); endmodule

这道题目比较容易,旅鼠只有两种状态,向左走或者向右走,如果碰到障碍物,它将切换方向,也就是如果在左侧撞到,它将会朝右走,如果在右侧撞到,将会向左走。题目要求moore型状态机实现,应该没什么难度。
3.2.5.11 Lemmings 2(Lemmings2) HDLbits答案更新系列13(3.2.5|HDLbits答案更新系列13(3.2.5 Finite State Machines 3.2.5.10 Lemmings 1等)
文章图片
HDLbits答案更新系列13(3.2.5|HDLbits答案更新系列13(3.2.5 Finite State Machines 3.2.5.10 Lemmings 1等)
文章图片

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 = 2'd0, RIGHT = 2'd1, GROUND_LEFT = 2'd2, GROUND_RIGHT = 2'd3; reg [1:0] current_state; reg [1:0] next_state; always@(posedge clk or posedge areset)begin if(areset)begin current_state <= LEFT; end else begin current_state <= next_state; end endalways@(*)begin case(current_state) LEFT:begin next_state = ground ? (bump_left ? RIGHT : LEFT) : GROUND_LEFT; end RIGHT:begin next_state = ground ? (bump_right ? LEFT : RIGHT) : GROUND_RIGHT; end GROUND_LEFT:begin next_state = ground ? LEFT : GROUND_LEFT; end GROUND_RIGHT:begin next_state = ground ? RIGHT : GROUND_RIGHT; end default:begin next_state = LEFT; end endcase endassign walk_left = (current_state == LEFT); assign walk_right = (current_state == RIGHT); assign aaah = (current_state == GROUND_LEFT || current_state == GROUND_RIGHT); /* //second way always@(posedge clk or posedge areset)begin if(areset)begin aaah <= 1'b0; end else begin aaah <= ~ground; end end */endmodule

这道题目相比第一道题,多加了一个掉落状态,如果ground为1,旅鼠将会发出大叫并且跌落。这里的旅鼠大叫信号(aaah)有两种实现方式,一种就是用状态机输出,另一种是直接将ground取反,但是不建议第二种方式,从作者的题意来看,要根据状态决定输出。
3.2.5.12 Lemmings 3(Lemmings3) HDLbits答案更新系列13(3.2.5|HDLbits答案更新系列13(3.2.5 Finite State Machines 3.2.5.10 Lemmings 1等)
文章图片
HDLbits答案更新系列13(3.2.5|HDLbits答案更新系列13(3.2.5 Finite State Machines 3.2.5.10 Lemmings 1等)
文章图片

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'd0, RIGHT = 4'd1, GROUND_LEFT = 4'd2, GROUND_RIGHT = 4'd3; parameter DIGGING_LEFT = 4'd4, DIGGING_RIGHT = 4'd5; reg [3:0] current_state; reg [3:0] next_state; always@(posedge clk or posedge areset)begin if(areset)begin current_state <= LEFT; end else begin current_state <= next_state; end endalways@(*)begin case(current_state) LEFT:begin next_state = ground ? (dig ? DIGGING_LEFT : (bump_left ? RIGHT : LEFT)) : GROUND_LEFT; end RIGHT:begin next_state = ground ? (dig ? DIGGING_RIGHT : (bump_right ? LEFT : RIGHT)) : GROUND_RIGHT; end GROUND_LEFT:begin next_state = ground ? LEFT : GROUND_LEFT; end GROUND_RIGHT:begin next_state = ground ? RIGHT : GROUND_RIGHT; end DIGGING_LEFT:begin next_state = ground ? DIGGING_LEFT : GROUND_LEFT; end DIGGING_RIGHT:begin next_state = ground ? DIGGING_RIGHT : GROUND_RIGHT; end default:begin next_state = LEFT; end endcase endassign walk_left = (current_state == LEFT); assign walk_right = (current_state == RIGHT); assign digging = (current_state == DIGGING_LEFT || current_state == DIGGING_RIGHT); assign aaah = (current_state == GROUND_LEFT || current_state == GROUND_RIGHT); /* //second way always@(posedge clk or posedge areset)begin if(areset)begin aaah <= 1'b0; end else begin aaah <= ~ground; end end */endmodule

这道题目花了我不少时间,主要在于状态的增加我没有理清楚。题目中作者说如果旅鼠在地面上(ground = 1)并且挖掘信号为1,则它可以开始挖洞,一直挖,直到把地都挖穿了(ground = 0),此时,旅鼠就掉下去了,并且发出大叫。对于大叫信号,和上一道题一样,有两种写法,建议用第一种。大家好好体会一下这道题目。
3.2.5.13 Lemmings 4(Lemmings4) HDLbits答案更新系列13(3.2.5|HDLbits答案更新系列13(3.2.5 Finite State Machines 3.2.5.10 Lemmings 1等)
文章图片
HDLbits答案更新系列13(3.2.5|HDLbits答案更新系列13(3.2.5 Finite State Machines 3.2.5.10 Lemmings 1等)
文章图片

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'd0, RIGHT = 4'd1, GROUND_LEFT = 4'd2, GROUND_RIGHT = 4'd3; parameter DIGGING_LEFT = 4'd4, DIGGING_RIGHT = 4'd5, SPLATTER = 4'd6, AAAH_END = 4'd7; reg [3:0] current_state; reg [3:0] next_state; reg [4:0] counter; always@(posedge clk or posedge areset)begin if(areset)begin counter <= 5'd0; end else if(next_state == GROUND_LEFT || next_state == GROUND_RIGHT)begin counter <= counter + 1'b1; end else begin counter <= 5'd0; end endalways@(posedge clk or posedge areset)begin if(areset)begin current_state <= LEFT; end else begin current_state <= next_state; end endalways@(*)begin case(current_state) LEFT:begin next_state = ground ? (dig ? DIGGING_LEFT : (bump_left ? RIGHT : LEFT)) : GROUND_LEFT; end RIGHT:begin next_state = ground ? (dig ? DIGGING_RIGHT : (bump_right ? LEFT : RIGHT)) : GROUND_RIGHT; end GROUND_LEFT:begin next_state = ground ? LEFT : (counter == 5'd20 ? SPLATTER : GROUND_LEFT); end GROUND_RIGHT:begin next_state = ground ? RIGHT : (counter == 5'd20 ? SPLATTER : GROUND_RIGHT); end DIGGING_LEFT:begin next_state = ground ? DIGGING_LEFT : GROUND_LEFT; end DIGGING_RIGHT:begin next_state = ground ? DIGGING_RIGHT : GROUND_RIGHT; end SPLATTER:begin next_state = ground ? AAAH_END : SPLATTER; end AAAH_END:begin next_state = AAAH_END; end default:begin next_state = LEFT; end endcase endassign walk_left = (current_state == LEFT); assign walk_right = (current_state == RIGHT); assign digging = (current_state == DIGGING_LEFT || current_state == DIGGING_RIGHT); assign aaah = (current_state == GROUND_LEFT || current_state == GROUND_RIGHT || current_state == SPLATTER); endmodule

这道题目真是作者又加了一个输出,如果旅鼠跌落的时间太久(大于20个周期),旅鼠就挂了,所以这里需要一个计数器,来计算旅鼠跌落的时间,大家注意,这里的计数器和平常的计数器不太一样,这里计数器的加1条件是当旅鼠开始跌落起计时,如果计数到20个周期,旅鼠就完蛋了...这里的大叫信号只能采用博主答案中的这种方式,没有第二种方式了。建议大家先不要看答案,先自己做一做,这几道题目真是非常有意思。
结语 今天更新这几道旅鼠的题目吧,不知道为啥,每次都把旅鼠打成竹鼠......我也很无奈.....好啦,还是那句老话,如果代码有错误的地方,欢迎大家指出来,我一定尽快改正。
HDLbits网站链接 https://hdlbits.01xz.net/wiki/Main_Page
【HDLbits答案更新系列13(3.2.5|HDLbits答案更新系列13(3.2.5 Finite State Machines 3.2.5.10 Lemmings 1等)】

    推荐阅读