FPGA-TankGame-new/TankGame.srcs/sources_1/new/tank_move.v

192 lines
4.5 KiB
Verilog

`timescale 1ns / 1ps
module tank_move(
clk, reset_n, start,
init_H, init_V,
tank_dir, tank_en, tank_move_en, player_enermy, moving,
tank_H, tank_V, tank_dir_feedback
);
input clk;
input moving;
input reset_n;
input start;
input [ 10: 0 ] init_H;
input [ 10: 0 ] init_V;
input [ 1: 0 ] tank_dir;
input tank_en;
input tank_move_en;
input player_enermy;
output reg [ 10: 0 ] tank_H;
output reg [ 10: 0 ] tank_V;
output reg [ 2: 0 ] tank_dir_feedback;
parameter HEIGHT = 480;
parameter WIDTH = 640;
parameter TANK_HEIGHT = 32;
parameter TANK_WIDTH = 32;
localparam
WAIT = 0,
INITIAL = 1,
STAY = 2,
UP = 4,
DOWN = 5,
LEFT = 6,
RIGHT = 7;
reg [ 2: 0 ] current_state, next_state;
always @( posedge clk ) begin: state_flip_flop
if ( !reset_n ) begin
current_state <= WAIT;
end
else if ( !tank_en ) begin
current_state <= WAIT;
end
else begin
current_state <= next_state;
end
end
reg init;
reg counter_en, counter_move_en;
always @( * ) begin: signals
counter_en = 1'b0;
init = 1'b0;
tank_dir_feedback[ 2 ] = 1;
case ( current_state )
INITIAL: begin
init = 1;
end
UP: begin
counter_en = 1;
tank_dir_feedback = 3'b000;
end
DOWN: begin
counter_en = 1;
tank_dir_feedback = 3'b001;
end
LEFT: begin
counter_en = 1;
tank_dir_feedback = 3'b010;
end
RIGHT: begin
counter_en = 1;
tank_dir_feedback = 3'b011;
end
endcase
end
always @( * ) begin: state_table
case ( current_state )
WAIT:
next_state = tank_en ? INITIAL : WAIT;
INITIAL:
next_state = STAY;
STAY, UP, DOWN, LEFT, RIGHT: begin
if ( !tank_en || !tank_move_en || !moving ) begin
next_state = STAY;
end
else begin
case ( tank_dir )
2'b00:
next_state = UP;
2'b01:
next_state = DOWN;
2'b10:
next_state = LEFT;
2'b11:
next_state = RIGHT;
endcase
end
end
default:
next_state = STAY;
endcase
end
always @( posedge clk ) begin: tank_move_logic
if ( !reset_n ) begin
tank_H <= init_H;
tank_V <= init_V;
end
else if ( init == 1 ) begin
tank_H <= init_H;
tank_V <= init_V;
end
else if ( counter_move_en && tank_move_en ) begin
case ( tank_dir_feedback )
3'b000: begin
if ( tank_V > 0 ) begin
tank_V <= tank_V - 1;
end
else begin
tank_V <= tank_V;
end
tank_H <= tank_H;
end
3'b001: begin
if ( tank_V + TANK_HEIGHT + 1 < HEIGHT ) begin
tank_V <= tank_V + 1;
end
else begin
tank_V <= tank_V;
end
tank_H <= tank_H;
end
3'b010: begin
if ( tank_H > 0 ) begin
tank_H <= tank_H - 1;
end
else begin
tank_H <= tank_H;
end
tank_V <= tank_V;
end
3'b011: begin
if ( tank_H + TANK_WIDTH + 1 < WIDTH ) begin
tank_H <= tank_H + 1;
end
else begin
tank_H <= tank_H;
end
tank_V <= tank_V;
end
default: begin
tank_H <= tank_H;
tank_V <= tank_V;
end
endcase
end
else begin
tank_H <= tank_H;
tank_V <= tank_V;
end
end
reg [ 31: 0 ] counter;
wire [ 31: 0 ] counter_num = player_enermy ? 2_500_000 : 2_500_000;
always @( posedge clk ) begin
if ( !reset_n ) begin
counter <= 0;
counter_move_en <= 0;
end
else if ( counter == counter_num ) begin
counter <= 0;
counter_move_en <= 1;
end
else if ( counter_en == 0 ) begin
counter <= 0;
counter_move_en <= 0;
end
else begin
counter <= counter + 1;
counter_move_en <= 0;
end
end
endmodule