题目:
思路:
在原有的状态机中,向FALL状态跳转前,开启一个计时器;在FALL状态中当输入ground拉高时,对计时值进行判断。
verilog代码实现:
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 [2:0] state;
reg [2:0] state_next;
assign state = state_next;
parameter LEFT = 0;
parameter RIGHT = 1;
parameter FALL_L = 2;
parameter FALL_R = 3;
parameter DIG_L = 4;
parameter DIG_R = 5;
parameter SPLAT = 6;
reg [7:0] falling_cnt = 8'd0;
reg cnt_valid = 1'b0;
always @(posedge clk) begin
if (cnt_valid) begin
falling_cnt <= falling_cnt + 1;
end else begin
falling_cnt <= 8'd0;
end
end
always @(posedge clk or posedge areset) begin
if (areset) begin
state_next <= LEFT;
end else begin
case (state)
LEFT: begin
if (!ground) begin
state_next <= FALL_L;
cnt_valid <= 1'b1; end
else if (dig) state_next <= DIG_L;
else if (bump_left) state_next <= RIGHT;
else state_next <= LEFT; end
RIGHT: begin
if (!ground) begin
state_next <= FALL_R;
cnt_valid <= 1'b1; end
else if (dig) state_next <= DIG_R;
else if (bump_right) state_next <= LEFT;
else state_next <= RIGHT; end
FALL_L: begin
if (ground) begin
cnt_valid <= 1'b0;
if (falling_cnt >= 8'd20) state_next <= SPLAT;
else state_next <= LEFT; end
else state_next <= FALL_L; end
FALL_R: begin
if (ground) begin
cnt_valid <= 1'b0;
if (falling_cnt >= 8'd20) state_next <= SPLAT;
else state_next <= RIGHT; end
else state_next <= FALL_R; end
DIG_L: begin
if (ground) state_next <= DIG_L;
else state_next <= FALL_L; end
DIG_R: begin
if (ground) state_next <= DIG_R;
else state_next <= FALL_R; end
SPLAT: begin
state_next <= SPLAT; end
endcase
end
end
always @ * begin
walk_left = (state != SPLAT & state == LEFT) ? 1'b1 : 1'b0;
walk_right = (state != SPLAT & state == RIGHT) ? 1'b1 : 1'b0;
aaah = (state != SPLAT & (state == FALL_L | state == FALL_R)) ? 1'b1 : 1'b0;
digging = (state != SPLAT & (state == DIG_L | state == DIG_R)) ? 1'b1 : 1'b0;
end
endmodule