-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathenemy.sv
More file actions
107 lines (91 loc) · 2.58 KB
/
Copy pathenemy.sv
File metadata and controls
107 lines (91 loc) · 2.58 KB
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
/*
enemy.sv
Aaron Shappell, 1739332
Ryan Shappell, 1739333
3/11/2020
EE371
Lab 6, Space Invaders
This lab is the final project, we chose to implement the classic game Space Invaders on the DE1_SoC.
*/
/*
Encapsulates logic for an individual enemy in the game.
Handles sprite drawing, death detection, and end game detection.
*/
module enemy
#(parameter FILE = "enemy1.txt", parameter W = 8, parameter H = 8)
(clk, reset, frame, sx, sy, grid_x, grid_y, vga_x, vga_y, bx, by, b_hit, dead, pixel, gg);
// Input and output logic
input logic clk, reset, frame;
input logic [9:0] sx, grid_x, vga_x, bx;
input logic [8:0] sy, grid_y, vga_y, by;
output logic b_hit, dead, pixel, gg;
// Internal logic
logic [W-1:0] data [2*H-1:0]; // sprite data for two frames
logic [W-1:0] frame0 [H-1:0];
logic [W-1:0] frame1 [H-1:0];
logic [9:0] x;
logic [8:0] y;
logic color, intersects;
// Read sprite data
initial
$readmemb(FILE, data);
// Sprite instance
sprite #(W, H) s (.clk, .reset, .x, .y, .vga_x, .vga_y, .data(frame ? frame1 : frame0), .color);
// Assign frame data
assign frame0 = data[H-1:0];
assign frame1 = data[2*H-1:H];
// Draw pixel if alive and colored
assign pixel = color & ~dead;
// Calc absolute x position based on the grid and setpoint
assign x = grid_x + sx;
assign y = grid_y + sy;
// Intersection/end game detection
assign intersects = (bx >= x && bx <= (x + W - 1)) && (by >= y && by <= (y + H - 1));
assign gg = ~dead & (y >= 162);
// Sequential DFF logic
always_ff @(posedge clk) begin
if(reset) begin
dead <= 0;
b_hit <= 0;
end else if(vga_x == 240 && vga_y == 180) begin // Update enemy after frame drawn
dead <= ~dead ? intersects : dead;
b_hit <= ~dead & intersects;
end
end
endmodule
/*
Tests all possible inputs of the enemy module to verify the outputs and functionality.
*/
module enemy_tb();
// Test logic
logic clk, reset, frame;
logic [9:0] sx, grid_x, vga_x, bx;
logic [8:0] sy, grid_y, vga_y, by;
logic b_hit, dead, pixel, gg;
// Device under test
enemy dut (.*);
// Setup clock
parameter CLOCK_PERIOD = 100;
initial begin
clk <= 0;
forever #(CLOCK_PERIOD / 2) clk <= ~clk;
end
// Test inputs
initial begin
reset <= 1; sx <= 10; sy <= 10; @(posedge clk);
reset <= 0; bx <= 6; by <= 15; frame <= 0;
for (int i = 0; i < 15; i++) begin
for(int row = 8; row < 20; row++) begin
vga_y <= row;
for(int col = 8; col < 20; col++) begin
vga_x <= col; @(posedge clk);
end
end
vga_x <= 240; vga_y <= 180; @(posedge clk);
end
@(posedge clk);
@(posedge clk);
@(posedge clk);
$stop;
end
endmodule