1092 數位系統設計

遊戲機制

蛇吃完三個蘋果即為獲勝,若是遊戲途中不慎觸碰到邊界即為失敗。

功能鍵

  1. switch0 - reset
  2. button2 - left
  3. button1 - start
  4. button0 - right

遊戲機制設定

因為遊戲只能靠左右鍵控制蛇的方向,再加上蛇的移動速度較快,故不容易獲勝。

Demo

前往Youtube觀看

程式碼

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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
//Reference   : (C) OOMusou 2008 http://oomusou.cnblogs.com
//Description : Demo how to write color pattern generator

module final (
//////////////////// Clock Input ////////////////////
CLOCK_50, // 50 MHz
CLOCK_50_2, // 50 MHz
//////////////////// Push Button ////////////////////
ORG_BUTTON, // Pushbutton[2:0]
//////////////////// DPDT Switch ////////////////////
SW, // Toggle Switch[9:0]
//////////////////// 7-SEG Dispaly ////////////////////
HEX0_D, // Seven Segment Digit 0
HEX0_DP, // Seven Segment Digit DP 0
HEX1_D, // Seven Segment Digit 1
HEX1_DP, // Seven Segment Digit DP 1
HEX2_D, // Seven Segment Digit 2
HEX2_DP, // Seven Segment Digit DP 2
HEX3_D, // Seven Segment Digit 3
HEX3_DP, // Seven Segment Digit DP 3
//////////////////////// LED ////////////////////////
LEDG, // LED Green[9:0]
//////////////////////// UART ////////////////////////
UART_TXD, // UART Transmitter
UART_RXD, // UART Receiver
UART_CTS, // UART Clear To Send
UART_RTS, // UART Request To Send
///////////////////// SDRAM Interface ////////////////
DRAM_DQ, // SDRAM Data bus 16 Bits
DRAM_ADDR, // SDRAM Address bus 13 Bits
DRAM_LDQM, // SDRAM Low-byte Data Mask
DRAM_UDQM, // SDRAM High-byte Data Mask
DRAM_WE_N, // SDRAM Write Enable
DRAM_CAS_N, // SDRAM Column Address Strobe
DRAM_RAS_N, // SDRAM Row Address Strobe
DRAM_CS_N, // SDRAM Chip Select
DRAM_BA_0, // SDRAM Bank Address 0
DRAM_BA_1, // SDRAM Bank Address 1
DRAM_CLK, // SDRAM Clock
DRAM_CKE, // SDRAM Clock Enable
//////////////////// Flash Interface ////////////////
FL_DQ, // FLASH Data bus 15 Bits
FL_DQ15_AM1, // FLASH Data bus Bit 15 or Address A-1
FL_ADDR, // FLASH Address bus 22 Bits
FL_WE_N, // FLASH Write Enable
FL_RST_N, // FLASH Reset
FL_OE_N, // FLASH Output Enable
FL_CE_N, // FLASH Chip Enable
FL_WP_N, // FLASH Hardware Write Protect
FL_BYTE_N, // FLASH Selects 8/16-bit mode
FL_RY, // FLASH Ready/Busy
//////////////////// LCD Module 16X2 ////////////////
LCD_BLON, // LCD Back Light ON/OFF
LCD_RW, // LCD Read/Write Select, 0 = Write, 1 = Read
LCD_EN, // LCD Enable
LCD_RS, // LCD Command/Data Select, 0 = Command, 1 = Data
LCD_DATA, // LCD Data bus 8 bits
//////////////////// SD_Card Interface ////////////////
SD_DAT0, // SD Card Data 0
SD_DAT3, // SD Card Data 3
SD_CMD, // SD Card Command Signal
SD_CLK, // SD Card Clock
SD_WP_N, // SD Card Write Protect
//////////////////// PS2 ////////////////////////////
PS2_KBDAT, // PS2 Keyboard Data
PS2_KBCLK, // PS2 Keyboard Clock
PS2_MSDAT, // PS2 Mouse Data
PS2_MSCLK, // PS2 Mouse Clock
//////////////////// VGA ////////////////////////////
VGA_HS, // VGA H_SYNC
VGA_VS, // VGA V_SYNC
VGA_R, // VGA Red[3:0]
VGA_G, // VGA Green[3:0]
VGA_B, // VGA Blue[3:0]
//////////////////// GPIO ////////////////////////////
GPIO0_CLKIN, // GPIO Connection 0 Clock In Bus
GPIO0_CLKOUT, // GPIO Connection 0 Clock Out Bus
GPIO0_D, // GPIO Connection 0 Data Bus
GPIO1_CLKIN, // GPIO Connection 1 Clock In Bus
GPIO1_CLKOUT, // GPIO Connection 1 Clock Out Bus
GPIO1_D // GPIO Connection 1 Data Bus
);
//////////////////////// Clock Input ////////////////////////
input CLOCK_50; // 50 MHz
input CLOCK_50_2; // 50 MHz
//////////////////////// Push Button ////////////////////////
input [2:0] ORG_BUTTON; // Pushbutton[2:0]
//////////////////////// DPDT Switch ////////////////////////
input [9:0] SW; // Toggle Switch[9:0]
//////////////////////// 7-SEG Dispaly ////////////////////////
output [6:0] HEX0_D; // Seven Segment Digit 0
output HEX0_DP; // Seven Segment Digit DP 0
output [6:0] HEX1_D; // Seven Segment Digit 1
output HEX1_DP; // Seven Segment Digit DP 1
output [6:0] HEX2_D; // Seven Segment Digit 2
output HEX2_DP; // Seven Segment Digit DP 2
output [6:0] HEX3_D; // Seven Segment Digit 3
output HEX3_DP; // Seven Segment Digit DP 3
//////////////////////////// LED ////////////////////////////
output [9:0] LEDG; // LED Green[9:0]
//////////////////////////// UART ////////////////////////////
output UART_TXD; // UART Transmitter
input UART_RXD; // UART Receiver
output UART_CTS; // UART Clear To Send
input UART_RTS; // UART Request To Send
/////////////////////// SDRAM Interface ////////////////////////
inout [15:0] DRAM_DQ; // SDRAM Data bus 16 Bits
output [12:0] DRAM_ADDR; // SDRAM Address bus 13 Bits
output DRAM_LDQM; // SDRAM Low-byte Data Mask
output DRAM_UDQM; // SDRAM High-byte Data Mask
output DRAM_WE_N; // SDRAM Write Enable
output DRAM_CAS_N; // SDRAM Column Address Strobe
output DRAM_RAS_N; // SDRAM Row Address Strobe
output DRAM_CS_N; // SDRAM Chip Select
output DRAM_BA_0; // SDRAM Bank Address 0
output DRAM_BA_1; // SDRAM Bank Address 1
output DRAM_CLK; // SDRAM Clock
output DRAM_CKE; // SDRAM Clock Enable
//////////////////////// Flash Interface ////////////////////////
inout [14:0] FL_DQ; // FLASH Data bus 15 Bits
inout FL_DQ15_AM1; // FLASH Data bus Bit 15 or Address A-1
output [21:0] FL_ADDR; // FLASH Address bus 22 Bits
output FL_WE_N; // FLASH Write Enable
output FL_RST_N; // FLASH Reset
output FL_OE_N; // FLASH Output Enable
output FL_CE_N; // FLASH Chip Enable
output FL_WP_N; // FLASH Hardware Write Protect
output FL_BYTE_N; // FLASH Selects 8/16-bit mode
input FL_RY; // FLASH Ready/Busy
//////////////////// LCD Module 16X2 ////////////////////////////
inout [7:0] LCD_DATA; // LCD Data bus 8 bits
output LCD_BLON; // LCD Back Light ON/OFF
output LCD_RW; // LCD Read/Write Select, 0 = Write, 1 = Read
output LCD_EN; // LCD Enable
output LCD_RS; // LCD Command/Data Select, 0 = Command, 1 = Data
//////////////////// SD Card Interface ////////////////////////
inout SD_DAT0; // SD Card Data 0
inout SD_DAT3; // SD Card Data 3
inout SD_CMD; // SD Card Command Signal
output SD_CLK; // SD Card Clock
input SD_WP_N; // SD Card Write Protect
//////////////////////// PS2 ////////////////////////////////
inout PS2_KBDAT; // PS2 Keyboard Data
inout PS2_KBCLK; // PS2 Keyboard Clock
inout PS2_MSDAT; // PS2 Mouse Data
inout PS2_MSCLK; // PS2 Mouse Clock
//////////////////////// VGA ////////////////////////////
output VGA_HS; // VGA H_SYNC
output VGA_VS; // VGA V_SYNC
output [3:0] VGA_R; // VGA Red[3:0]
output [3:0] VGA_G; // VGA Green[3:0]
output [3:0] VGA_B; // VGA Blue[3:0]
//////////////////////// GPIO ////////////////////////////////
input [1:0] GPIO0_CLKIN; // GPIO Connection 0 Clock In Bus
output [1:0] GPIO0_CLKOUT; // GPIO Connection 0 Clock Out Bus
inout [31:0] GPIO0_D; // GPIO Connection 0 Data Bus
input [1:0] GPIO1_CLKIN; // GPIO Connection 1 Clock In Bus
output [1:0] GPIO1_CLKOUT; // GPIO Connection 1 Clock Out Bus
inout [31:0] GPIO1_D; // GPIO Connection 1 Data Bus

