-
Notifications
You must be signed in to change notification settings - Fork 0
/
missile.vhd
97 lines (78 loc) · 3.49 KB
/
missile.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
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
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity missile is
port(
clk, not_reset: in std_logic;
px_x, px_y: in std_logic_vector(9 downto 0);
nes_a, nes_b: in std_logic;
x_position, y_position: in std_logic_vector(9 downto 0);
destruction: in std_logic;
missile_coord_x, missile_coord_y: out std_logic_vector(9 downto 0);
shooting: out std_logic;
rgb_pixel: out std_logic_vector(0 to 2)
);
end missile;
architecture behaviour of missile is
constant WIDTH: integer := 4;
constant HEIGHT: integer := 4;
type rom_type is array(0 to HEIGHT - 1) of
std_logic_vector(WIDTH - 1 downto 0);
constant MISSILE: rom_type := ("0100", "1110", "1110", "1010");
constant DELAY: integer := 50000; -- 1kHz
signal counter, counter_next: std_logic_vector(16 downto 0);
signal row_address, col_address: std_logic_vector(1 downto 0);
signal data: std_logic_vector(WIDTH - 1 downto 0);
signal output_enable: std_logic;
signal missile_ready, missile_ready_next: std_logic;
signal button_pressed: std_logic;
signal x_coordinate, x_coordinate_next: std_logic_vector(9 downto 0);
signal y_coordinate, y_coordinate_next: std_logic_vector(9 downto 0);
begin
process(clk, not_reset)
begin
if not_reset = '0' then
counter <= (others => '0');
missile_ready <= '1';
x_coordinate <= (others => '0');
y_coordinate <= (others => '0');
elsif falling_edge(clk) then
counter <= counter_next;
missile_ready <= missile_ready_next;
x_coordinate <= x_coordinate_next;
y_coordinate <= y_coordinate_next;
end if;
end process;
shooting <= '1' when (missile_ready = '1' and
missile_ready_next = '0') else
'0';
button_pressed <= '1' when (nes_a = '1' or nes_b = '1') else '0';
missile_ready_next <= '0' when (button_pressed = '1' and
missile_ready = '1') else
'1' when (destruction = '1' or
y_coordinate < 10) else
missile_ready;
output_enable <= '1' when (missile_ready = '0' and
px_x >= x_coordinate and
px_x < x_coordinate + WIDTH and
px_y >= y_coordinate and
px_y < y_coordinate + HEIGHT) else
'0';
row_address <= px_y(1 downto 0) - y_coordinate(1 downto 0);
col_address <= px_x(1 downto 0) - x_coordinate(1 downto 0);
data <= MISSILE(conv_integer(row_address));
rgb_pixel <= "111" when (output_enable = '1' and
data(conv_integer(col_address)) = '1') else
"000";
counter_next <= counter + 1 when counter < DELAY else (others => '0');
x_coordinate_next <= x_position when (missile_ready = '1' and
button_pressed = '1') else
x_coordinate when missile_ready = '0' else
(others => '0');
y_coordinate_next <= y_coordinate - 1 when (missile_ready = '0' and
counter = 0) else
y_position when missile_ready = '1' else
y_coordinate;
missile_coord_x <= x_coordinate;
missile_coord_y <= y_coordinate;
end behaviour;