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
|
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package pong_pkg is
subtype short is signed(16 downto 0);
type direction is (UP, DOWN, NONE);
type dimension is record
w : short;
h : short;
end record;
constant SCREEN_SIZE : dimension := ( w => to_signed(640, short'length),
h => to_signed(480, short'length) );
type location is record
r : short;
c : short;
end record;
type paddle is record
loc : location;
dir : direction;
end record;
component paddle_mover is
generic(
paddle_size : dimension;
screen_size : dimension;
reset_loc : location
);
port(
clk : in std_logic;
en : in std_logic;
rst : in std_logic;
dir : in direction;
q : in paddle;
d : out paddle
);
end component;
end package;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.pong_pkg.all;
entity paddle_mover is
generic(
paddle_size : dimension := (w => to_signed(1, short'length), h => to_signed(1 short'length));
screen_size : dimension := (w => to_signed(1, short'length), h => to_signed(1 short'length));
reset_loc : location := (r => to_signed(1, short'length), c => to_signed(1 short'length))
);
port(
clk : in std_logic;
en : in std_logic;
rst : in std_logic;
dir : in direction;
q : in paddle;
d : out paddle
);
end entity;
architecture beh of paddle_mover is
constant velocity : short := to_signed(1, short'length);
signal next_candidate :paddle := (dir => NONE, loc => (others => 1));
signal next_paddle : paddle := (dir => NONE, loc => (others => 1));
signal next_moves : std_logic := '0';
signal off_bottom : std_logic := '0';
signal off_top : std_logic := '0';
begin
next_candidate.dir <= q.dir;
next_candidate.loc.c <= q.loc.c;
next_candidate.loc.r <= q.loc.r + velocity when dir = DOWN else
q.loc.r - velocity when dir = UP else
q.loc.r;
off_bottom <= (next_candidate.loc.r + paddle_size.h) >= screen_size.h;
off_top <= next_candidate.loc.r <= to_unsigned(0, short'length);
next_moves <= off_bottom nor off_top;
next_paddle.dir <= next_candidate.dir;
next_paddle.loc.c <= next_candidate.loc.c;
next_paddle.loc.r <= next_candidate.loc.r when next_moves = '1' else q.loc.r;
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
d.loc <= reset_loc;
elsif en = '1' then
d <= next_paddle;
end if;
end if;
end process;
end architecture;
|