// Horizontal Parameter
parameter H_FRONT = 16;
parameter H_SYNC = 96;
parameter H_BACK = 48;
parameter H_ACT = 640;
parameter H_BLANK = H_FRONT + H_SYNC + H_BACK;
parameter H_TOTAL = H_FRONT + H_SYNC + H_BACK + H_ACT;

// Vertical Parameter
parameter V_FRONT = 11;
parameter V_SYNC = 2;
parameter V_BACK = 32;
parameter V_ACT = 480;
parameter V_BLANK = V_FRONT + V_SYNC + V_BACK;
parameter V_TOTAL = V_FRONT + V_SYNC + V_BACK + V_ACT;

wire CLK_25;
wire CLK_to_DAC;
wire RST_N;

divn # (.WIDTH(26), .N(2))
u0 (
.clk(CLOCK_50),
.rst_n(SW[0]),
.o_clk(CLK_25)
);

// Select DAC clock
assign CLK_to_DAC = CLK_25;
assign VGA_SYNC = 1'b0; // This pin is unused.
assign VGA_BLANK = ~((H_Cont<H_BLANK)||(V_Cont<V_BLANK));
assign VGA_CLK = ~CLK_to_DAC; // Invert internal clock to output clock
assign RST_N = SW[0]; // Set reset signal is KEY[0]
//assign RST_N = ORG_BUTTON[2];
//assign right = ORG_BUTTON[0];
//assign left = ORG_BUTTON[2];
//assign start = ORG_BUTTON[1];
wire BT[0:2];
assign BT[0] = ORG_BUTTON[0];
assign BT[1] = ORG_BUTTON[1];
assign BT[2] = ORG_BUTTON[2];

