๐Ÿ“ฆ furkan / fakequidditch

๐Ÿ“„ ver_player_controller.v ยท 123 lines
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
123module ver_player_controller #(
	parameter PLAYER_RADIUS,		// 25 px works
	parameter INITIAL_VER_POS,		// 'd200 works
	parameter HOR_POS,
	parameter MOVEMENT_FREQUENCY,	// inversely proportinal to speed ('d200000 works)
	parameter TOP_BOUNDARY,
	parameter BOT_BOUNDARY,
	parameter BLOCKING_BALL_Y
)
(	input clk,

	input bludged,

	input vu_button,
	input vd_button,

	input [9:0] BLOCKING_BALL_X,
	
	output reg [9:0] ver_pos,
	
	output reg clean_bludge,
	output reg [3:0] bludge_time
);

	// Vertical player movements
	reg [1:0] ver_state;
	
	parameter float = 'd0;
	parameter    up = 'd1;
	parameter  down = 'd2;
	
	reg can_move_up, can_move_down;

	integer up_button_counter, down_button_counter;
	integer counter_clk;
	
	initial begin 
		counter_clk         =   0;
		ver_state           = float;
		ver_pos = INITIAL_VER_POS;
		up_button_counter   =   0;
		down_button_counter =   0;
		can_move_up         =   1;
		can_move_down       =   1;
		bludge_time         =  10;
		clean_bludge        =   0;
	end
	
	always @(posedge clk) begin
		if (bludged == 1) begin
			if ((counter_clk == 49999999) && bludge_time != 0) begin
				counter_clk <= 'd0;
				bludge_time <= bludge_time - 'd1;
				clean_bludge <= 0;
			end else if (bludge_time == 0) begin
				clean_bludge <= 1;
				counter_clk <= 'd0;
			end else begin
				counter_clk <= counter_clk + 'd1;
			end
		end else begin
			bludge_time <= 10;
			clean_bludge <= 0;
		end
	end

	// State transitions

	always @(posedge clk) begin
		if (vu_button == vd_button) begin
			ver_state = float;
		end else if (vu_button == 0) begin
			ver_state = up;
		end else begin
			ver_state = down;
		end
	end
	
	always @(posedge clk) begin
		if (vu_button == 0 && up_button_counter < MOVEMENT_FREQUENCY) begin
			up_button_counter <= up_button_counter + 'd1;
		end else begin
			up_button_counter <= 0;
		end
		
		if (vd_button == 0 && down_button_counter < MOVEMENT_FREQUENCY) begin
			down_button_counter <= down_button_counter + 'd1;
		end else begin
			down_button_counter <= 0;
		end
	end

	always @(posedge clk) begin
		case (ver_state)
			float: begin
				ver_pos <= ver_pos;
			end
			up: begin
				if (ver_pos > (TOP_BOUNDARY + PLAYER_RADIUS) && up_button_counter   == 'd98 && can_move_up == 1) ver_pos <= ver_pos - 1;
			end
			down: begin
				if (ver_pos < (BOT_BOUNDARY - PLAYER_RADIUS) && down_button_counter == 'd98 && can_move_down == 1) ver_pos <= ver_pos + 1;
			end
		endcase
	end
	
	always @(posedge clk) begin
		if (bludged == 1) begin
			can_move_up   <= 0;
			can_move_down <= 0;
		end else if ((ver_pos - BLOCKING_BALL_Y)**2 + (HOR_POS - BLOCKING_BALL_X)**2 < (PLAYER_RADIUS + PLAYER_RADIUS + 2)**2) begin
			if (ver_pos > BLOCKING_BALL_Y) begin
				can_move_up   <= 0;
			end else begin
				can_move_down <= 0;
			end			
		end else begin
			can_move_up   <= 1;
			can_move_down <= 1;
		end
	end

endmodule