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
70module ver_player_controller #(
parameter PLAYER_RADIUS, // 35 px works
parameter INITIAL_VER_POS, // 'd200 works
parameter MOVEMENT_FREQUENCY // inversely proportinal to speed ('d200000 works)
)
( input clk,
input vu_button,
input vd_button,
output reg [9:0] ver_pos
);
// Vertical player movements
reg [1:0] ver_state;
parameter float = 'd0;
parameter up = 'd1;
parameter down = 'd2;
integer up_button_counter, down_button_counter;
initial begin
ver_state = float;
ver_pos = INITIAL_VER_POS;
up_button_counter = 0;
down_button_counter = 0;
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
// State machine
always @(posedge clk) begin
case (ver_state)
float: begin
ver_pos <= ver_pos;
end
up: begin
if (ver_pos > (88 + PLAYER_RADIUS) && up_button_counter == 'd98) ver_pos <= ver_pos - 1;
end
down: begin
if (ver_pos < (510 - PLAYER_RADIUS) && down_button_counter == 'd98) ver_pos <= ver_pos + 1;
end
endcase
end
endmodule