reg [10:0] H_Cont;
reg [10:0] V_Cont;
reg [9:0] vga_r;
reg [9:0] vga_g;
reg [9:0] vga_b;
reg vga_hs;
reg vga_vs;
reg [10:0] X;
reg [10:0] Y;

assign VGA_R = vga_r;
assign VGA_G = vga_g;
assign VGA_B = vga_b;
assign VGA_HS = vga_hs;
assign VGA_VS = vga_vs;

// Horizontal Generator: Refer to the pixel clock
always@(posedge CLK_to_DAC, negedge RST_N) begin
if(!RST_N) begin
H_Cont <= 0;
vga_hs <= 1;
X <= 0;
end
else begin
if (H_Cont < H_TOTAL)
H_Cont <= H_Cont+1'b1;
else
H_Cont <= 0;

// Horizontal Sync
if(H_Cont == H_FRONT-1) // Front porch end
vga_hs <= 1'b0;

if(H_Cont == H_FRONT + H_SYNC -1) // Sync pulse end
vga_hs <= 1'b1;

// Current X
if(H_Cont >= H_BLANK)
X <= H_Cont-H_BLANK;
else
X <= 0;
end
end

// Vertical Generator: Refer to the horizontal sync
always@(posedge VGA_HS, negedge RST_N) begin
if(!RST_N) begin
V_Cont <= 0;
vga_vs <= 1;
Y <= 0;
end
else begin
if (V_Cont<V_TOTAL)
V_Cont <= V_Cont + 1'b1;
else
V_Cont <= 0;

