Verilog有限状态机(3)
HDLBits链接
前言
今天继续更新状态机小节的习题,本章主要编写Lemmings Game部分。
题库
题目描述10:
Game Lemmings1:有个小人左右走,它只有两种状态:向左走和向右走;左边碰到东西之后它就向右走,右边碰到东西之后它就向左走,两边都碰到东西就跟当前方向的反方向走;复位时小人向左走
Solution10:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| module top_module( input clk, input areset, input bump_left, input bump_right, output walk_left, output walk_right);
parameter LEFT=1'b0, RIGHT=1'b1; reg state, next_state; wire [1:0] bump; assign bump = {bump_left,bump_right};
always @(*) begin case(state) LEFT:begin if((bump == 2'b10) || (bump == 2'b11))begin next_state = RIGHT; end else begin next_state = LEFT; end end RIGHT:begin if((bump == 2'b01) || (bump == 2'b11))begin next_state = LEFT; end else begin next_state = RIGHT; end end endcase end
always @(posedge clk, posedge areset) begin if(areset)begin state <= LEFT; end else begin state <= next_state; end end
assign walk_left = (state == LEFT); assign walk_right = (state == RIGHT);
endmodule
|
题目描述11:
Game Lemmings2:有个小人左右走,它只有两种状态:向左走和向右走;左边碰到东西之后它就向右走,右边碰到东西之后它就向左走,两边都碰到东西就跟当前方向的反方向走;复位时小人向左走;
添加ground信号,ground=1时规则与上述规则相同;ground=0时,记录当前走的方向,并将aaah信号置1,直到ground=1时,走与掉落之前相同的方向。
Solution11:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| module top_module( input clk, input areset, input bump_left, input bump_right, input ground, output walk_left, output walk_right, output aaah ); parameter LEFT = 2'b0; parameter RIGHT = 2'b1; parameter AH_LEFT = 2'b10; parameter AH_RIGHT = 2'b11; reg [1:0] state,next_state; wire [1:0] bump; assign bump = {bump_left,bump_right}; always @(*)begin case(state) LEFT:begin if(ground == 1'b0)begin next_state = AH_LEFT; end else if((bump == 2'b10) || (bump == 2'b11))begin next_state = RIGHT; end else begin next_state = LEFT; end end RIGHT:begin if(ground == 1'b0)begin next_state = AH_RIGHT; end else if((bump == 2'b01) || (bump == 2'b11))begin next_state = LEFT; end else begin next_state = RIGHT; end end AH_LEFT:begin if(ground == 1'b0)begin next_state = AH_LEFT; end else begin next_state = LEFT; end end AH_RIGHT:begin if(ground == 1'b0)begin next_state = AH_RIGHT; end else begin next_state = RIGHT; end end endcase end always@(posedge clk,posedge areset)begin if(areset)begin state <= LEFT; end else begin state <= next_state; end end assign walk_left = (state == LEFT); assign walk_right = (state == RIGHT); assign aaah = ((state == AH_LEFT) | (state == AH_RIGHT));
endmodule
|
题目描述12:
Game Lemmings3:有个小人左右走,它只有两种状态:向左走和向右走;左边碰到东西之后它就向右走,右边碰到东西之后它就向左走,两边都碰到东西就跟当前方向的反方向走;复位时小人向左走;
添加ground信号,ground=1时规则与上述规则相同;ground=0时,记录当前走的方向,并将aaah信号置1,直到ground=1时,走与掉落之前相同的方向。
添加dig信号,ground=1时一直挖,ground=0时,进入aaah状态,直到ground再次为1,方向与dig开始的方向相同。
优先级:fall>dig>switch direction
Solution12:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| module top_module( input clk, input areset, input bump_left, input bump_right, input ground, input dig, output walk_left, output walk_right, output aaah, output digging );
parameter LEFT = 3'b0; parameter RIGHT = 3'b1; parameter DIG_LEFT = 3'b10; parameter DIG_RIGHT = 3'b11; parameter FALL_LEFT = 3'b100; parameter FALL_RIGHT = 3'b101; reg [2:0] state,next_state; wire [1:0] bump; assign bump = {bump_left,bump_right}; always @(*)begin case(state) LEFT:begin if(ground == 1'b0)begin next_state = FALL_LEFT; end else if(dig == 1'b1)begin next_state = DIG_LEFT; end else if((bump == 2'b10) || (bump == 2'b11))begin next_state = RIGHT; end else begin next_state = LEFT; end end RIGHT:begin if(ground == 1'b0)begin next_state = FALL_RIGHT; end else if(dig == 1'b1)begin next_state = DIG_RIGHT; end else if((bump == 2'b01) || (bump == 2'b11))begin next_state = LEFT; end else begin next_state = RIGHT; end end DIG_LEFT:begin if(ground == 1'b0)begin next_state = FALL_LEFT; end else begin next_state = DIG_LEFT; end end DIG_RIGHT:begin if(ground == 1'b0)begin next_state = FALL_RIGHT; end else begin next_state = DIG_RIGHT; end end FALL_LEFT:begin if(ground == 1'b0)begin next_state = FALL_LEFT; end else begin next_state = LEFT; end end FALL_RIGHT:begin if(ground == 1'b0)begin next_state = FALL_RIGHT; end else begin next_state = RIGHT; end end endcase end always @(posedge clk,posedge areset)begin if(areset)begin state <= LEFT; end else begin state <= next_state; end end assign walk_left = (state == LEFT); assign walk_right = (state == RIGHT); assign digging = ((state == DIG_LEFT) | (state == DIG_RIGHT)); assign aaah = ((state == FALL_LEFT) | (state == FALL_RIGHT)); endmodule
|
题目描述13:
Game Lemmings4:小人行动规则与上述规则相同,添加小人会die的规则:
如果小人fall超过20cycles,则当其接触地面时直接die(未接触地面时不会die)。dig,fall,left和right输出全部置零,直到reset信号来临。
手绘状态转移图:(Dead状态少个自己到自己的状态)
Solution13:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
| module top_module( input clk, input areset, input bump_left, input bump_right, input ground, input dig, output walk_left, output walk_right, output aaah, output digging ); parameter LEFT = 3'b0; parameter RIGHT = 3'b1; parameter DIG_LEFT = 3'b10; parameter DIG_RIGHT = 3'b11; parameter FALL_LEFT = 3'b100; parameter FALL_RIGHT = 3'b101; parameter DEAD = 3'b110; parameter SPLATTER = 3'b111; reg [2:0] state,next_state; reg [4:0] Cycle_Count; wire [1:0] bump; assign bump = {bump_left,bump_right}; always @(*)begin case(state) LEFT:begin if(ground == 1'b0)begin next_state = FALL_LEFT; end else if(dig == 1'b1)begin next_state = DIG_LEFT; end else if((bump == 2'b10) || (bump == 2'b11))begin next_state = RIGHT; end else begin next_state = LEFT; end end RIGHT:begin if(ground == 1'b0)begin next_state = FALL_RIGHT; end else if(dig == 1'b1)begin next_state = DIG_RIGHT; end else if((bump == 2'b01) || (bump == 2'b11))begin next_state = LEFT; end else begin next_state = RIGHT; end end DIG_LEFT:begin if(ground == 1'b0)begin next_state = FALL_LEFT; end else begin next_state = DIG_LEFT; end end DIG_RIGHT:begin if(ground == 1'b0)begin next_state = FALL_RIGHT; end else begin next_state = DIG_RIGHT; end end FALL_LEFT:begin if((ground == 1'b0) && (Cycle_Count < 5'd20))begin next_state = FALL_LEFT; end else if((ground == 1'b0) && (Cycle_Count >= 5'd20))begin next_state = SPLATTER; end else begin next_state = LEFT; end end FALL_RIGHT:begin if((ground == 1'b0) && (Cycle_Count < 5'd20))begin next_state = FALL_RIGHT; end else if((ground == 1'b0) && (Cycle_Count >= 5'd20))begin next_state = SPLATTER; end else begin next_state = RIGHT; end end SPLATTER:begin if(ground == 1'b1)begin next_state = DEAD; end else begin next_state = SPLATTER; end end DEAD:begin next_state = DEAD; end endcase end always @(posedge clk,posedge areset)begin if(areset)begin state <= LEFT; end else begin state <= next_state; end end always @(posedge clk,posedge areset)begin if(areset)begin Cycle_Count <= 5'd0; end else if((next_state == FALL_LEFT) || (next_state == FALL_RIGHT)) begin Cycle_Count <= Cycle_Count + 1'b1; end else begin Cycle_Count <= 5'd0; end end assign walk_left = (state == LEFT); assign walk_right = (state == RIGHT); assign aaah = ((state == FALL_LEFT) || (state == FALL_RIGHT) || (state == SPLATTER)); assign digging = ((state == DIG_LEFT) || (state == DIG_RIGHT));
endmodule
|
结语
今天更新的几道旅鼠题非常有意思,大家可以先自己尝试。代码若有问题的话可以与我交流。