-
Notifications
You must be signed in to change notification settings - Fork 0
/
explosion.vhd
113 lines (96 loc) · 3.7 KB
/
explosion.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity explosion is
port(
clk, not_reset: in std_logic;
px_x, px_y: in std_logic_vector(9 downto 0);
destruction: in std_logic;
origin_x, origin_y: std_logic_vector(9 downto 0);
rgb_pixel: out std_logic_vector(2 downto 0)
);
end explosion;
architecture behaviour of explosion is
-- frame size (32x32 px)
constant SIZE: integer := 32;
-- colour masks
constant RED: std_logic_vector := "100";
constant YELLOW: std_logic_vector := "110";
-- for delay of 100ms
constant DELAY: integer := 2000000;
signal counter, counter_next: std_logic_vector(20 downto 0);
type states is (idle, state1, state2, state3);
signal state, state_next: states;
signal output_enable: std_logic;
-- address is made of row and column adresses
-- addr <= (row_address & col_address);
signal addr: std_logic_vector(9 downto 0);
signal row_address, col_address: std_logic_vector(4 downto 0);
signal explosion_rgb, explosion_mask: std_logic_vector(2 downto 0);
begin
process(clk, not_reset)
begin
if not_reset = '0' then
state <= idle;
counter <= (others => '0');
elsif falling_edge(clk) then
state <= state_next;
counter <= counter_next;
end if;
end process;
animation: process(state, counter, destruction)
begin
state_next <= state;
counter_next <= counter;
case state is
when idle =>
counter_next <= (others => '0');
if destruction = '1' then
state_next <= state1;
end if;
when state1 =>
if counter = DELAY - 1 then
counter_next <= (others => '0');
state_next <= state2;
else
counter_next <= counter + 1;
end if;
when state2 =>
if counter = DELAY - 1 then
counter_next <= (others => '0');
state_next <= state3;
else
counter_next <= counter + 1;
end if;
when state3 =>
if counter = DELAY - 1 then
counter_next <= (others => '0');
state_next <= idle;
else
counter_next <= counter + 1;
end if;
end case;
end process;
output_enable <= '1' when (state /= idle and
px_x >= origin_x and
px_x < origin_x + SIZE and
px_y >= origin_y and
px_y < origin_y + SIZE) else
'0';
explosion_mask <= explosion_rgb when state = state1 and
-- only allow reg through
explosion_rgb(1) = '0' else
explosion_rgb when state = state2 and
-- allow red and yellow through
explosion_rgb(0) = '0' else
-- allow all colours through
explosion_rgb when state = state3 else
(others => '0');
rgb_pixel <= explosion_mask when output_enable = '1' else (others => '0');
row_address <= px_y(4 downto 0) - origin_y(4 downto 0);
col_address <= px_x(4 downto 0) - origin_x(4 downto 0);
addr <= row_address & col_address;
explosion:
entity work.explosion_rom(content)
port map(addr => addr, data => explosion_rgb);
end behaviour;