// Vertical Sync
if (V_Cont == V_FRONT-1) // Front porch end
vga_vs <= 1'b0;

if (V_Cont == V_FRONT + V_SYNC-1) // Sync pulse end
vga_vs <= 1'b1;

// Current Y
if (V_Cont >= V_BLANK)
Y <= V_Cont-V_BLANK;
else
Y <= 0;
end
end

//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////

//clock control
integer s10 = 250000000;// 10s
integer s1 = 25000000;// 1s
integer s0 = 3750000;//0.15S
integer ms1 = 25000;// 1ms
integer clock = 0;

integer dir = 3; //default right up-0, right-1, down-2, left-3
integer gamelock = 0;
integer headx, heady;
integer long = 1;
integer apple1x, apple1y;
integer apple2x, apple2y;
integer apple3x, apple3y;
integer a1 =1 ;
integer a2 =1 ;
integer a3 =1 ;

always@(posedge CLK_to_DAC, negedge RST_N) begin
if(!RST_N) begin
gamelock = 0;
dir = 3;
headx = 340;
heady = 240;
apple1x = 100;
apple1y = 120;
apple2x = 360;
apple2y = 180;
apple3x = 240;
apple3y = 420;
a1 = 1;
a2 = 1;
a3 = 1;
clock = 0;
vga_r <= 0;
vga_g <= 0;
vga_b <= 0;
end
else begin
if(gamelock == 1) begin
clock = clock + 1;
if(clock % s1 == 0) begin
clock = 0;
end
if(clock % (100*ms1) == 0) begin
if(headx >= 591 || headx <= 80 || heady <= 40 || heady >= 431) begin
gamelock = 2;
end
else if (a1 == 0 && a2 == 0 && a3 == 0) begin
gamelock = 3;
end
end

//control snack
if(clock % s0 == 0) begin
if (!BT[2]) begin
dir = dir - 1;
if (dir < 0) begin
dir = dir + 4;
end
end
else if (!BT[0]) begin
dir = dir + 1;
if (dir > 3) begin
dir = dir - 4;
end
end

if (dir == 0) begin //up
heady = heady - 10;
end
else if (dir == 1) begin //right
headx = headx + 10;
end
else if (dir == 2) begin //down
heady = heady + 10;
end
else if (dir == 3) begin //left
headx = headx - 10;
end

if(headx == apple1x && heady == apple1y) begin
a1 = 0;
end

if(headx == apple3x && heady == apple3y) begin
a3 = 0;
end

if(headx == apple2x && heady == apple2y) begin
a2 = 0;
end
end
end
vga_g <= ( X <= headx+10 && X >= headx && Y >= heady && Y <= heady+10 ) ? 1023 :
128;

