-
Notifications
You must be signed in to change notification settings - Fork 0
/
player_control.vhd
50 lines (43 loc) · 1.69 KB
/
player_control.vhd
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
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity player_control is
Port ( CLK : in STD_LOGIC;
collision : in STD_LOGIC;
adc_value : in STD_LOGIC_VECTOR (11 downto 0);
player_y : out STD_LOGIC_VECTOR (9 downto 0)); -- 10 bits just to make it the same length as x coordinates
end player_control;
architecture Behavioral of player_control is
SIGNAL adc_10bit : STD_LOGIC_VECTOR (9 DOWNTO 0); -- again using 10 bits, but the most significant bit should ALWAYS be 0
SIGNAL counter : STD_LOGIC_VECTOR (19 DOWNTO 0); -- scale down 50 MHz clock to 60 Hz
CONSTANT prescaler : INTEGER := 833333; -- 50.000.000 Hz / 833.333 ~= 60 Hz
CONSTANT player_height : INTEGER := 12;
begin
adc_10bit <= '0' & adc_value (11 DOWNTO 3);
map_position: PROCESS (CLK)
BEGIN
IF rising_edge(CLK) THEN
IF (counter >= prescaler AND collision = '0') THEN
-- Map ADC value to player y-position on screen
-- y-position can be 0 to (480 - player_height = 468)
-- Max 9-bit ADC value is 511, so we subtract
-- 31 (~16 from each "end" of the potentiometer)
-- and also subtract the player height, so the sprite
-- cannot leave the bottom of the screen.
-- In this case we must subtract 43 total, or ~22 in
-- each end - or in this case just map the bottom 22 values
-- to 0 and the top 22 values to VMAX = 480 - player_height
IF (adc_10bit < 22) THEN
player_y <= (OTHERS => '0');
ELSIF (adc_10bit > 489) THEN
player_y <= "0111010100"; -- 468 binary
ELSE
player_y <= adc_10bit - 22;
END IF;
ELSE
counter <= counter + 1;
END IF;
END IF;
END PROCESS;
end Behavioral;