-
Notifications
You must be signed in to change notification settings - Fork 2
/
fball.sv.bak
151 lines (138 loc) · 4.93 KB
/
fball.sv.bak
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
module fball ( input Clk, // 50 MHz clock
Reset, // Active-high reset signal
frame_clk, // The clock indicating a new frame (~60Hz)
input [9:0] DrawX, DrawY, // Current pixel coordinates
input [1:0] roomNum, myRoomNum, // game and fball's roomNum
input [9:0] startX, startY, // initial location
output logic is_fball, // Whether current pixel belongs to fball or background
output logic up_num, // sprite number for fball, if 1 draw fball up, if 0 draw it downwards
output logic [8:0] fball_address, // outputs fball's address for sprite drawing
output logic [9:0] Fball_X_Pos, Fball_Y_Pos // current position
);
parameter [9:0] Fball_X_Min = 10'd0; // Leftmost point on the X axis
parameter [9:0] Fball_X_Max = 10'd639; // Rightmost point on the X axis
parameter [9:0] Fball_Y_Min = 10'd0; // Topmost point on the Y axis
parameter [9:0] Fball_Y_Max = 10'd479; // Bottommost point on the Y axis
// parameter [9:0] Goomba_Y_Step = 10'd2; // Step size on the Y axis
logic [9:0] Fball_Size_X; // Fball x size
assign Fball_Size_X = 10'd10;
logic [9:0] Fball_Size_Y; // Fball y size
assign Fball_Size_Y = 10'd10;
// States
logic [9:0] Fball_Y_Vel;
logic [1:0] dormant_count; // when this reaches 3 the fireball should erupt upwards and the count should go back to 0 until the fireball has returned to below the screen
logic normal_functionality;
// Next States
logic [9:0] Fball_X_Pos_in, Fball_Y_Pos_in, Fball_Y_Vel_in;
logic up_num_in;
logic [1:0] dormant_count_in;
// Misc.
logic [9:0] Clk_counter;
//////// Do not modify the always_ff blocks. ////////
// Detect rising edge of frame_clk
logic frame_clk_delayed, frame_clk_rising_edge;
always_ff @ (posedge Clk) begin
frame_clk_delayed <= frame_clk;
frame_clk_rising_edge <= (frame_clk == 1'b1) && (frame_clk_delayed == 1'b0);
end
// Update registers
always_ff @ (posedge Clk)
begin
if (Reset) // move goomba to storage place
begin
Fball_X_Pos <= 800;
Fball_Y_Pos <= 10'd0;
Fball_Y_Vel <= 10'd0;
up_num <= 1'b1;
Clk_counter <= 10'd0;
dormant_count <= 2'd0;
normal_functionality <= 1'b0;
end
else if (roomNum == myRoomNum && normal_functionality == 1'b1) // normal goomba functionality now
begin
Fball_X_Pos <= Goomba_X_Pos_in;
Fball_Y_Pos <= Goomba_Y_Pos_in;
Goomba_Y_Vel <= Goomba_Y_Vel_in;
up_num <= up_num_in;
dormant_count <= dormant_count_in;
normal_functionality <= 1'b1;
if (Clk_counter > 1000)
Clk_counter <= 0;
else
begin
if (frame_clk_rising_edge)
Clk_counter++;
end
end
else if (roomNum == myRoomNum) // move goomba to its start position cuz it's in the right room - setup
begin
Fball_X_Pos <= startX;
Fball_Y_Pos <= startY;
Fball_Y_Vel <= 10'd0;
up_num <= 1'b1;
Clk_counter <= 10'd0;
dormant_count <= 2'd0;
normal_functionality <= 1'b1;
end
else // move goomba back to storage place
begin
Fball_X_Pos <= 800;
Fball_Y_Pos <= 10'd0;
Fball_Y_Vel <= 10'd0;
up_num <= up_num_in;
dormant_count <= dormant_count_in;
normal_functionality <= 1'b0;
if (Clk_counter > 1000)
Clk_counter <= 0;
else
begin
if (frame_clk_rising_edge)
Clk_counter++;
end
end
end
//////// Do not modify the always_ff blocks. ////////
// You need to modify always_comb block.
always_comb
begin
// By default, position unchanged and velocity at 0
Fball_X_Pos_in = Fball_X_Pos;
Fball_Y_Pos_in = Fball_Y_Pos;
Fball_Y_Vel_in = Fball_Y_Vel;
up_num_in = up_num;
dormant_count_in = dormant_count;
// Update position and motion only at rising edge of frame clock
if (frame_clk_rising_edge)
begin
Fball_X_Pos_in = Fball_X_Pos;
Fball_Y_Pos_in = Fball_Y_Pos + Fball_Y_Vel;
up_num_in = up_num;
dormant_count_in = dormant_count;
if (Clk_counter % 10 == 0)
begin
if (dormant_count < 3'd3)
dormant_count_in = dormant_count + 1'b1;
else if (dormant_count == 3'd3 && Fball_Y_Pos == 490)
walk_num_goomba_in = 3'd0;
end
end
end
// Compute whether the pixel corresponds to Goomba or background
/* Since the multiplicants are required to be signed, we have to first cast them
from logic to int (signed by default) before they are multiplied. */
int DistX, DistY;
assign DistX = DrawX - Goomba_X_Pos + Goomba_Size_X;
assign DistY = DrawY - Goomba_Y_Pos + Goomba_Size_Y;
always_comb begin
if (DistX <= (Goomba_Size_X*2) && DistY <= (Goomba_Size_Y*2) && DistX >= 10'd0 && DistY >= 10'd0)
is_goomba = 1'b1;
else
is_goomba = 1'b0;
if (is_goomba == 1'b1)
begin
goomba_address = DistX + DistY * 21;
end
else
goomba_address = 9'b0; // don't care
end
endmodule