vga_b <= ( Y >= 1 && Y <= 40 && X <= 640 && X >= 41) ? 1023 :
( Y >= 441 && Y <= 480 && X <= 640 && X >= 41) ? 1023 :
( X <= 640 && X >= 601) ? 1023 :
( X <= 80 && X >= 41) ? 1023 :
128;

vga_r <= ( a1 == 1 && X >= 101 && X <= 110 && Y >= 121 && Y <= 130)? 1023:
( a2 == 1 && X >= 361 && X <= 370 && Y >= 181 && Y <= 190)? 1023:
( a3 == 1 && X >= 241 && X <= 250 && Y >= 421 && Y <= 430)? 1023:
128;
if(gamelock == 0) begin
if(!BT[1]) begin
gamelock = 1;
end
end

if(gamelock == 2) begin
vga_r <= (X >= 226 && X <= 235 && Y >= 101 && Y <= 150) ? 1023:
(X >= 226 && X <= 275 && Y >= 141 && Y <= 150) ? 1023:

(X >= 286 && X <= 335 && Y >= 101 && Y <= 110) ? 1023:
(X >= 286 && X <= 335 && Y >= 141 && Y <= 150) ? 1023:
(X >= 286 && X <= 295 && Y >= 101 && Y <= 150) ? 1023:
(X >= 326 && X <= 335 && Y >= 101 && Y <= 150) ? 1023:

(X >= 346 && X <= 395 && Y >= 101 && Y <= 110) ? 1023:
(X >= 346 && X <= 395 && Y >= 121 && Y <= 130) ? 1023:
(X >= 346 && X <= 395 && Y >= 141 && Y <= 150) ? 1023:
(X >= 346 && X <= 355 && Y >= 111 && Y <= 120) ? 1023:
(X >= 386 && X <= 395 && Y >= 131 && Y <= 140) ? 1023:

(X >= 406 && X <= 455 && Y >= 101 && Y <= 110) ? 1023:
(X >= 406 && X <= 455 && Y >= 121 && Y <= 130) ? 1023:
(X >= 406 && X <= 455 && Y >= 141 && Y <= 150) ? 1023:
(X >= 406 && X <= 415 && Y >= 101 && Y <= 150) ? 1023:
128;

if(!BT[1]) begin
gamelock = 1;
end
end

if (gamelock == 3)begin
vga_r <= (X >= 256 && X <= 305 && Y >= 101 && Y <= 110) ? 1023:
(X >= 256 && X <= 305 && Y >= 121 && Y <= 130) ? 1023:
(X >= 256 && X <= 305 && Y >= 141 && Y <= 150) ? 1023:
(X >= 256 && X <= 265 && Y >= 101 && Y <= 150) ? 1023:

(X >= 316 && X <= 325 && Y >= 101 && Y <= 150) ? 1023:
(X >= 356 && X <= 365 && Y >= 101 && Y <= 150) ? 1023:
(X >= 326 && X <= 335 && Y >= 101 && Y <= 120) ? 1023:
(X >= 346 && X <= 355 && Y >= 131 && Y <= 150) ? 1023:
(X >= 336 && X <= 345 && Y >= 121 && Y <= 130) ? 1023:

(X >= 376 && X <= 385 && Y >= 101 && Y <= 150) ? 1023:
(X >= 386 && X <= 405 && Y >= 101 && Y <= 110) ? 1023:
(X >= 386 && X <= 405 && Y >= 141 && Y <= 150) ? 1023:
(X >= 406 && X <= 415 && Y >= 111 && Y <= 120) ? 1023:
(X >= 416 && X <= 425 && Y >= 121 && Y <= 130) ? 1023:
(X >= 406 && X <= 415 && Y >= 131 && Y <= 140) ? 1023:
128;

if(!BT[1]) begin
gamelock = 1;
end
end
end
end

endmodule

參考

pin腳連接和vga輸出皆參考此網站