diff --git a/FachvertiefungComputersystemeTODOS.svg b/FachvertiefungComputersystemeTODOS.svg new file mode 100644 index 0000000..77c7419 --- /dev/null +++ b/FachvertiefungComputersystemeTODOS.svg @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + + + + + + + + Nexys A7 + + + + + + + Artix 100T + + + + + + + Top.vhd + + + + + + + clk + + + + + + + Switches + + + + + + + 7 segment display + + + + + + + VGA + + + + + + + LEDs + + + + + + + Buttons + + + + + + + vga.vhd + + + + + + + Apples.vhd + + + + + + + Buttons.vhd + + + + + + + Gametick.vhd + + + + + + + GameArea.vhd + + + + + + + Gamelogic.vhd + + + + + + + Head.vhd + + + + + + + init.vhd + + + + + + + GameAreaMux.vhd + + + + + + + LFSR.vhd + + + + + + + reset.vhd + + + + + + + Score.vhd + + + + + + + Tail.vhd + + + + + + + game_tile_storage.vhd + + + clk + + + + + reset + + + VGA_G + + + VGA_R + + + VGA_B + + + VGA_HS + + + VGA_VS + + + + + + + + + + + + + next_pix + + + pix_col + + + + + apples_done + + + + + run_apples + + + run_head + + + direction + + + head_pos + + + head_done + + + run_init + + + init_done + + + + + tile_coord + tile_from_GA + tile_to_GA + set_tile + + + + + seed + + + run_reset + + + reset_done + + + + apple_placed + + + SEG + + + DP + + + AN + + + run_tail + + + tail_pos + + + + + tail_done + + + + diff --git a/ProjectDescription.pptx b/ProjectDescription.pptx new file mode 100644 index 0000000..8f08538 Binary files /dev/null and b/ProjectDescription.pptx differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..86b2838 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Fachvertiefung Computersysteme + +## Projektstruktur + +![Projektstruktur](./FachvertiefungComputersystemeTODOS.svg) + +## TODO + +- Magenta: selbst schreiben +- Orange: anpassen +- Blau: testen diff --git a/constraints file/Nexys-A7-100T-Master.xdc b/constraints file/Nexys-A7-100T-Master.xdc new file mode 100644 index 0000000..76cab45 --- /dev/null +++ b/constraints file/Nexys-A7-100T-Master.xdc @@ -0,0 +1,214 @@ +## This file is a general .xdc for the Nexys A7-100T +## To use it in a project: +## - uncomment the lines corresponding to used pins +## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project +## Note: As the Nexys 4 DDR was rebranded to the Nexys A7 with no substantial changes, this XDC file will also work for the Nexys 4 DDR. + +## Clock signal +set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports clk]; #IO_L12P_T1_MRCC_35 Sch=clk100mhz +create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk]; + + +##Switches +set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { SW[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0] +set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { SW[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1] +set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { SW[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2] +set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { SW[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3] +set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { SW[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4] +set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { SW[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5] +set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { SW[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6] +set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { SW[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7] +set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { SW[8] }]; #IO_L24N_T3_34 Sch=sw[8] +set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { SW[9] }]; #IO_25_34 Sch=sw[9] +set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { SW[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10] +set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { SW[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11] +#set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { SW[12] }]; #IO_L24P_T3_35 Sch=sw[12] +#set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { SW[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13] +#set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { SW[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14] +#set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { SW[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15] + +## LEDs +set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { LED[0] }]; #IO_L18P_T2_A24_15 Sch=led[0] +set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { LED[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1] +set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { LED[2] }]; #IO_L17N_T2_A25_15 Sch=led[2] +set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { LED[3] }]; #IO_L8P_T1_D11_14 Sch=led[3] +set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { LED[4] }]; #IO_L7P_T1_D09_14 Sch=led[4] +set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { LED[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5] +set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { LED[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6] +set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { LED[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7] +set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { LED[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8] +set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { LED[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9] +set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { LED[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10] +set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { LED[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11] +#set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { LED[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12] +#set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { LED[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13] +#set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { LED[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14] +#set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { LED[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15] + +## RGB LEDs +#set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { LED16_B }]; #IO_L5P_T0_D06_14 Sch=led16_b +#set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { LED16_G }]; #IO_L10P_T1_D14_14 Sch=led16_g +#set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { LED16_R }]; #IO_L11P_T1_SRCC_14 Sch=led16_r +#set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { LED17_B }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=led17_b +#set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { LED17_G }]; #IO_0_14 Sch=led17_g +#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { LED17_R }]; #IO_L11N_T1_SRCC_14 Sch=led17_r + +##7 segment display +set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { SEG[0] }]; #IO_L24N_T3_A00_D16_14 Sch=ca +set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { SEG[1] }]; #IO_25_14 Sch=cb +set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { SEG[2] }]; #IO_25_15 Sch=cc +set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { SEG[3] }]; #IO_L17P_T2_A26_15 Sch=cd +set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { SEG[4] }]; #IO_L13P_T2_MRCC_14 Sch=ce +set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { SEG[5] }]; #IO_L19P_T3_A10_D26_14 Sch=cf +set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { SEG[6] }]; #IO_L4P_T0_D04_14 Sch=cg +set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { DP }]; #IO_L19N_T3_A21_VREF_15 Sch=dp +set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { AN[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0] +set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { AN[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1] +set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { AN[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2] +set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { AN[3] }]; #IO_L19P_T3_A22_15 Sch=an[3] +set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { AN[4] }]; #IO_L8N_T1_D12_14 Sch=an[4] +set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { AN[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5] +set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { AN[6] }]; #IO_L23P_T3_35 Sch=an[6] +set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { AN[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7] + +##CPU Reset Button +#set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { CPU_RESETN }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn + +##Buttons +set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { BTNC }]; #IO_L9P_T1_DQS_14 Sch=btnc +set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { BTNU }]; #IO_L4N_T0_D05_14 Sch=btnu +set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { BTNL }]; #IO_L12P_T1_MRCC_14 Sch=btnl +set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { BTNR }]; #IO_L10N_T1_D15_14 Sch=btnr +set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { BTND }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd + + +##Pmod Headers +##Pmod Header JA +#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { JA[1] }]; #IO_L20N_T3_A19_15 Sch=ja[1] +#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { JA[2] }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2] +#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { JA[3] }]; #IO_L21P_T3_DQS_15 Sch=ja[3] +#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { JA[4] }]; #IO_L18N_T2_A23_15 Sch=ja[4] +#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { JA[7] }]; #IO_L16N_T2_A27_15 Sch=ja[7] +#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { JA[8] }]; #IO_L16P_T2_A28_15 Sch=ja[8] +#set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports { JA[9] }]; #IO_L22N_T3_A16_15 Sch=ja[9] +#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { JA[10] }]; #IO_L22P_T3_A17_15 Sch=ja[10] + +##Pmod Header JB +#set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { JB[1] }]; #IO_L1P_T0_AD0P_15 Sch=jb[1] +#set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { JB[2] }]; #IO_L14N_T2_SRCC_15 Sch=jb[2] +#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { JB[3] }]; #IO_L13N_T2_MRCC_15 Sch=jb[3] +#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { JB[4] }]; #IO_L15P_T2_DQS_15 Sch=jb[4] +#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { JB[7] }]; #IO_L11N_T1_SRCC_15 Sch=jb[7] +#set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { JB[8] }]; #IO_L5P_T0_AD9P_15 Sch=jb[8] +#set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { JB[9] }]; #IO_0_15 Sch=jb[9] +#set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { JB[10] }]; #IO_L13P_T2_MRCC_15 Sch=jb[10] + +##Pmod Header JC +#set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { JC[1] }]; #IO_L23N_T3_35 Sch=jc[1] +#set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { JC[2] }]; #IO_L19N_T3_VREF_35 Sch=jc[2] +#set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { JC[3] }]; #IO_L22N_T3_35 Sch=jc[3] +#set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { JC[4] }]; #IO_L19P_T3_35 Sch=jc[4] +#set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { JC[7] }]; #IO_L6P_T0_35 Sch=jc[7] +#set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { JC[8] }]; #IO_L22P_T3_35 Sch=jc[8] +#set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { JC[9] }]; #IO_L21P_T3_DQS_35 Sch=jc[9] +#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { JC[10] }]; #IO_L5P_T0_AD13P_35 Sch=jc[10] + +##Pmod Header JD +#set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { JD[1] }]; #IO_L21N_T3_DQS_35 Sch=jd[1] +#set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { JD[2] }]; #IO_L17P_T2_35 Sch=jd[2] +#set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { JD[3] }]; #IO_L17N_T2_35 Sch=jd[3] +#set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { JD[4] }]; #IO_L20N_T3_35 Sch=jd[4] +#set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { JD[7] }]; #IO_L15P_T2_DQS_35 Sch=jd[7] +#set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { JD[8] }]; #IO_L20P_T3_35 Sch=jd[8] +#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { JD[9] }]; #IO_L15N_T2_DQS_35 Sch=jd[9] +#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { JD[10] }]; #IO_L13N_T2_MRCC_35 Sch=jd[10] + +##Pmod Header JXADC +#set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVCMOS33 } [get_ports { XA_N[1] }]; #IO_L9N_T1_DQS_AD3N_15 Sch=xa_n[1] +#set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVCMOS33 } [get_ports { XA_P[1] }]; #IO_L9P_T1_DQS_AD3P_15 Sch=xa_p[1] +#set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVCMOS33 } [get_ports { XA_N[2] }]; #IO_L8N_T1_AD10N_15 Sch=xa_n[2] +#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVCMOS33 } [get_ports { XA_P[2] }]; #IO_L8P_T1_AD10P_15 Sch=xa_p[2] +#set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVCMOS33 } [get_ports { XA_N[3] }]; #IO_L7N_T1_AD2N_15 Sch=xa_n[3] +#set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVCMOS33 } [get_ports { XA_P[3] }]; #IO_L7P_T1_AD2P_15 Sch=xa_p[3] +#set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { XA_N[4] }]; #IO_L10N_T1_AD11N_15 Sch=xa_n[4] +#set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 } [get_ports { XA_P[4] }]; #IO_L10P_T1_AD11P_15 Sch=xa_p[4] + +##VGA Connector +set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0] +set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1] +set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2] +set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3] +set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0] +set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1] +set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2] +set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3] +set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0] +set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[1] }]; #IO_L4N_T0_35 Sch=vga_b[1] +set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2] +set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[3] }]; #IO_L4P_T0_35 Sch=vga_b[3] +set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { VGA_HS }]; #IO_L4P_T0_15 Sch=vga_hs +set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { VGA_VS }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs + +##Micro SD Connector +#set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { SD_RESET }]; #IO_L14P_T2_SRCC_35 Sch=sd_reset +#set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { SD_CD }]; #IO_L9N_T1_DQS_AD7N_35 Sch=sd_cd +#set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { SD_SCK }]; #IO_L9P_T1_DQS_AD7P_35 Sch=sd_sck +#set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { SD_CMD }]; #IO_L16N_T2_35 Sch=sd_cmd +#set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[0] }]; #IO_L16P_T2_35 Sch=sd_dat[0] +#set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[1] }]; #IO_L18N_T2_35 Sch=sd_dat[1] +#set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[2] }]; #IO_L18P_T2_35 Sch=sd_dat[2] +#set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[3] }]; #IO_L14N_T2_SRCC_35 Sch=sd_dat[3] + +##Accelerometer +#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { ACL_MISO }]; #IO_L11P_T1_SRCC_15 Sch=acl_miso +#set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { ACL_MOSI }]; #IO_L5N_T0_AD9N_15 Sch=acl_mosi +#set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { ACL_SCLK }]; #IO_L14P_T2_SRCC_15 Sch=acl_sclk +#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { ACL_CSN }]; #IO_L12P_T1_MRCC_15 Sch=acl_csn +#set_property -dict { PACKAGE_PIN B13 IOSTANDARD LVCMOS33 } [get_ports { ACL_INT[1] }]; #IO_L2P_T0_AD8P_15 Sch=acl_int[1] +#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { ACL_INT[2] }]; #IO_L20P_T3_A20_15 Sch=acl_int[2] + +##Temperature Sensor +#set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { TMP_SCL }]; #IO_L1N_T0_AD0N_15 Sch=tmp_scl +#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { TMP_SDA }]; #IO_L12N_T1_MRCC_15 Sch=tmp_sda +#set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { TMP_INT }]; #IO_L6N_T0_VREF_15 Sch=tmp_int +#set_property -dict { PACKAGE_PIN B14 IOSTANDARD LVCMOS33 } [get_ports { TMP_CT }]; #IO_L2N_T0_AD8N_15 Sch=tmp_ct + +##Omnidirectional Microphone +#set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { M_CLK }]; #IO_25_35 Sch=m_clk +#set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { M_DATA }]; #IO_L24N_T3_35 Sch=m_data +#set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { M_LRSEL }]; #IO_0_35 Sch=m_lrsel + +##PWM Audio Amplifier +#set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { AUD_PWM }]; #IO_L4N_T0_15 Sch=aud_pwm +#set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { AUD_SD }]; #IO_L6P_T0_15 Sch=aud_sd + +##USB-RS232 Interface +#set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { UART_TXD_IN }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in +#set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { UART_RXD_OUT }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out +#set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { UART_CTS }]; #IO_L12N_T1_MRCC_35 Sch=uart_cts +#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { UART_RTS }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts + +##USB HID (PS/2) +#set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { PS2_CLK }]; #IO_L13P_T2_MRCC_35 Sch=ps2_clk +#set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { PS2_DATA }]; #IO_L10N_T1_AD15N_35 Sch=ps2_data + +##SMSC Ethernet PHY +#set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { ETH_MDC }]; #IO_L11P_T1_SRCC_16 Sch=eth_mdc +#set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { ETH_MDIO }]; #IO_L14N_T2_SRCC_16 Sch=eth_mdio +#set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { ETH_RSTN }]; #IO_L10P_T1_AD15P_35 Sch=eth_rstn +#set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { ETH_CRSDV }]; #IO_L6N_T0_VREF_16 Sch=eth_crsdv +#set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXERR }]; #IO_L13N_T2_MRCC_16 Sch=eth_rxerr +#set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXD[0] }]; #IO_L13P_T2_MRCC_16 Sch=eth_rxd[0] +#set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXD[1] }]; #IO_L19N_T3_VREF_16 Sch=eth_rxd[1] +#set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXEN }]; #IO_L11N_T1_SRCC_16 Sch=eth_txen +#set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXD[0] }]; #IO_L14P_T2_SRCC_16 Sch=eth_txd[0] +#set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXD[1] }]; #IO_L12N_T1_MRCC_16 Sch=eth_txd[1] +#set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { ETH_REFCLK }]; #IO_L11P_T1_SRCC_35 Sch=eth_refclk +#set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { ETH_INTN }]; #IO_L12P_T1_MRCC_16 Sch=eth_intn + +##Quad SPI Flash +#set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[0] }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0] +#set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[1] }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1] +#set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2] +#set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3] +#set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { QSPI_CSN }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_csn diff --git a/rotten apples/Apples_r1.vhd b/rotten apples/Apples_r1.vhd new file mode 100644 index 0000000..33a36d8 --- /dev/null +++ b/rotten apples/Apples_r1.vhd @@ -0,0 +1 @@ +library IEEE;use IEEE.STD_LOGIC_1164.all;use IEEE.NUMERIC_STD.all;use work.local_types.all;entity Apples_r1 is generic(AREAWIDTH:natural:=64;AREAHEIGHT:natural:=48);port(clk:in std_ulogic;reset:in std_ulogic;random:in std_ulogic_vector(11 downto 0);tile_coord:out coordinate_t;tile_from_GA:in game_tile;tile_to_GA:out game_tile;set_tile:out std_ulogic;run_apples:in std_ulogic;apples_done:out std_ulogic;apple_placed:in std_ulogic);end Apples_r1;architecture xxyxxzz of Apples_r1 is type qxmbvtzw is(gjdorpwq,xklyfbnc,tzwqhjmv,sprcnlfd,bmvtrwqx,jwplzxkc,nyqvthwd,dcfxlrbm);signal apwznkrc,qvtbmjyl:qxmbvtzw;signal hxwdpkvs:coordinate_t;signal mnbrcwjf:coordinate_t;signal lkjhgfds:game_tile;constant trwqxmbv:coordinate_t:=(x=>(others=>'0'),y=>(others=>'0'));constant cjdpsfnl:game_tile:=(is_tail=>'0',is_head=>'0',is_apple=>'0',is_body=>'0',parent=>trwqxmbv);begin lkjhgfds.is_apple<='1';lkjhgfds.is_tail<='0';lkjhgfds.is_head<='0';lkjhgfds.is_body<='0';lkjhgfds.parent.y<="000000";lkjhgfds.parent.x<="000000";hxwdpkvs.x<=std_ulogic_vector(to_unsigned(to_integer(unsigned(random(11 downto 6)))mod AREAWIDTH,6));hxwdpkvs.y<=std_ulogic_vector(to_unsigned(to_integer(unsigned(random(5 downto 0)))mod AREAHEIGHT,6));prqwzmbv:process(clk)begin if reset='1'then apwznkrc<=gjdorpwq;elsif rising_edge(clk)then apwznkrc<=qvtbmjyl;if apwznkrc=xklyfbnc then mnbrcwjf<=hxwdpkvs;end if;end if;end process prqwzmbv;xktnljfh:process(apwznkrc,run_apples,tile_from_GA)begin case apwznkrc is when jwplzxkc=>qvtbmjyl<=nyqvthwd;when nyqvthwd=>qvtbmjyl<=dcfxlrbm;when dcfxlrbm=>qvtbmjyl<=gjdorpwq;when gjdorpwq=>if run_apples='1'then qvtbmjyl<=xklyfbnc;else qvtbmjyl<=gjdorpwq;end if;when xklyfbnc=>if apple_placed='1'then qvtbmjyl<=dcfxlrbm;else qvtbmjyl<=tzwqhjmv;end if;when tzwqhjmv=>qvtbmjyl<=sprcnlfd;when sprcnlfd=>qvtbmjyl<=bmvtrwqx;when bmvtrwqx=>qvtbmjyl<=jwplzxkc;end case;end process xktnljfh;gwbvtmzc:process(apwznkrc)begin case apwznkrc is when nyqvthwd=>tile_coord<=mnbrcwjf;set_tile<='1';tile_to_GA<=lkjhgfds;apples_done<='0';when bmvtrwqx=>tile_coord<=mnbrcwjf;set_tile<='0';tile_to_GA<=cjdpsfnl;apples_done<='0';when jwplzxkc=>tile_coord<=mnbrcwjf;set_tile<='0';tile_to_GA<=cjdpsfnl;apples_done<='0';when dcfxlrbm=>tile_coord.x<="000000";tile_coord.y<="000000";set_tile<='0';tile_to_GA<=cjdpsfnl;apples_done<='1';when xklyfbnc=>tile_coord.x<="000000";tile_coord.y<="000000";set_tile<='0';tile_to_GA<=cjdpsfnl;apples_done<='0';when gjdorpwq=>tile_coord.x<="000000";tile_coord.y<="000000";set_tile<='0';tile_to_GA<=cjdpsfnl;apples_done<='0';when tzwqhjmv=>tile_coord<=mnbrcwjf;set_tile<='0';tile_to_GA<=cjdpsfnl;apples_done<='0';when sprcnlfd=>tile_coord<=mnbrcwjf;set_tile<='0';tile_to_GA<=cjdpsfnl;apples_done<='0';end case;end process gwbvtmzc;end xxyxxzz; \ No newline at end of file diff --git a/rotten apples/Apples_r2.vhd b/rotten apples/Apples_r2.vhd new file mode 100644 index 0000000..c0bb3c8 --- /dev/null +++ b/rotten apples/Apples_r2.vhd @@ -0,0 +1 @@ +library IEEE;use IEEE.STD_LOGIC_1164.all;use IEEE.NUMERIC_STD.all;use work.local_types.all;entity Apples_r2 is generic(AREAWIDTH:natural:=64;AREAHEIGHT:natural:=48);port(clk:in std_ulogic;reset:in std_ulogic;random:in std_ulogic_vector(11 downto 0);tile_coord:out coordinate_t;tile_from_GA:in game_tile;tile_to_GA:out game_tile;set_tile:out std_ulogic;run_apples:in std_ulogic;apples_done:out std_ulogic;apple_placed:in std_ulogic);end Apples_r2;architecture Behavioral of Apples_r2 is type qxplzjwd is(XWQRTZYP,MNBCVXZA,PLKOIJUY,QAZWSXED,RFVTGBYH,TGBYHNUJ,IJMOKPLN,EDCRFVTB);signal mnbvcxza,poiuytre:qxplzjwd;signal lkjhgfds:coordinate_t;signal qwertyui:coordinate_t;signal asdfghjk:game_tile;constant zxcvbnml:coordinate_t:=(x=>(others=>'0'),y=>(others=>'0'));constant plmoknij:game_tile:=(is_tail=>'0',is_head=>'0',is_apple=>'0',is_body=>'0',parent=>zxcvbnml);begin asdfghjk.is_apple<='1';asdfghjk.is_tail<='0';asdfghjk.is_head<='0';asdfghjk.is_body<='0';asdfghjk.parent.y<="000000";asdfghjk.parent.x<="000000";lkjhgfds.x<=std_ulogic_vector((to_unsigned(to_integer(unsigned(random(11 downto 6)))mod AREAWIDTH,6)+1));lkjhgfds.y<=std_ulogic_vector((to_unsigned(to_integer(unsigned(random(5 downto 0)))mod AREAHEIGHT,6)+1));bvcxzaqw:process(clk)begin if reset='1' then mnbvcxza<=XWQRTZYP;elsif rising_edge(clk)then mnbvcxza<=poiuytre;if mnbvcxza=MNBCVXZA then qwertyui<=lkjhgfds;end if;end if;end process bvcxzaqw;njiuhbyg:process(mnbvcxza,run_apples,tile_from_GA)begin case mnbvcxza is when XWQRTZYP=>if run_apples='1'then poiuytre<=MNBCVXZA;else poiuytre<=XWQRTZYP;end if;when MNBCVXZA=>if apple_placed='1'then poiuytre<=EDCRFVTB;else poiuytre<=PLKOIJUY;end if;when PLKOIJUY=>poiuytre<=QAZWSXED;when QAZWSXED=>poiuytre<=RFVTGBYH;when RFVTGBYH=>poiuytre<=TGBYHNUJ;when TGBYHNUJ=>if tile_from_GA.is_tail='1'or tile_from_GA.is_head='1'or tile_from_GA.is_body='1'then poiuytre<=MNBCVXZA;else poiuytre<=IJMOKPLN;end if;when IJMOKPLN=>poiuytre<=EDCRFVTB;when EDCRFVTB=>poiuytre<=XWQRTZYP;end case;end process njiuhbyg;tgvrfced:process(mnbvcxza)begin case mnbvcxza is when XWQRTZYP=>tile_coord.x<="000000";tile_coord.y<="000000";set_tile<='0';tile_to_GA<=plmoknij;apples_done<='0';when MNBCVXZA=>tile_coord.x<="000000";tile_coord.y<="000000";set_tile<='0';tile_to_GA<=plmoknij;apples_done<='0';when PLKOIJUY=>tile_coord<=qwertyui;set_tile<='0';tile_to_GA<=plmoknij;apples_done<='0';when QAZWSXED=>tile_coord<=qwertyui;set_tile<='0';tile_to_GA<=plmoknij;apples_done<='0';when RFVTGBYH=>tile_coord<=qwertyui;set_tile<='0';tile_to_GA<=plmoknij;apples_done<='0';when TGBYHNUJ=>tile_coord<=qwertyui;set_tile<='0';tile_to_GA<=plmoknij;apples_done<='0';when IJMOKPLN=>tile_coord<=qwertyui;set_tile<='1';tile_to_GA<=asdfghjk;apples_done<='0';when EDCRFVTB=>tile_coord.x<="000000";tile_coord.y<="000000";set_tile<='0';tile_to_GA<=plmoknij;apples_done<='1';end case;end process tgvrfced;end Behavioral; \ No newline at end of file diff --git a/rotten apples/Apples_r3.vhd b/rotten apples/Apples_r3.vhd new file mode 100644 index 0000000..86cc520 --- /dev/null +++ b/rotten apples/Apples_r3.vhd @@ -0,0 +1 @@ +library IEEE;use IEEE.STD_LOGIC_1164.all;use IEEE.NUMERIC_STD.all;use work.local_types.all;entity Apples_r3 is generic(AREAWIDTH:natural:=64;AREAHEIGHT:natural:=48);port(clk:in std_ulogic;reset:in std_ulogic;random:in std_ulogic_vector(11 downto 0);tile_coord:out coordinate_t;tile_from_GA:in game_tile;tile_to_GA:out game_tile;set_tile:out std_ulogic;run_apples:in std_ulogic;apples_done:out std_ulogic;apple_placed:in std_ulogic);end Apples_r3;architecture KSNFOWJD of Apples_r3 is type KJDHFBVD is(HGBDLSKW,TRMCNZWO,PLVQIXUY,AFKJEHBR,DWNOCAST,SJYPXUGV,QIZBLMTF,EXRCKHWP);signal MNBCXZLQ,PWORTKJA:KJDHFBVD;signal LSDKEIRN,ZMCNEIPO:coordinate_t;signal BFVRCDSE:game_tile;constant QWEMNZXC:coordinate_t:=(x=>(others=>'0'),y=>(others=>'0'));constant XCVBASDF:game_tile:=(is_tail=>'0',is_head=>'0',is_apple=>'0',is_body=>'0',parent=>QWEMNZXC);begin BFVRCDSE.is_apple<='1';BFVRCDSE.is_tail<='0';BFVRCDSE.is_head<='0';BFVRCDSE.is_body<='0';BFVRCDSE.parent.y<="000000";BFVRCDSE.parent.x<="000000";LSDKEIRN.x<=std_ulogic_vector(to_unsigned(to_integer(unsigned(random(11 downto 6)))mod AREAWIDTH,6));LSDKEIRN.y<=std_ulogic_vector(to_unsigned(to_integer(unsigned(random(5 downto 0)))mod AREAHEIGHT,6));LKJHGFDS:process(clk)begin if reset='1'then MNBCXZLQ<=HGBDLSKW;elsif rising_edge(clk)then MNBCXZLQ<=PWORTKJA;if MNBCXZLQ=TRMCNZWO then ZMCNEIPO<=LSDKEIRN;end if;end if;end process LKJHGFDS;MNBVCXZA:process(MNBCXZLQ,run_apples,tile_from_GA)begin case MNBCXZLQ is when HGBDLSKW=>if run_apples='1'then PWORTKJA<=TRMCNZWO;else PWORTKJA<=HGBDLSKW;end if;when TRMCNZWO=>if apple_placed='1'then PWORTKJA<=EXRCKHWP;else PWORTKJA<=PLVQIXUY;end if;when PLVQIXUY=>PWORTKJA<=AFKJEHBR;when AFKJEHBR=>PWORTKJA<=DWNOCAST;when DWNOCAST=>PWORTKJA<=SJYPXUGV;when SJYPXUGV=>if tile_from_GA.is_tail='1'or tile_from_GA.is_head='1'or tile_from_GA.is_body='1'then PWORTKJA<=TRMCNZWO;else PWORTKJA<=QIZBLMTF;end if;when QIZBLMTF=>PWORTKJA<=EXRCKHWP;when EXRCKHWP=>PWORTKJA<=HGBDLSKW;end case;end process MNBVCXZA;QWERTYUI:process(MNBCXZLQ)begin case MNBCXZLQ is when HGBDLSKW|TRMCNZWO=>tile_coord.x<="000000";tile_coord.y<="000000";set_tile<='0';tile_to_GA<=XCVBASDF;apples_done<='0';when PLVQIXUY|AFKJEHBR|DWNOCAST|SJYPXUGV=>tile_coord<=ZMCNEIPO;set_tile<='0';tile_to_GA<=XCVBASDF;apples_done<='0';when QIZBLMTF=>tile_coord<=ZMCNEIPO;set_tile<='1';tile_to_GA<=BFVRCDSE;apples_done<='0';when EXRCKHWP=>tile_coord.x<="000000";tile_coord.y<="000000";set_tile<='0';tile_to_GA<=XCVBASDF;apples_done<='1';end case;end process QWERTYUI;end KSNFOWJD; \ No newline at end of file diff --git a/rotten apples/Apples_r4.vhd b/rotten apples/Apples_r4.vhd new file mode 100644 index 0000000..4fcbe3f --- /dev/null +++ b/rotten apples/Apples_r4.vhd @@ -0,0 +1 @@ +library IEEE;use IEEE.STD_LOGIC_1164.all;use IEEE.NUMERIC_STD.all;use work.local_types.all;entity Apples_r4 is generic(AREAWIDTH:natural:=64;AREAHEIGHT:natural:=48);port(clk:in std_ulogic;reset:in std_ulogic;random:in std_ulogic_vector(11 downto 0);tile_coord:out coordinate_t;tile_from_GA:in game_tile;tile_to_GA:out game_tile;set_tile:out std_ulogic;run_apples:in std_ulogic;apples_done:out std_ulogic;apple_placed:in std_ulogic);end Apples_r4;architecture qxvbgdwp of Apples_r4 is type mktjwfns is(zqxwkjmn,bvplsfcr,dhqtnrwg,fjmvyxlb,kpcaheds,gtwruizo,xnmyjqvb,lsefpkcd);signal nbrtxmvl,wdjyhqsf:mktjwfns;signal pckfbzrt:coordinate_t;signal ajslwnvd:coordinate_t;signal gmhtxcyq:game_tile;constant tdrzvkpb:coordinate_t:=(x=>(others=>'0'),y=>(others=>'0'));constant ywncmfjl:game_tile:=(is_tail=>'0',is_head=>'0',is_apple=>'0',is_body=>'0',parent=>tdrzvkpb);begin gmhtxcyq.is_apple<='1';gmhtxcyq.is_tail<='0';gmhtxcyq.is_head<='0';gmhtxcyq.is_body<='0';gmhtxcyq.parent.y<="000000";gmhtxcyq.parent.x<="000000";pckfbzrt.x<=std_ulogic_vector(to_unsigned(to_integer(unsigned(random(11 downto 6)))mod AREAWIDTH,6));pckfbzrt.y<=std_ulogic_vector(to_unsigned(to_integer(unsigned(random(5 downto 0)))mod AREAHEIGHT,6));lqpmxvsd:process(clk)begin if reset='1'then nbrtxmvl<=zqxwkjmn;elsif rising_edge(clk)then nbrtxmvl<=wdjyhqsf;if nbrtxmvl=bvplsfcr then ajslwnvd<=pckfbzrt;end if;end if;end process lqpmxvsd;hfgwkbjr:process(nbrtxmvl,run_apples,tile_from_GA)begin case nbrtxmvl is when zqxwkjmn=>if run_apples='1'then wdjyhqsf<=bvplsfcr;else wdjyhqsf<=zqxwkjmn;end if;when bvplsfcr=>wdjyhqsf<=dhqtnrwg;when dhqtnrwg=>wdjyhqsf<=fjmvyxlb;when fjmvyxlb=>wdjyhqsf<=kpcaheds;when kpcaheds=>wdjyhqsf<=gtwruizo;when gtwruizo=>if tile_from_GA.is_tail='1'or tile_from_GA.is_head='1'or tile_from_GA.is_body='1'then wdjyhqsf<=bvplsfcr;else wdjyhqsf<=xnmyjqvb;end if;when xnmyjqvb=>wdjyhqsf<=lsefpkcd;when lsefpkcd=>wdjyhqsf<=zqxwkjmn;end case;end process hfgwkbjr;rtzjdlwq:process(nbrtxmvl)begin case nbrtxmvl is when zqxwkjmn=>tile_coord.x<="000000";tile_coord.y<="000000";set_tile<='0';tile_to_GA<=ywncmfjl;apples_done<='0';when bvplsfcr=>tile_coord.x<="000000";tile_coord.y<="000000";set_tile<='0';tile_to_GA<=ywncmfjl;apples_done<='0';when dhqtnrwg=>tile_coord<=ajslwnvd;set_tile<='0';tile_to_GA<=ywncmfjl;apples_done<='0';when fjmvyxlb=>tile_coord<=ajslwnvd;set_tile<='0';tile_to_GA<=ywncmfjl;apples_done<='0';when kpcaheds=>tile_coord<=ajslwnvd;set_tile<='0';tile_to_GA<=ywncmfjl;apples_done<='0';when gtwruizo=>tile_coord<=ajslwnvd;set_tile<='0';tile_to_GA<=ywncmfjl;apples_done<='0';when xnmyjqvb=>tile_coord<=ajslwnvd;set_tile<='1';tile_to_GA<=gmhtxcyq;apples_done<='0';when lsefpkcd=>tile_coord.x<="000000";tile_coord.y<="000000";set_tile<='0';tile_to_GA<=ywncmfjl;apples_done<='1';end case;end process rtzjdlwq;end qxvbgdwp; \ No newline at end of file diff --git a/rotten apples/apples_fsm_description.pdf b/rotten apples/apples_fsm_description.pdf new file mode 100644 index 0000000..473a807 Binary files /dev/null and b/rotten apples/apples_fsm_description.pdf differ diff --git a/simulation files/Gamelogic_tb.vhd b/simulation files/Gamelogic_tb.vhd new file mode 100644 index 0000000..e6e95a6 --- /dev/null +++ b/simulation files/Gamelogic_tb.vhd @@ -0,0 +1,229 @@ +---------------------------------------------------------------------------------- +-- Company: ICT +-- Engineer: Daniel Fabian & Ulrich Paleček +-- +-- Create Date: 05/06/2026 05:54:30 PM +-- Design Name: Snake +-- Module Name: Gamelogic_tb - Behavioral +-- Project Name: Snake +-- Target Devices: Nexys 4 DDR & Nexys A7 100T +-- Tool Versions: Vivado 2020+ +-- Description: Testbench for the Main Statemachine (Gamelogic) +-- +-- Dependencies: Snake project +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 1.0 - First working version +-- Additional Comments: +-- +---------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +use work.local_types.all; + +entity Gamelogic_tb is + -- Port ( ); +end Gamelogic_tb; + +architecture testbench of Gamelogic_tb is + constant CLK_PERIOD : time := 10 ns; + signal clk_sig : std_logic := '0'; + signal tick_sig : std_logic := '0'; + signal button_pressed_sig : std_logic := '0'; + signal logic_reset_sig : std_logic := '0'; + signal past_rst : std_logic := '0'; + signal run_reset_sig : std_ulogic; + signal run_init_sig : std_ulogic; + signal run_head_sig : std_ulogic; + signal run_tail_sig : std_ulogic; + signal run_apples_sig : std_ulogic; + signal reset_done_sig : std_ulogic; + signal init_done_sig : std_ulogic; + signal head_done_sig : std_ulogic; + signal tail_done_sig : std_ulogic; + signal apples_done_sig : std_ulogic; + signal head_death_sig : std_ulogic; +begin + + Gamelogic_inst : entity work.Gamelogic + port map( + clk => clk_sig, + tick => tick_sig, + button_pressed => button_pressed_sig, + reset => logic_reset_sig, + run_reset => run_reset_sig, + run_init => run_init_sig, + run_head => run_head_sig, + run_tail => run_tail_sig, + run_apples => run_apples_sig, + reset_done => reset_done_sig, + init_done => init_done_sig, + head_done => head_done_sig, + tail_done => tail_done_sig, + apples_done => apples_done_sig, + head_death => head_death_sig + ); + + clk_gen : process + begin + clk_sig <= '1'; + wait for CLK_PERIOD / 2; + clk_sig <= '0'; + wait for CLK_PERIOD / 2; + end process; + + -- -- Stimulus Prozess + stimulus : process + begin + -- Reset Phase + logic_reset_sig <= '1'; + head_done_sig <= '0'; + head_death_sig <= '0'; + tail_done_sig <= '0'; + apples_done_sig <= '0'; + init_done_sig <= '0'; + reset_done_sig <= '0'; + wait for CLK_PERIOD * 5; + wait for 0 ns; + logic_reset_sig <= '0'; + -- Test Phase + assert run_head_sig = '0' and run_tail_sig = '0' and run_apples_sig = '0' and run_reset_sig = '1' and run_init_sig = '0' report "Reset not in Reset State" severity error; + + wait for CLK_PERIOD; + reset_done_sig <= '1'; + wait for CLK_PERIOD; + reset_done_sig <= '0'; + wait for CLK_PERIOD; + + assert run_head_sig = '0' and run_tail_sig = '0' and run_apples_sig = '0' and run_reset_sig = '0' and run_init_sig = '1' report "Not in init state after reset done" severity error; + + wait for CLK_PERIOD; + init_done_sig <= '1'; + wait for CLK_PERIOD; + init_done_sig <= '0'; + wait for CLK_PERIOD; + + assert run_head_sig = '0' and run_tail_sig = '0' and run_apples_sig = '0' and run_reset_sig = '0' and run_init_sig = '0' report "Not in empty state after init done" severity error; + + wait for CLK_PERIOD * 10; + + button_pressed_sig <= '1'; + + wait for CLK_PERIOD * 1; + + assert run_head_sig = '0' and run_tail_sig = '0' and run_apples_sig = '0' and run_reset_sig = '0' and run_init_sig = '0' report "Not in empty state after button pressed - should wait for tick" severity error; + + wait for CLK_PERIOD; + + tick_sig <= '1'; + + wait for CLK_PERIOD * 2; -- Two clock cycles for synchroniser + + assert run_head_sig = '1' and run_tail_sig = '0' and run_apples_sig = '0' and run_reset_sig = '0' and run_init_sig = '0' report "Not in head state after idle tick" severity error; + + wait for CLK_PERIOD; + head_done_sig <= '1'; + wait for CLK_PERIOD; + head_done_sig <= '0'; + wait for CLK_PERIOD; + + assert run_head_sig = '0' and run_tail_sig = '1' and run_apples_sig = '0' and run_reset_sig = '0' and run_init_sig = '0' report "Not in tail state after head done" severity error; + + wait for CLK_PERIOD; + tail_done_sig <= '1'; + wait for CLK_PERIOD; + tail_done_sig <= '0'; + wait for CLK_PERIOD; + + assert run_head_sig = '0' and run_tail_sig = '0' and run_apples_sig = '1' and run_reset_sig = '0' and run_init_sig = '0' report "Not in apples state after tail done" severity error; + + wait for CLK_PERIOD; + apples_done_sig <= '1'; + wait for CLK_PERIOD; + apples_done_sig <= '0'; + wait for CLK_PERIOD; + + assert run_head_sig = '0' and run_tail_sig = '0' and run_apples_sig = '0' and run_reset_sig = '0' and run_init_sig = '0' report "Not in idle state after apples done" severity error; + + wait for CLK_PERIOD * 10; + + tick_sig <= '0'; + assert run_head_sig = '0' and run_tail_sig = '0' and run_apples_sig = '0' and run_reset_sig = '0' and run_init_sig = '0' report "Not in empty state after button pressed - should wait for tick" severity error; + + wait for CLK_PERIOD * 20; + + assert run_head_sig = '0' and run_tail_sig = '0' and run_apples_sig = '0' and run_reset_sig = '0' and run_init_sig = '0' report "Not in empty state after button pressed - should wait for tick" severity error; + + wait for CLK_PERIOD; + + tick_sig <= '1'; + + wait for CLK_PERIOD * 2; -- Two clock cycles for synchroniser + + assert run_head_sig = '1' and run_tail_sig = '0' and run_apples_sig = '0' and run_reset_sig = '0' and run_init_sig = '0' report "Not in head state after idle tick" severity error; + wait for CLK_PERIOD * 50; + + wait for CLK_PERIOD; + head_death_sig <= '1'; + wait for CLK_PERIOD; + head_death_sig <= '0'; + wait for CLK_PERIOD; + + assert run_head_sig = '0' and run_tail_sig = '0' and run_apples_sig = '0' and run_reset_sig = '0' and run_init_sig = '0' report "Not in Death state after Head Death" severity error; + + -- CHECK RESET ONCE MORE + + wait for CLK_PERIOD * 10; + wait for 0 ns; + logic_reset_sig <= '1'; + wait for CLK_PERIOD; + wait for 0 ns; + logic_reset_sig <= '0'; + -- Test Phase + wait for CLK_PERIOD; + assert run_head_sig = '0' and run_tail_sig = '0' and run_apples_sig = '0' and run_reset_sig = '1' and run_init_sig = '0' report "Reset not in Reset State" severity error; + + wait for CLK_PERIOD; + reset_done_sig <= '1'; + wait for CLK_PERIOD; + reset_done_sig <= '0'; + wait for CLK_PERIOD; + + assert run_head_sig = '0' and run_tail_sig = '0' and run_apples_sig = '0' and run_reset_sig = '0' and run_init_sig = '1' report "Not in init state after reset done" severity error; + + wait for CLK_PERIOD; + init_done_sig <= '1'; + wait for CLK_PERIOD; + init_done_sig <= '0'; + wait for CLK_PERIOD; + + assert run_head_sig = '0' and run_tail_sig = '0' and run_apples_sig = '0' and run_reset_sig = '0' and run_init_sig = '0' report "Not in empty state after init done" severity error; + -- Simulation beenden + wait for CLK_PERIOD * 10; + std.env.stop; + end process; + + monitor : process (clk_sig) + begin + if rising_edge(clk_sig) then + if run_head_sig = '1' then + assert run_tail_sig = '0' report "More than one run signal high! (head/tail)" severity error; + assert run_apples_sig = '0' report "More than one run signal high! (head/apples)" severity error; + assert run_reset_sig = '0' report "More than one run signal high! (head/reset)" severity error; + assert run_init_sig = '0' report "More than one run signal high! (head/init)" severity error; + elsif run_tail_sig = '1' then + assert run_apples_sig = '0' report "More than one run signal high! (tail/apples)" severity error; + assert run_reset_sig = '0' report "More than one run signal high! (tail/reset)" severity error; + assert run_init_sig = '0' report "More than one run signal high! (tail/init)" severity error; + elsif run_apples_sig = '1' then + assert run_reset_sig = '0' report "More than one run signal high! (apples/reset)" severity error; + assert run_init_sig = '0' report "More than one run signal high! (apples/init)" severity error; + elsif run_reset_sig = '1' then + assert run_init_sig = '0' report "More than one run signal high! (reset/init)" severity error; + end if; + end if; + end process; + +end testbench; diff --git a/simulation files/Head_tb.vhd b/simulation files/Head_tb.vhd new file mode 100644 index 0000000..2d8a424 --- /dev/null +++ b/simulation files/Head_tb.vhd @@ -0,0 +1,1062 @@ +---------------------------------------------------------------------------------- +-- Company: ICT +-- Engineer: Daniel Fabian & Ulrich Paleček +-- +-- Create Date: 04/11/2026 03:42:35 PM +-- Design Name: Snake +-- Module Name: Head_tb - Behavioral +-- Project Name: Snake +-- Target Devices: Nexys 4 DDR & Nexys A7 100T +-- Tool Versions: Vivado 2020+ +-- Description: Testbench for module head +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 1.0 - First working version +-- Additional Comments: +-- +---------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use work.local_types.all; + +entity Head_tb is + -- Port ( ); +end Head_tb; + +architecture Testbench of Head_tb is + + constant CLK_PERIOD : time := 10 ns; + signal clk_sig : std_logic := '0'; + signal run_head_sig : std_logic := '0'; + signal head_done_sig : std_logic := '0'; + signal head_death_sig : std_logic := '0'; + signal logic_reset_sig : std_logic := '0'; + signal tile_coord_head_sig : coordinate_t; + signal tile_from_GA_sig : game_tile; + signal tile_to_GA_sig : game_tile; + signal set_tile_sig : std_ulogic; + signal head_pos_out_sig : coordinate_t; + signal direction_sig : direction_t; + + signal trigger_head : std_logic := '0'; + + signal last_tile_coord_head_sig : coordinate_t; + signal last_head_done_sig : std_logic := '0'; + signal last_head_death_sig : std_logic := '0'; + signal last_tile_to_GA_sig : game_tile; + signal last_set_tile_sig : std_ulogic; + + signal empty_tile : game_tile; + signal head_tile : game_tile; + signal body_tile : game_tile; + signal tail_tile : game_tile; + signal apple_tile : game_tile; +begin + + empty_tile.is_tail <= '0'; + empty_tile.is_head <= '0'; + empty_tile.is_apple <= '0'; + empty_tile.is_body <= '0'; + empty_tile.parent.y <= "000000"; + empty_tile.parent.x <= "000000"; + head_tile.is_head <= '1'; + head_tile.is_tail <= '0'; + head_tile.is_apple <= '0'; + head_tile.is_body <= '0'; + head_tile.parent.y <= "000000"; + head_tile.parent.x <= "000000"; + body_tile.is_head <= '0'; + body_tile.is_tail <= '0'; + body_tile.is_apple <= '0'; + body_tile.is_body <= '1'; + tail_tile.is_tail <= '1'; + tail_tile.is_head <= '0'; + tail_tile.is_apple <= '0'; + tail_tile.is_body <= '0'; + tail_tile.parent.y <= "000000"; + tail_tile.parent.x <= "000000"; + apple_tile.is_apple <= '1'; + apple_tile.is_tail <= '0'; + apple_tile.is_head <= '0'; + apple_tile.is_body <= '0'; + apple_tile.parent.y <= "000000"; + apple_tile.parent.x <= "000000"; + + Head_inst : entity work.Head + generic map( + AREAHEIGHT => 48, + AREAWIDTH => 64 + ) + port map( + clk => clk_sig, --: in std_ulogic; + run_head => run_head_sig, --: in std_ulogic; + head_done => head_done_sig, --: out std_ulogic; + head_death => head_death_sig, + reset => logic_reset_sig, + --gamearea manipulation/information interface + tile_coord => tile_coord_head_sig, --: out coordinate; + tile_from_GA => tile_from_GA_sig, --: in game_tile; + tile_to_GA => tile_to_GA_sig, --: out game_tile; + --get_tile => get_tile_sig, --: out std_ulogic; + set_tile => set_tile_sig, --: out std_ulogic; + --gamesstate information + head_pos => head_pos_out_sig, --: in coordinate; + --button direction + direction => direction_sig--, --: in buttondir--; + -- debug_last_dir => debug_last_dir_sig + ); + + clk_gen : process + begin + clk_sig <= '1'; + wait for CLK_PERIOD / 2; + clk_sig <= '0'; + wait for CLK_PERIOD / 2; + end process; + + -- 0. In a the beninging >> IDLE + -- 1. Calculate next head postition >> CALC_NEXT_HEAD_POS + -- 2. Check next head position (wall) | request tile next head position >> CHECK_NEXT_HEAD_POS + -- 3. wait >> CYCLE_WASTE + -- 4. wait >> WASTE_CYCLE + -- 5. Check death at next head position >> CHECK_DEATH + -- 6. Write Next Head Position >> SET_NEXT_HEAD + -- 7. Write Last Head Position as body >> SET_BODY + -- 8. Set Done sig >> DONE + -- Ferner liefen: >> DEATH + + kickoff_head : process (head_done_sig, head_death_sig, trigger_head) + begin + if run_head_sig = '0' and trigger_head = '1' then + run_head_sig <= '1'; + elsif run_head_sig = '1' and head_death_sig = '1' then + run_head_sig <= '0'; + elsif run_head_sig = '1' and head_done_sig = '1' then + run_head_sig <= '0'; + else + run_head_sig <= run_head_sig; + end if; + end process; + + -- -- Stimulus Prozess + stimulus : process + begin + -- Reset Phase + wait for 0 ns; + logic_reset_sig <= '1'; + tile_from_GA_sig <= empty_tile; + wait for CLK_PERIOD * 5; + logic_reset_sig <= '0'; + -- Should still be in reset state + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" and set_tile_sig = '0' and tile_to_GA_sig = empty_tile and head_done_sig = '0' and head_death_sig = '0' report "Reset not in Reset State" severity error; + wait for CLK_PERIOD * 5; + -- should be in IDLE state + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" and set_tile_sig = '0' and tile_to_GA_sig = empty_tile and head_done_sig = '0' and head_death_sig = '0' report "Not in IDLE state" severity error; + wait for CLK_PERIOD * 5; + + -- Test valid RIGHT + report "Test: Valid RIGHT"; + body_tile.parent.x <= "001101"; + body_tile.parent.y <= "010101"; + wait for 0 ns; + trigger_head <= '1'; + tile_from_GA_sig <= body_tile; + direction_sig <= RIGHT; + head_pos_out_sig.x <= "001100"; + head_pos_out_sig.y <= "010101"; + wait until tile_coord_head_sig.x /= "000000" and tile_coord_head_sig.y /= "000000"; + trigger_head <= '0'; + assert tile_coord_head_sig.x = "001101" and tile_coord_head_sig.y = "010101" report "Wrong coordinate for next head position" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = empty_tile report "tile_to_GA not empty for check" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + last_tile_coord_head_sig <= tile_coord_head_sig; + last_head_done_sig <= head_done_sig; + last_head_death_sig <= head_death_sig; + last_tile_to_GA_sig <= tile_to_GA_sig; + last_set_tile_sig <= set_tile_sig; + wait for CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + tile_from_GA_sig <= empty_tile; + wait until set_tile_sig = '1' for 50 * CLK_PERIOD; + if set_tile_sig = '1' then + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = "001101" and tile_coord_head_sig.y = "010101" report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait until tile_to_GA_sig = body_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = body_tile then + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timeout - not setting body_tile after head_tile has been set" severity failure; + end if; + else + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing body to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + assert tile_to_GA_sig = body_tile report "Not a body tile" severity error; + wait until tile_to_GA_sig = head_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = "001101" and tile_coord_head_sig.y = "010101" report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timout - not setting head_tile after body_tile has been set" severity failure; + end if; + end if; + else + report "Testbench Timeout - never setting tile" severity failure; + end if; + wait until head_done_sig = '1'; + + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" report "Position should be empty in/after done" severity error; + assert tile_to_GA_sig = empty_tile report "Should send empty tile during done state"; + assert head_death_sig = '0' report "Death and done are not possible at the same time" severity error; + + wait for CLK_PERIOD * 10; + + -- Test valid RIGHT eating apple + report "Test: Valid RIGHT eating apple"; + body_tile.parent.x <= "001101"; + body_tile.parent.y <= "010101"; + wait for 0 ns; + trigger_head <= '1'; + tile_from_GA_sig <= body_tile; + direction_sig <= RIGHT; + head_pos_out_sig.x <= "001100"; + head_pos_out_sig.y <= "010101"; + wait until tile_coord_head_sig.x /= "000000" and tile_coord_head_sig.y /= "000000"; + trigger_head <= '0'; + assert tile_coord_head_sig.x = "001101" and tile_coord_head_sig.y = "010101" report "Wrong coordinate for next head position" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = empty_tile report "tile_to_GA not empty for check" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + last_tile_coord_head_sig <= tile_coord_head_sig; + last_head_done_sig <= head_done_sig; + last_head_death_sig <= head_death_sig; + last_tile_to_GA_sig <= tile_to_GA_sig; + last_set_tile_sig <= set_tile_sig; + wait for CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + tile_from_GA_sig <= apple_tile; + wait until set_tile_sig = '1' for 50 * CLK_PERIOD; + if set_tile_sig = '1' then + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = "001101" and tile_coord_head_sig.y = "010101" report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait until tile_to_GA_sig = body_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = body_tile then + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timeout - not setting body_tile after head_tile has been set" severity failure; + end if; + else + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing body to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + assert tile_to_GA_sig = body_tile report "Not a body tile" severity error; + wait until tile_to_GA_sig = head_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = "001101" and tile_coord_head_sig.y = "010101" report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timout - not setting head_tile after body_tile has been set" severity failure; + end if; + end if; + else + report "Testbench Timeout - never setting tile" severity failure; + end if; + wait until head_done_sig = '1'; + + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" report "Position should be empty in/after done" severity error; + assert tile_to_GA_sig = empty_tile report "Should send empty tile during done state"; + assert head_death_sig = '0' report "Death and done are not possible at the same time" severity error; + + wait for CLK_PERIOD * 10; + + -- Test invalid LEFT after RIGHT + report "Test: invalid LEFT after RIGHT"; + body_tile.parent.x <= "001101"; + body_tile.parent.y <= "010101"; + wait for 0ns; + trigger_head <= '1'; + tile_from_GA_sig <= body_tile; + direction_sig <= LEFT; + head_pos_out_sig.x <= "001100"; + head_pos_out_sig.y <= "010101"; + wait until tile_coord_head_sig.x /= "000000" and tile_coord_head_sig.y /= "000000"; + trigger_head <= '0'; + assert tile_coord_head_sig.x = "001101" and tile_coord_head_sig.y = "010101" report "Wrong coordinate for next head position" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = empty_tile report "tile_to_GA not empty for check" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + last_tile_coord_head_sig <= tile_coord_head_sig; + last_head_done_sig <= head_done_sig; + last_head_death_sig <= head_death_sig; + last_tile_to_GA_sig <= tile_to_GA_sig; + last_set_tile_sig <= set_tile_sig; + wait for CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + tile_from_GA_sig <= empty_tile; + wait until set_tile_sig = '1' for 50 * CLK_PERIOD; + if set_tile_sig = '1' then + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = "001101" and tile_coord_head_sig.y = "010101" report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait until tile_to_GA_sig = body_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = body_tile then + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timeout - not setting body_tile after head_tile has been set" severity failure; + end if; + else + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing body to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + assert tile_to_GA_sig = body_tile report "Not a body tile" severity error; + wait until tile_to_GA_sig = head_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = "001101" and tile_coord_head_sig.y = "010101" report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timout - not setting head_tile after body_tile has been set" severity failure; + end if; + end if; + else + report "Testbench Timeout - never setting tile" severity failure; + end if; + wait until head_done_sig = '1'; + + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" report "Position should be empty in/after done" severity error; + assert tile_to_GA_sig = empty_tile report "Should send empty tile during done state"; + assert head_death_sig = '0' report "Death and done are not possible at the same time" severity error; + + wait for CLK_PERIOD * 10; + + -- Test valid DOWN + report "Test: Valid DOWN"; + body_tile.parent.x <= "001100"; + body_tile.parent.y <= "010110"; + wait for 0 ns; + trigger_head <= '1'; + tile_from_GA_sig <= body_tile; + direction_sig <= DOWN; + head_pos_out_sig.x <= "001100"; + head_pos_out_sig.y <= "010101"; + + wait until tile_coord_head_sig.x /= "000000" and tile_coord_head_sig.y /= "000000"; + trigger_head <= '0'; + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Wrong coordinate for next head position" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = empty_tile report "tile_to_GA not empty for check" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + last_tile_coord_head_sig <= tile_coord_head_sig; + last_head_done_sig <= head_done_sig; + last_head_death_sig <= head_death_sig; + last_tile_to_GA_sig <= tile_to_GA_sig; + last_set_tile_sig <= set_tile_sig; + wait for CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + tile_from_GA_sig <= empty_tile; + wait until set_tile_sig = '1' for 50 * CLK_PERIOD; + if set_tile_sig = '1' then + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait until tile_to_GA_sig = body_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = body_tile then + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timeout - not setting body_tile after head_tile has been set" severity failure; + end if; + else + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing body to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + assert tile_to_GA_sig = body_tile report "Not a body tile" severity error; + wait until tile_to_GA_sig = head_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timout - not setting head_tile after body_tile has been set" severity failure; + end if; + end if; + else + report "Testbench Timeout - never setting tile" severity failure; + end if; + wait until head_done_sig = '1'; + + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" report "Position should be empty in/after done" severity error; + assert tile_to_GA_sig = empty_tile report "Should send empty tile during done state"; + assert head_death_sig = '0' report "Death and done are not possible at the same time" severity error; + + wait for CLK_PERIOD * 10; + + -- Test invalid UP after DOWN + report "Test: invalid UP after DOWN"; + body_tile.parent.x <= "001100"; + body_tile.parent.y <= "010110"; + wait for 0 ns; + trigger_head <= '1'; + tile_from_GA_sig <= body_tile; + direction_sig <= UP; + head_pos_out_sig.x <= "001100"; + head_pos_out_sig.y <= "010101"; + + wait until tile_coord_head_sig.x /= "000000" and tile_coord_head_sig.y /= "000000"; + trigger_head <= '0'; + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Wrong coordinate for next head position" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = empty_tile report "tile_to_GA not empty for check" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + last_tile_coord_head_sig <= tile_coord_head_sig; + last_head_done_sig <= head_done_sig; + last_head_death_sig <= head_death_sig; + last_tile_to_GA_sig <= tile_to_GA_sig; + last_set_tile_sig <= set_tile_sig; + wait for CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + tile_from_GA_sig <= empty_tile; + wait until set_tile_sig = '1' for 50 * CLK_PERIOD; + if set_tile_sig = '1' then + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait until tile_to_GA_sig = body_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = body_tile then + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timeout - not setting body_tile after head_tile has been set" severity failure; + end if; + else + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing body to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + assert tile_to_GA_sig = body_tile report "Not a body tile" severity error; + wait until tile_to_GA_sig = head_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timout - not setting head_tile after body_tile has been set" severity failure; + end if; + end if; + else + report "Testbench Timeout - never setting tile" severity failure; + end if; + wait until head_done_sig = '1'; + + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" report "Position should be empty in/after done" severity error; + assert tile_to_GA_sig = empty_tile report "Should send empty tile during done state"; + assert head_death_sig = '0' report "Death and done are not possible at the same time" severity error; + + wait for CLK_PERIOD * 10; + + -- Test valid LEFT + report "Test: Valid LEFT"; + body_tile.parent.x <= "001011"; + body_tile.parent.y <= "010101"; + wait for 0 ns; + trigger_head <= '1'; + tile_from_GA_sig <= body_tile; + direction_sig <= LEFT; + head_pos_out_sig.x <= "001100"; + head_pos_out_sig.y <= "010101"; + + wait until tile_coord_head_sig.x /= "000000" and tile_coord_head_sig.y /= "000000"; + trigger_head <= '0'; + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Wrong coordinate for next head position" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = empty_tile report "tile_to_GA not empty for check" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + last_tile_coord_head_sig <= tile_coord_head_sig; + last_head_done_sig <= head_done_sig; + last_head_death_sig <= head_death_sig; + last_tile_to_GA_sig <= tile_to_GA_sig; + last_set_tile_sig <= set_tile_sig; + wait for CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + tile_from_GA_sig <= empty_tile; + wait until set_tile_sig = '1' for 50 * CLK_PERIOD; + if set_tile_sig = '1' then + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait until tile_to_GA_sig = body_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = body_tile then + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timeout - not setting body_tile after head_tile has been set" severity failure; + end if; + else + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing body to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + assert tile_to_GA_sig = body_tile report "Not a body tile" severity error; + wait until tile_to_GA_sig = head_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timout - not setting head_tile after body_tile has been set" severity failure; + end if; + end if; + else + report "Testbench Timeout - never setting tile" severity failure; + end if; + wait until head_done_sig = '1'; + + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" report "Position should be empty in/after done" severity error; + assert tile_to_GA_sig = empty_tile report "Should send empty tile during done state"; + assert head_death_sig = '0' report "Death and done are not possible at the same time" severity error; + + wait for CLK_PERIOD * 10; + + -- Test invalid RIGHT after LEFT + report "Test: invalid RIGHT after LEFT"; + body_tile.parent.x <= "001011"; + body_tile.parent.y <= "010101"; + wait for 0 ns; + trigger_head <= '1'; + tile_from_GA_sig <= empty_tile; + direction_sig <= RIGHT; + head_pos_out_sig.x <= "001100"; + head_pos_out_sig.y <= "010101"; + + wait until tile_coord_head_sig.x /= "000000" and tile_coord_head_sig.y /= "000000"; + trigger_head <= '0'; + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Wrong coordinate for next head position" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = empty_tile report "tile_to_GA not empty for check" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + last_tile_coord_head_sig <= tile_coord_head_sig; + last_head_done_sig <= head_done_sig; + last_head_death_sig <= head_death_sig; + last_tile_to_GA_sig <= tile_to_GA_sig; + last_set_tile_sig <= set_tile_sig; + wait for CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + tile_from_GA_sig <= empty_tile; + wait until set_tile_sig = '1' for 50 * CLK_PERIOD; + if set_tile_sig = '1' then + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait until tile_to_GA_sig = body_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = body_tile then + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timeout - not setting body_tile after head_tile has been set" severity failure; + end if; + else + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing body to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + assert tile_to_GA_sig = body_tile report "Not a body tile" severity error; + wait until tile_to_GA_sig = head_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timout - not setting head_tile after body_tile has been set" severity failure; + end if; + end if; + else + report "Testbench Timeout - never setting tile" severity failure; + end if; + wait until head_done_sig = '1'; + + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" report "Position should be empty in/after done" severity error; + assert tile_to_GA_sig = empty_tile report "Should send empty tile during done state"; + assert head_death_sig = '0' report "Death and done are not possible at the same time" severity error; + + wait for CLK_PERIOD * 10; + + -- Test valid UP + report "Test: Valid UP"; + body_tile.parent.x <= "001100"; + body_tile.parent.y <= "010100"; + wait for 0 ns; + trigger_head <= '1'; + tile_from_GA_sig <= empty_tile; + direction_sig <= UP; + head_pos_out_sig.x <= "001100"; + head_pos_out_sig.y <= "010101"; + + wait until tile_coord_head_sig.x /= "000000" and tile_coord_head_sig.y /= "000000"; + trigger_head <= '0'; + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Wrong coordinate for next head position" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = empty_tile report "tile_to_GA not empty for check" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + last_tile_coord_head_sig <= tile_coord_head_sig; + last_head_done_sig <= head_done_sig; + last_head_death_sig <= head_death_sig; + last_tile_to_GA_sig <= tile_to_GA_sig; + last_set_tile_sig <= set_tile_sig; + wait for CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + tile_from_GA_sig <= empty_tile; + wait until set_tile_sig = '1' for 50 * CLK_PERIOD; + if set_tile_sig = '1' then + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait until tile_to_GA_sig = body_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = body_tile then + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timeout - not setting body_tile after head_tile has been set" severity failure; + end if; + else + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing body to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + assert tile_to_GA_sig = body_tile report "Not a body tile" severity error; + wait until tile_to_GA_sig = head_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timout - not setting head_tile after body_tile has been set" severity failure; + end if; + end if; + else + report "Testbench Timeout - never setting tile" severity failure; + end if; + wait until head_done_sig = '1'; + + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" report "Position should be empty in/after done" severity error; + assert tile_to_GA_sig = empty_tile report "Should send empty tile during done state"; + assert head_death_sig = '0' report "Death and done are not possible at the same time" severity error; + + wait for CLK_PERIOD * 10; + + -- Test invalid DOWN (after UP) + report "Test: invalid DOWN after UP"; + body_tile.parent.x <= "001100"; + body_tile.parent.y <= "010100"; + wait for 0 ns; + trigger_head <= '1'; + tile_from_GA_sig <= empty_tile; + direction_sig <= DOWN; + head_pos_out_sig.x <= "001100"; + head_pos_out_sig.y <= "010101"; + + wait until tile_coord_head_sig.x /= "000000" and tile_coord_head_sig.y /= "000000"; + trigger_head <= '0'; + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Wrong coordinate for next head position" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = empty_tile report "tile_to_GA not empty for check" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + last_tile_coord_head_sig <= tile_coord_head_sig; + last_head_done_sig <= head_done_sig; + last_head_death_sig <= head_death_sig; + last_tile_to_GA_sig <= tile_to_GA_sig; + last_set_tile_sig <= set_tile_sig; + wait for CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + tile_from_GA_sig <= empty_tile; + wait until set_tile_sig = '1' for 50 * CLK_PERIOD; + if set_tile_sig = '1' then + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait until tile_to_GA_sig = body_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = body_tile then + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timeout - not setting body_tile after head_tile has been set" severity failure; + end if; + else + assert tile_coord_head_sig.x = "001100" and tile_coord_head_sig.y = "010101" report "Writing body to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + assert tile_to_GA_sig = body_tile report "Not a body tile" severity error; + wait until tile_to_GA_sig = head_tile for 50 * CLK_PERIOD; + if tile_to_GA_sig = head_tile then + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Writing head to wrong position" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + else + report "Testbench Timout - not setting head_tile after body_tile has been set" severity failure; + end if; + end if; + else + report "Testbench Timeout - never setting tile" severity failure; + end if; + wait until head_done_sig = '1'; + + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" report "Position should be empty in/after done" severity error; + assert tile_to_GA_sig = empty_tile report "Should send empty tile during done state"; + assert head_death_sig = '0' report "Death and done are not possible at the same time" severity error; + + wait for CLK_PERIOD * 10; + + -- Test DEATH by BODY + report "Test: DEATH by BODY"; + body_tile.parent.x <= "001100"; + body_tile.parent.y <= "010100"; + wait for 0 ns; + trigger_head <= '1'; + tile_from_GA_sig <= empty_tile; + direction_sig <= UP; + head_pos_out_sig.x <= "001100"; + head_pos_out_sig.y <= "010101"; + + wait until tile_coord_head_sig.x /= "000000" and tile_coord_head_sig.y /= "000000"; + trigger_head <= '0'; + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Wrong coordinate for next head position" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = empty_tile report "tile_to_GA not empty for check" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + last_tile_coord_head_sig <= tile_coord_head_sig; + last_head_done_sig <= head_done_sig; + last_head_death_sig <= head_death_sig; + last_tile_to_GA_sig <= tile_to_GA_sig; + last_set_tile_sig <= set_tile_sig; + wait for CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + tile_from_GA_sig <= body_tile; + wait until (set_tile_sig = '1' or head_death_sig = '1') for 50 * CLK_PERIOD; + if set_tile_sig = '1' then + report "Setting tile even though snake should die" severity error; + elsif head_death_sig = '1' then + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" report "Position should be empty in/after done" severity error; + assert tile_to_GA_sig = empty_tile report "Should send empty tile during done state"; + assert head_done_sig = '0' report "Death and done are not possible at the same time" severity error; + else + report "Testbench Timeout - never setting tile" severity failure; + end if; + + wait for CLK_PERIOD * 10; + -- Test DEATH by TAIL + report "Test: DEATH by TAIL"; + body_tile.parent.x <= "001100"; + body_tile.parent.y <= "010100"; + wait for 0 ns; + trigger_head <= '1'; + tile_from_GA_sig <= empty_tile; + direction_sig <= UP; + head_pos_out_sig.x <= "001100"; + head_pos_out_sig.y <= "010101"; + + wait until tile_coord_head_sig.x /= "000000" and tile_coord_head_sig.y /= "000000"; + trigger_head <= '0'; + assert tile_coord_head_sig.x = body_tile.parent.x and tile_coord_head_sig.y = body_tile.parent.y report "Wrong coordinate for next head position" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = empty_tile report "tile_to_GA not empty for check" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + last_tile_coord_head_sig <= tile_coord_head_sig; + last_head_done_sig <= head_done_sig; + last_head_death_sig <= head_death_sig; + last_tile_to_GA_sig <= tile_to_GA_sig; + last_set_tile_sig <= set_tile_sig; + wait for CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + wait for 0.1 * CLK_PERIOD; + assert tile_coord_head_sig = last_tile_coord_head_sig report "Coordinate changed during read operation" severity error; + assert set_tile_sig = '0' report "Setting tile without checking" severity error; + assert tile_to_GA_sig = last_tile_to_GA_sig report "tile_to_GA changed during read operation" severity error; + assert head_done_sig = '0' report "Head cannot be done during pos check" severity error; + assert head_death_sig = '0' report "Head cannot die during pos check" severity error; + wait for 0.9 * CLK_PERIOD; + tile_from_GA_sig <= tail_tile; + wait until (set_tile_sig = '1' or head_death_sig = '1') for 50 * CLK_PERIOD; + if set_tile_sig = '1' then + report "Setting tile even though snake should die" severity error; + elsif head_death_sig = '1' then + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" report "Position should be empty in/after done" severity error; + assert tile_to_GA_sig = empty_tile report "Should send empty tile during done state"; + assert head_done_sig = '0' report "Death and done are not possible at the same time" severity error; + else + report "Testbench Timeout - never setting tile" severity failure; + end if; + + wait for CLK_PERIOD * 10; + + -- Test DEATH by WALL (x overflow) + report "Test: DEATH by WALL (x overflow)"; + trigger_head <= '1'; + tile_from_GA_sig <= empty_tile; + direction_sig <= RIGHT; + head_pos_out_sig.x <= "111111"; + head_pos_out_sig.y <= "010101"; + body_tile.parent.x <= "001100"; + body_tile.parent.y <= "010100"; + + wait until head_death_sig = '1' for 50 * CLK_PERIOD; + if head_death_sig = '1' then + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" report "Position should be empty in/after done" severity error; + assert tile_to_GA_sig = empty_tile report "Should send empty tile during done state"; + assert head_done_sig = '0' report "Death and done are not possible at the same time" severity error; + else + report "Testbench Timeout - Snake did not die" severity failure; + end if; + + wait for CLK_PERIOD * 10; + + -- Set last direction to left by actually turning left + trigger_head <= '1'; + tile_from_GA_sig <= empty_tile; + direction_sig <= LEFT; + head_pos_out_sig.x <= "001100"; + head_pos_out_sig.y <= "010101"; + body_tile.parent.x <= "001011"; + body_tile.parent.y <= "010101"; + wait for CLK_PERIOD * 11; + trigger_head <= '0'; + wait for CLK_PERIOD * 10; + + -- Test DEATH by WALL (y overflow) + report "Test: DEATH by WALL (y overflow)"; + trigger_head <= '1'; + tile_from_GA_sig <= empty_tile; + direction_sig <= DOWN; + head_pos_out_sig.x <= "001100"; + head_pos_out_sig.y <= "101111"; + body_tile.parent.x <= "001100"; + body_tile.parent.y <= "010100"; + wait until head_death_sig = '1' for 50 * CLK_PERIOD; + if head_death_sig = '1' then + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" report "Position should be empty in/after done" severity error; + assert tile_to_GA_sig = empty_tile report "Should send empty tile during done state"; + assert head_done_sig = '0' report "Death and done are not possible at the same time" severity error; + else + report "Testbench Timeout - Snake did not die" severity failure; + end if; + wait for CLK_PERIOD * 10; + + -- Test DEATH by WALL (x underflow) + report "Test: DEATH by WALL (x underflow)"; + trigger_head <= '1'; + tile_from_GA_sig <= empty_tile; + direction_sig <= LEFT; + head_pos_out_sig.x <= "000000"; + head_pos_out_sig.y <= "010101"; + body_tile.parent.x <= "001100"; + body_tile.parent.y <= "010100"; + wait until head_death_sig = '1' for 50 * CLK_PERIOD; + if head_death_sig = '1' then + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" report "Position should be empty in/after done" severity error; + assert tile_to_GA_sig = empty_tile report "Should send empty tile during done state"; + assert head_done_sig = '0' report "Death and done are not possible at the same time" severity error; + else + report "Testbench Timeout - Snake did not die" severity failure; + end if; + wait for CLK_PERIOD * 10; + + -- Test DEATH by WALL (y underflow) + report "Test: DEATH by WALL (y underflow)"; + trigger_head <= '1'; + tile_from_GA_sig <= empty_tile; + direction_sig <= UP; + head_pos_out_sig.x <= "001100"; + head_pos_out_sig.y <= "000000"; + body_tile.parent.x <= "001100"; + body_tile.parent.y <= "010100"; + wait until head_death_sig = '1' for 50 * CLK_PERIOD; + if head_death_sig = '1' then + assert tile_coord_head_sig.x = "000000" and tile_coord_head_sig.y = "000000" report "Position should be empty in/after done" severity error; + assert tile_to_GA_sig = empty_tile report "Should send empty tile during done state"; + assert head_done_sig = '0' report "Death and done are not possible at the same time" severity error; + else + report "Testbench Timeout - Snake did not die" severity failure; + end if; + + wait for CLK_PERIOD * 10; + + -- Simulation beenden + wait for CLK_PERIOD * 10; + std.env.stop; + end process; + + -- monitor : process (clk_sig) + -- begin + -- -- assert direction_sig = LEFT report "T'was left" severity warning; + -- end process; +end Testbench; diff --git a/simulation files/LFSR_tb.vhd b/simulation files/LFSR_tb.vhd new file mode 100644 index 0000000..ad47147 --- /dev/null +++ b/simulation files/LFSR_tb.vhd @@ -0,0 +1,237 @@ +---------------------------------------------------------------------------------- +-- Company: ICT +-- Engineer: Daniel Fabian & Ulrich Paleček +-- +-- Create Date: 05/06/2026 03:24:20 PM +-- Design Name: Snake +-- Module Name: LFSR_tb - Behavioral +-- Project Name: Snake +-- Target Devices: Nexys 4 DDR & Nexys A7 100T +-- Tool Versions: Vivado 2020+ +-- Description: Testbench for the LFSR Module +-- +-- Dependencies: Snake project +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 1.0 - First working version +-- Additional Comments: +-- +---------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +use work.local_types.all; + +entity LFSR_tb is + -- Port ( ); +end LFSR_tb; + +architecture testbench of LFSR_tb is + constant CLK_PERIOD : time := 10 ns; + signal clk_sig : std_logic := '0'; + signal logic_reset_sig : std_logic := '0'; + signal past_rst : std_logic := '0'; + signal seed_sig : std_ulogic_vector(11 downto 0); + signal random_sig : std_ulogic_vector(11 downto 0); + signal random_sig_past : std_ulogic_vector(11 downto 0) := (others => '0'); + signal started : std_logic := '0'; +begin + + LFSR_inst : entity work.LFSR + port map( + clk => clk_sig, + reset => logic_reset_sig, + seed => seed_sig, + random => random_sig + ); + + clk_gen : process + begin + clk_sig <= '1'; + wait for CLK_PERIOD / 2; + clk_sig <= '0'; + wait for CLK_PERIOD / 2; + started <= '1'; + end process; + + -- -- Stimulus Prozess + stimulus : process + begin + -- Reset Phase + logic_reset_sig <= '1'; + seed_sig <= "000000000100"; + wait for CLK_PERIOD * 5; + wait for 0 ns; + logic_reset_sig <= '0'; + -- Test Phase + report "Begin Test, seed: 000000000100"; + wait for CLK_PERIOD; + assert random_sig = "000000000100" report "Wrong Value Step 1" severity error; + wait for CLK_PERIOD; + assert random_sig = "000000001000" report "Wrong Value Step 2" severity error; + wait for CLK_PERIOD; + assert random_sig = "000000010000" report "Wrong Value Step 3" severity error; + wait for CLK_PERIOD; + assert random_sig = "000000100000" report "Wrong Value Step 4" severity error; + wait for CLK_PERIOD; + assert random_sig = "000001000000" report "Wrong Value Step 5" severity error; + wait for CLK_PERIOD; + assert random_sig = "000010000000" report "Wrong Value Step 6" severity error; + wait for CLK_PERIOD; + assert random_sig = "000100000000" report "Wrong Value Step 7" severity error; + wait for CLK_PERIOD; + assert random_sig = "001000000000" report "Wrong Value Step 8" severity error; + wait for CLK_PERIOD; + assert random_sig = "010000000000" report "Wrong Value Step 9" severity error; + wait for CLK_PERIOD; + assert random_sig = "100000000000" report "Wrong Value Step 10" severity error; + wait for CLK_PERIOD; + assert random_sig = "001000010001" report "Wrong Value Step 11" severity error; + wait for CLK_PERIOD; + assert random_sig = "010000100010" report "Wrong Value Step 12" severity error; + wait for CLK_PERIOD; + assert random_sig = "100001000100" report "Wrong Value Step 13" severity error; + wait for CLK_PERIOD; + assert random_sig = "001010011001" report "Wrong Value Step 14" severity error; + wait for CLK_PERIOD; + assert random_sig = "010100110010" report "Wrong Value Step 15" severity error; + wait for CLK_PERIOD; + assert random_sig = "101001100100" report "Wrong Value Step 16" severity error; + wait for CLK_PERIOD; + assert random_sig = "011011011001" report "Wrong Value Step 17" severity error; + wait for CLK_PERIOD; + assert random_sig = "110110110010" report "Wrong Value Step 18" severity error; + wait for CLK_PERIOD; + assert random_sig = "100101110101" report "Wrong Value Step 19" severity error; + wait for CLK_PERIOD; + assert random_sig = "000011111011" report "Wrong Value Step 20" severity error; + wait for CLK_PERIOD; + assert random_sig = "000111110110" report "Wrong Value Step 21" severity error; + report "End Test, seed: 000000000100"; + + report "Begin Test, reset, seed: 001010011101"; + wait for CLK_PERIOD; + seed_sig <= "001010011101"; + wait for 0 ns; -- Force Delta Step for past_rst to correctly assign + logic_reset_sig <= '1'; + wait for CLK_PERIOD * 5; + wait for 0 ns; -- Force Delta Step for past_rst to correctly assign + logic_reset_sig <= '0'; + + report "Begin Test, seed: 001010011101"; + wait for CLK_PERIOD; + assert random_sig = "001010011101" report "Wrong Value Step 1" severity error; + wait for CLK_PERIOD; + assert random_sig = "010100111010" report "Wrong Value Step 2" severity error; + wait for CLK_PERIOD; + assert random_sig = "101001110100" report "Wrong Value Step 3" severity error; + wait for CLK_PERIOD; + assert random_sig = "011011111001" report "Wrong Value Step 4" severity error; + wait for CLK_PERIOD; + assert random_sig = "110111110010" report "Wrong Value Step 5" severity error; + wait for CLK_PERIOD; + assert random_sig = "100111110101" report "Wrong Value Step 6" severity error; + wait for CLK_PERIOD; + assert random_sig = "000111111011" report "Wrong Value Step 7" severity error; + wait for CLK_PERIOD; + assert random_sig = "001111110110" report "Wrong Value Step 8" severity error; + wait for CLK_PERIOD; + assert random_sig = "011111101100" report "Wrong Value Step 9" severity error; + wait for CLK_PERIOD; + assert random_sig = "111111011000" report "Wrong Value Step 10" severity error; + wait for CLK_PERIOD; + assert random_sig = "110110100001" report "Wrong Value Step 11" severity error; + wait for CLK_PERIOD; + assert random_sig = "100101010011" report "Wrong Value Step 12" severity error; + wait for CLK_PERIOD; + assert random_sig = "000010110111" report "Wrong Value Step 13" severity error; + wait for CLK_PERIOD; + assert random_sig = "000101101110" report "Wrong Value Step 14" severity error; + wait for CLK_PERIOD; + assert random_sig = "001011011100" report "Wrong Value Step 15" severity error; + wait for CLK_PERIOD; + assert random_sig = "010110111000" report "Wrong Value Step 16" severity error; + wait for CLK_PERIOD; + assert random_sig = "101101110000" report "Wrong Value Step 17" severity error; + wait for CLK_PERIOD; + assert random_sig = "010011110001" report "Wrong Value Step 18" severity error; + wait for CLK_PERIOD; + assert random_sig = "100111100010" report "Wrong Value Step 19" severity error; + wait for CLK_PERIOD; + assert random_sig = "000111010101" report "Wrong Value Step 20" severity error; + wait for CLK_PERIOD; + assert random_sig = "001110101010" report "Wrong Value Step 21" severity error; + report "End Test, seed: 001010011101"; + + wait for CLK_PERIOD * 50; + + -- Simulation beenden + wait for CLK_PERIOD * 10; + std.env.stop; + end process; + + monitor : process (clk_sig) + begin + if rising_edge(clk_sig) then + random_sig_past <= random_sig; + past_rst <= logic_reset_sig; + -- Expect value to immediately reset but get the first random value only one clock after reset is gone + if (logic_reset_sig = '1' or past_rst = '1') and started = '1' then + assert random_sig = seed_sig report "Reset wrong: " & integer'image(to_integer(unsigned(random_sig))) & " should be: " & integer'image(to_integer(unsigned(seed_sig))) severity error; + else + assert random_sig /= seed_sig report "Random might be wrong: " & integer'image(to_integer(unsigned(random_sig))) & " should not be seed: " & integer'image(to_integer(unsigned(seed_sig))) severity warning; + assert random_sig /= random_sig_past report "Random wrong: " & integer'image(to_integer(unsigned(random_sig))) & " did not change from: " & integer'image(to_integer(unsigned(random_sig_past))) severity error; + end if; + end if; + end process; + +end testbench; + +-- LFSR REFERENCE WEBSITE: https://www.omnicalculator.com/math/linear-feedback-shift-register + +-- FOR SEED: 000000000100 +-- Message: 000000000100 at step 0 +-- Message: 000000001000 at step 1 +-- Message: 000000010000 at step 2 +-- Message: 000000100000 at step 3 +-- Message: 000001000000 at step 4 +-- Message: 000010000000 at step 5 +-- Message: 000100000000 at step 6 +-- Message: 001000000000 at step 7 +-- Message: 010000000000 at step 8 +-- Message: 100000000000 at step 9 +-- Message: 001000010001 at step 10 +-- Message: 010000100010 at step 11 +-- Message: 100001000100 at step 12 +-- Message: 001010011001 at step 13 +-- Message: 010100110010 at step 14 +-- Message: 101001100100 at step 15 +-- Message: 011011011001 at step 16 +-- Message: 110110110010 at step 17 +-- Message: 100101110101 at step 18 +-- Message: 000011111011 at step 19 +-- Message: 000111110110 at step 20 + +-- FOR SEED: 001010011101 +-- Message: 001010011101 at step 0 +-- Message: 010100111010 at step 1 +-- Message: 101001110100 at step 2 +-- Message: 011011111001 at step 3 +-- Message: 110111110010 at step 4 +-- Message: 100111110101 at step 5 +-- Message: 000111111011 at step 6 +-- Message: 001111110110 at step 7 +-- Message: 011111101100 at step 8 +-- Message: 111111011000 at step 9 +-- Message: 110110100001 at step 10 +-- Message: 100101010011 at step 11 +-- Message: 000010110111 at step 12 +-- Message: 000101101110 at step 13 +-- Message: 001011011100 at step 14 +-- Message: 010110111000 at step 15 +-- Message: 101101110000 at step 16 +-- Message: 010011110001 at step 17 +-- Message: 100111100010 at step 18 +-- Message: 000111010101 at step 19 +-- Message: 001110101010 at step 20 diff --git a/simulation files/VGA_tb.vhd b/simulation files/VGA_tb.vhd new file mode 100644 index 0000000..6b695e7 --- /dev/null +++ b/simulation files/VGA_tb.vhd @@ -0,0 +1,127 @@ +---------------------------------------------------------------------------------- +-- Company: ICT +-- Engineer: Daniel Fabian & Ulrich Paleček +-- +-- Create Date: 05/07/2026 05:09:06 PM +-- Design Name: Snake +-- Module Name: VGA_tb - Behavioral +-- Project Name: Snake +-- Target Devices: Nexys 4 DDR & Nexys A7 100T +-- Tool Versions: Vivado 2020+ +-- Description: Testbench for module VGA +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 1.0 - First working version +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +use work.local_types.all; + +entity VGA_tb is + -- Port ( ); +end VGA_tb; + +architecture testbench of VGA_tb is + constant CLK_PERIOD : time := 10 ns; + signal clk_sig : std_logic := '0'; + signal vga_clk_sig : std_logic := '0'; + signal next_pix_x_sig : std_ulogic_vector(9 downto 0); + signal next_pix_y_sig : std_ulogic_vector(9 downto 0); + signal last_next_pix_x_sig : std_ulogic_vector(9 downto 0) := (others => '0'); + signal last_next_pix_y_sig : std_ulogic_vector(9 downto 0) := (others => '0'); + signal pix_col_sig : color; + signal last_pix_col_sig : color; + signal VGA_R : std_ulogic_vector (3 downto 0); + signal VGA_G : std_ulogic_vector (3 downto 0); + signal VGA_B : std_ulogic_vector (3 downto 0); + signal VGA_HS : std_ulogic; + signal VGA_VS : std_ulogic; + +begin + + VGA_inst : entity work.vga + port map( + --clk + clk => clk_sig, + --pixel input + pxl_in => pix_col_sig, + --pixel request + next_pix_x => next_pix_x_sig, + next_pix_y => next_pix_y_sig, + --VGA Connector + VGA_R => VGA_R, + VGA_G => VGA_G, + VGA_B => VGA_B, + VGA_HS => VGA_HS, + VGA_VS => VGA_VS + ); + + clk_gen : process + begin + clk_sig <= '1'; + wait for CLK_PERIOD / 2; + clk_sig <= '0'; + wait for CLK_PERIOD / 2; + clk_sig <= '1'; + vga_clk_sig <= '1'; + wait for CLK_PERIOD / 2; + clk_sig <= '0'; + wait for CLK_PERIOD / 2; + clk_sig <= '1'; + wait for CLK_PERIOD / 2; + clk_sig <= '0'; + wait for CLK_PERIOD / 2; + clk_sig <= '1'; + vga_clk_sig <= '0'; + wait for CLK_PERIOD / 2; + clk_sig <= '0'; + wait for CLK_PERIOD / 2; + end process; + + -- -- Stimulus Prozess + stimulus : process + begin + -- Reset Phase + pix_col_sig.red <= "0010"; + pix_col_sig.green <= "0100"; + pix_col_sig.blue <= "0001"; + wait for CLK_PERIOD * 4 * 10; + pix_col_sig.red <= "1010"; + pix_col_sig.green <= "1100"; + pix_col_sig.blue <= "1001"; + wait for CLK_PERIOD * 4 * 646; + assert VGA_HS = '1' report "Horizontal Sync not high" severity error; + wait for CLK_PERIOD * 4; + assert VGA_HS = '0' report "Horizontal Sync not gone low" severity error; + wait for CLK_PERIOD * 4 * 95; + assert VGA_HS = '0' report "Horizontal Sync low too short" severity error; + wait for CLK_PERIOD * 4; + assert VGA_HS = '1' report "Horizontal Sync low too long" severity error; + wait for CLK_PERIOD * 4 * 46; + assert unsigned(next_pix_y_sig) = 1 report "Vertical addition wrong" severity error; + -- Simulation beenden + wait for CLK_PERIOD * 10000; + std.env.stop; + end process; + + monitor : process (vga_clk_sig) + begin + if rising_edge(vga_clk_sig) then + last_next_pix_x_sig <= next_pix_x_sig; + last_next_pix_y_sig <= next_pix_y_sig; + last_pix_col_sig <= pix_col_sig; + if UNSIGNED(next_pix_x_sig) < 640 and unsigned(next_pix_x_sig) > 0 then + assert unsigned(next_pix_x_sig) = (unsigned(last_next_pix_x_sig) + 1) report "Addition not working" severity error; + assert VGA_R = last_pix_col_sig.red and VGA_G = last_pix_col_sig.green and VGA_B = last_pix_col_sig.blue report "Wrong color to output" severity error; + end if; + end if; + end process; + +end testbench; diff --git a/source/Buttons.vhd b/source/Buttons.vhd new file mode 100644 index 0000000..70d6dcd --- /dev/null +++ b/source/Buttons.vhd @@ -0,0 +1,193 @@ +---------------------------------------------------------------------------------- +-- Company: ICT +-- Engineer: Daniel Fabian & Ulrich Paleček +-- +-- Create Date: 03/20/2026 02:28:52 PM +-- Design Name: Snake +-- Module Name: Buttons - Behavioral +-- Project Name: Snake +-- Target Devices: Nexys 4 DDR & Nexys A7 100T +-- Tool Versions: Vivado 2020+ +-- Description: Handle Buttoninput +-- +-- Dependencies: Snake project +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 1.0 - First working version +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +use work.local_types.all; + +entity Buttons is + port ( + clk : in std_ulogic; + tick : in std_ulogic; + reset : in std_ulogic; + button_up : in std_ulogic; + button_down : in std_ulogic; + button_left : in std_ulogic; + button_right : in std_ulogic; + direction : out direction_t; + button_pressed : out std_ulogic + ); +end Buttons; + +architecture Behavioral of Buttons is + + -- direction calculation and buttonpress + signal buttonpress : std_ulogic; + signal direction_reg : direction_t; + signal direction_pre_reg : direction_t; + + -- sync to clk + signal tick_d1 : std_ulogic; + signal tick_d2 : std_ulogic; + signal tick_rising : std_ulogic; + signal button_up_d1 : std_ulogic; + signal button_up_d2 : std_ulogic; + signal button_up_rising : std_ulogic; + signal button_up_falling : std_ulogic; + signal button_down_d1 : std_ulogic; + signal button_down_d2 : std_ulogic; + signal button_down_rising : std_ulogic; + signal button_down_falling : std_ulogic; + signal button_left_d1 : std_ulogic; + signal button_left_d2 : std_ulogic; + signal button_left_rising : std_ulogic; + signal button_left_falling : std_ulogic; + signal button_right_d1 : std_ulogic; + signal button_right_d2 : std_ulogic; + signal button_right_rising : std_ulogic; + signal button_right_falling : std_ulogic; + + -- debouncing for buttons + signal lockout_up : std_ulogic := '0'; + signal lockout_down : std_ulogic := '0'; + signal lockout_left : std_ulogic := '0'; + signal lockout_right : std_ulogic := '0'; + signal counter_up : unsigned(16 downto 0) := (others => '0'); + signal counter_down : unsigned(16 downto 0) := (others => '0'); + signal counter_left : unsigned(16 downto 0) := (others => '0'); + signal counter_right : unsigned(16 downto 0) := (others => '0'); + +begin + + sync_tick : process (clk) + begin + if rising_edge(clk) then + tick_d1 <= tick; + tick_d2 <= tick_d1; + end if; + end process sync_tick; + + tick_rising <= tick_d1 and not tick_d2; + + sync_buttons : process (clk) + begin + if rising_edge(clk) then + button_up_d1 <= button_up; + button_up_d2 <= button_up_d1; + button_down_d1 <= button_down; + button_down_d2 <= button_down_d1; + button_left_d1 <= button_left; + button_left_d2 <= button_left_d1; + button_right_d1 <= button_right; + button_right_d2 <= button_right_d1; + end if; + end process sync_buttons; + + button_up_rising <= button_up_d1 and not button_up_d2; + button_down_rising <= button_down_d1 and not button_down_d2; + button_left_rising <= button_left_d1 and not button_left_d2; + button_right_rising <= button_right_d1 and not button_right_d2; + + button_up_falling <= not button_up_d1 and button_up_d2; + button_down_falling <= not button_down_d1 and button_down_d2; + button_left_falling <= not button_left_d1 and button_left_d2; + button_right_falling <= not button_right_d1 and button_right_d2; + + debouncer : process (clk) + begin + if rising_edge(clk) then + if button_up_falling = '1' then + lockout_up <= '1'; + counter_up <= (others => '0'); + elsif counter_up = "1111111111111111" then + lockout_up <= '0'; + else + counter_up <= counter_up + 1; + end if; + if button_down_falling = '1' then + lockout_down <= '1'; + counter_down <= (others => '0'); + elsif counter_down = "1111111111111111" then + lockout_down <= '0'; + else + counter_down <= counter_down + 1; + end if; + if button_left_falling = '1' then + lockout_left <= '1'; + counter_left <= (others => '0'); + elsif counter_left = "1111111111111111" then + lockout_left <= '0'; + else + counter_left <= counter_left + 1; + end if; + if button_right_falling = '1' then + lockout_right <= '1'; + counter_right <= (others => '0'); + elsif counter_right = "1111111111111111" then + lockout_right <= '0'; + else + counter_right <= counter_right + 1; + end if; + end if; + end process debouncer; + + prepare_direction : process (clk) + begin + if rising_edge(clk) then + if button_up_rising = '1' and lockout_up = '0' then + direction_pre_reg <= UP; + elsif button_down_rising = '1' and lockout_down = '0' then + direction_pre_reg <= DOWN; + elsif button_left_rising = '1' and lockout_left = '0' then + direction_pre_reg <= LEFT; + elsif button_right_rising = '1' and lockout_right = '0' then + direction_pre_reg <= RIGHT; + else + direction_pre_reg <= direction_pre_reg; + end if; + end if; + end process prepare_direction; + + buttonpress_process : process (clk, reset) + begin + if reset = '1' then + buttonpress <= '0'; + elsif rising_edge(clk) then + if button_up_rising = '1' or button_down_rising = '1' or button_left_rising = '1' or button_right_rising = '1' then + buttonpress <= '1'; + end if; + end if; + end process buttonpress_process; + + direction_process : process (clk) + begin + if rising_edge(clk) then + if tick_rising = '1' then + direction_reg <= direction_pre_reg; + end if; + end if; + end process direction_process; + + direction <= direction_reg; + button_pressed <= buttonpress; + +end Behavioral; diff --git a/source/GameArea.vhd b/source/GameArea.vhd new file mode 100644 index 0000000..4b4fa24 --- /dev/null +++ b/source/GameArea.vhd @@ -0,0 +1,142 @@ +---------------------------------------------------------------------------------- +-- Company: ICT +-- Engineer: Daniel Fabian & Ulrich Paleček +-- +-- Create Date: 03/20/2026 02:28:52 PM +-- Design Name: Snake +-- Module Name: GameArea - Behavioral +-- Project Name: Snake +-- Target Devices: Nexys 4 DDR & Nexys A7 100T +-- Tool Versions: Vivado 2020+ +-- Description: Handle the GameArea +-- +-- Dependencies: Snake project +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 1.0 - First working version +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +use work.local_types.all; + +entity GameArea is + generic ( + AREAWIDTH : natural := 64; + AREAHEIGHT : natural := 48; + VGAx : natural := 640; + VGAy : natural := 480 + ); + port ( + --clk just because + clk : in std_ulogic; + --interface for vga + next_pix_x : in std_ulogic_vector (9 downto 0); + next_pix_y : in std_ulogic_vector (9 downto 0); + pix_col : out color; + --signal for reset + rst_game : in std_ulogic; + --gamearea manipulation/information interface + tile_coord : in coordinate_t; + tile_from_GA : out game_tile; + tile_to_GA : in game_tile; + set_tile : in std_ulogic; + --gamesstate information + head_pos_out : out coordinate_t; + tail_pos_out : out coordinate_t; + apple_placed : out std_ulogic + ); +end GameArea; + +architecture Behavioral of GameArea is + signal head_pos : coordinate_t; + signal tail_pos : coordinate_t; + signal apple_pos : coordinate_t; + signal sig_apple_placed : std_ulogic; + signal vga_tile_x : std_ulogic_vector(5 downto 0); + signal vga_tile_y : std_ulogic_vector(5 downto 0); + signal vga_tile : game_tile; + +begin + + head_pos_out <= head_pos; + tail_pos_out <= tail_pos; + apple_placed <= sig_apple_placed; + + vga_tile_x <= std_ulogic_vector(to_unsigned((to_integer(unsigned(next_pix_x)) * AREAWIDTH) / VGAx, 6)); + vga_tile_y <= std_ulogic_vector(to_unsigned((to_integer(unsigned(next_pix_y)) * AREAHEIGHT) / VGAy, 6)); + + game_tiles : entity work.Game_tile_storage + port map( + clk => clk, + reset => rst_game, + --interface for VGA read + VGA_coord.x => vga_tile_x, + VGA_coord.y => vga_tile_y, + VGA_Tile_out => vga_tile, + --interface for read/write + tile_coord => tile_coord, + set_tile => set_tile, + tile_to_GA => tile_to_GA, + tile_from_GA => tile_from_GA--; + + ); + + tile_process : process (clk) + begin + if rising_edge(clk) then + if set_tile = '1' and rst_game = '0' then + if tile_to_GA.is_tail = '1' and set_tile = '1' then + tail_pos.x <= tile_coord.x; + tail_pos.y <= tile_coord.y; + elsif tile_to_GA.is_head = '1' and set_tile = '1' then + head_pos.x <= tile_coord.x; + head_pos.y <= tile_coord.y; + if tile_coord.x = apple_pos.x and tile_coord.y = apple_pos.y then + sig_apple_placed <= '0'; + end if; + elsif tile_to_GA.is_apple = '1' and set_tile = '1' then + apple_pos.x <= tile_coord.x; + apple_pos.y <= tile_coord.y; + sig_apple_placed <= '1'; + end if; + end if; + end if; + end process tile_process; + + vga_out : process (clk) + begin + if rising_edge(clk) then + + if vga_tile.is_head = '1' then + pix_col.red <= "0000"; + pix_col.green <= "1111"; + pix_col.blue <= "0000"; + elsif vga_tile.is_tail = '1' then + pix_col.red <= "0000"; + pix_col.green <= "0000"; + pix_col.blue <= "1111"; + elsif vga_tile.is_apple = '1' then + pix_col.red <= "1111"; + pix_col.green <= "0000"; + pix_col.blue <= "0000"; + elsif vga_tile.is_body = '1' then + pix_col.red <= "1111"; + pix_col.green <= "1111"; + pix_col.blue <= "1111"; + else + pix_col.red <= "0010"; + pix_col.green <= "0010"; + pix_col.blue <= "0010"; + + end if; + + end if; + + end process vga_out; + +end Behavioral; diff --git a/source/GameAreaMux.vhd b/source/GameAreaMux.vhd new file mode 100644 index 0000000..324961c --- /dev/null +++ b/source/GameAreaMux.vhd @@ -0,0 +1,79 @@ +---------------------------------------------------------------------------------- +-- Company: ICT +-- Engineer: Daniel Fabian & Ulrich Paleček +-- +-- Create Date: 03/20/2026 02:28:52 PM +-- Design Name: Snake +-- Module Name: GameAreaMux - Behavioral +-- Project Name: Snake +-- Target Devices: Nexys 4 DDR & Nexys A7 100T +-- Tool Versions: Vivado 2020+ +-- Description: Multiplex the Gamearea Interface +-- +-- Dependencies: Snake project +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 1.0 - First working version +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +use work.local_types.all; + +entity GameAreaMux is + generic ( + NumInterfaces : natural := 1 + ); + + port ( + GameAreaPort : inout GameAreaInterface; + SelectionPort : inout GameAreaInterfaceVector(NumInterfaces - 1 downto 0); + Selection : in std_ulogic_vector(NumInterfaces - 1 downto 0) + + ); +end GameAreaMux; + +architecture Behavioral of GameAreaMux is + + -- Default/idle values for the GameArea bus + constant origin : coordinate_t := ( + x => (others => '0'), + y => (others => '0') + ); + + constant empty_tile : game_tile := ( + is_tail => '0', + is_head => '0', + is_apple => '0', + is_body => '0', + parent => origin + ); + +begin + + mux_proc : process (Selection, SelectionPort) + begin + GameAreaPort.tile_coord <= origin; + GameAreaPort.tile_to_GA <= empty_tile; + GameAreaPort.set_tile <= '0'; + + for i in 0 to NumInterfaces - 1 loop + if Selection(i) = '1' then + GameAreaPort.tile_coord <= SelectionPort(i).tile_coord; + GameAreaPort.tile_to_GA <= SelectionPort(i).tile_to_GA; + GameAreaPort.set_tile <= SelectionPort(i).set_tile; + end if; + end loop; + end process mux_proc; + + outputs : for i in 0 to NumInterfaces - 1 generate + + SelectionPort(i).tile_from_GA <= GameAreaPort.tile_from_GA when Selection(i) = '1' + else + empty_tile; + end generate; +end Behavioral; diff --git a/source/Game_tile_storage.vhd b/source/Game_tile_storage.vhd new file mode 100644 index 0000000..99d4b91 --- /dev/null +++ b/source/Game_tile_storage.vhd @@ -0,0 +1,563 @@ +---------------------------------------------------------------------------------- +-- Company: ICT +-- Engineer: Daniel Fabian & Ulrich Paleček +-- +-- Create Date: 03/23/2026 06:01:20 PM +-- Design Name: Snake +-- Module Name: Game_tile_storage - Behavioral +-- Project Name: Snake +-- Target Devices: Nexys 4 DDR & Nexys A7 100T +-- Tool Versions: Vivado 2020+ +-- Description: Store Gametiles in BRAM +-- +-- Dependencies: Snake project +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 1.0 - First working version +-- Additional Comments: +-- +---------------------------------------------------------------------------------- +library IEEE; +library UNISIM; +library UNIMACRO; +use IEEE.STD_LOGIC_1164.all; +use UNISIM.vcomponents.all; +use UNIMACRO.vcomponents.all; +use work.local_types.all; + +entity Game_tile_storage is + port ( + clk : in std_ulogic; + reset : in std_ulogic; + --interface for VGA read + VGA_coord : in coordinate_t; + VGA_Tile_out : out game_tile; + --interface for read/write + tile_coord : in coordinate_t; + set_tile : in std_ulogic; + tile_to_GA : in game_tile; + tile_from_GA : out game_tile--; + + ); +end Game_tile_storage; + +architecture Behavioral of Game_tile_storage is + + -- VGA Interface + signal vga_address : std_ulogic_vector(11 downto 0) := (others => '0'); + signal PortB_address1 : std_ulogic_vector(10 downto 0) := (others => '0'); + signal PortB_address2 : std_ulogic_vector(10 downto 0) := (others => '0'); + signal PortB_data_out1 : std_ulogic_vector(17 downto 0) := (others => '0'); + signal PortB_data_out2 : std_ulogic_vector(17 downto 0) := (others => '0'); + signal vga_enable1 : std_ulogic; + signal vga_enable2 : std_ulogic; + signal vga_data_out1 : game_tile; + signal vga_data_out2 : game_tile; + + -- Gamearea Interface + signal Logic_address : std_ulogic_vector(11 downto 0) := (others => '0'); + signal PortA_address1 : std_ulogic_vector(10 downto 0) := (others => '0'); + signal PortA_address2 : std_ulogic_vector(10 downto 0) := (others => '0'); + signal PortA_data_out1 : std_ulogic_vector(17 downto 0) := (others => '0'); + signal PortA_data_out2 : std_ulogic_vector(17 downto 0) := (others => '0'); + signal PortA_data_in1 : std_ulogic_vector(17 downto 0) := (others => '0'); + signal PortA_data_in2 : std_ulogic_vector(17 downto 0) := (others => '0'); + signal logic_enable1 : std_ulogic; + signal logic_enable2 : std_ulogic; + signal logic_write1 : std_ulogic_vector(1 downto 0) := (others => '0'); + signal logic_write2 : std_ulogic_vector(1 downto 0) := (others => '0'); + signal logic_data_out1 : game_tile; + signal logic_data_out2 : game_tile; + signal data_in : std_ulogic_vector(17 downto 0) := (others => '0'); + signal zero_input : std_ulogic_vector(17 downto 0) := (others => '0'); + + -- Outputpipes + signal logic_enable_pipe : std_ulogic_vector(1 downto 0) := (others => '0'); + signal vga_enable_pipe : std_ulogic_vector(1 downto 0) := (others => '0'); + +begin + vga_address (11 downto 6) <= VGA_coord.x; + vga_address (5 downto 0) <= VGA_coord.y; + + vga_enable1 <= '1'; + vga_enable2 <= '1'; + + Logic_address (11 downto 6) <= tile_coord.x; + Logic_address (5 downto 0) <= tile_coord.y; + + PortA_address1 <= Logic_address(10 downto 0); + PortA_address2 <= Logic_address(10 downto 0); + + PortB_address1 <= vga_address(10 downto 0); + PortB_address2 <= vga_address(10 downto 0); + + logic_enable1 <= not Logic_address(11) or not set_tile; + logic_enable2 <= Logic_address(11) or not set_tile; + + logic_write1(1) <= (not Logic_address(11)) and set_tile; + logic_write1(0) <= (not Logic_address(11)) and set_tile; + + logic_write2(1) <= Logic_address(11) and set_tile; + logic_write2(0) <= Logic_address(11) and set_tile; + + data_in(17) <= tile_to_GA.is_tail; + data_in(16) <= tile_to_GA.is_head; + data_in(15) <= tile_to_GA.is_apple; + data_in(14) <= tile_to_GA.is_body; + data_in(13) <= '0'; + data_in(12) <= '0'; + data_in(11 downto 6) <= tile_to_GA.parent.x; + data_in(5 downto 0) <= tile_to_GA.parent.y; + + vga_data_out1.is_tail <= PortB_data_out1(17); + vga_data_out1.is_head <= PortB_data_out1(16); + vga_data_out1.is_apple <= PortB_data_out1(15); + vga_data_out1.is_body <= PortB_data_out1(14); + vga_data_out1.parent.x <= PortB_data_out1(11 downto 6); + vga_data_out1.parent.y <= PortB_data_out1(5 downto 0); + + vga_data_out2.is_tail <= PortB_data_out2(17); + vga_data_out2.is_head <= PortB_data_out2(16); + vga_data_out2.is_apple <= PortB_data_out2(15); + vga_data_out2.is_body <= PortB_data_out2(14); + vga_data_out2.parent.x <= PortB_data_out2(11 downto 6); + vga_data_out2.parent.y <= PortB_data_out2(5 downto 0); + + logic_data_out1.is_tail <= PortA_data_out1(17); + logic_data_out1.is_head <= PortA_data_out1(16); + logic_data_out1.is_apple <= PortA_data_out1(15); + logic_data_out1.is_body <= PortA_data_out1(14); + logic_data_out1.parent.x <= PortA_data_out1(11 downto 6); + logic_data_out1.parent.y <= PortA_data_out1(5 downto 0); + + logic_data_out2.is_tail <= PortA_data_out2(17); + logic_data_out2.is_head <= PortA_data_out2(16); + logic_data_out2.is_apple <= PortA_data_out2(15); + logic_data_out2.is_body <= PortA_data_out2(14); + logic_data_out2.parent.x <= PortA_data_out2(11 downto 6); + logic_data_out2.parent.y <= PortA_data_out2(5 downto 0); + + PortA_data_in1 <= data_in when (Logic_address(11) = '0' and set_tile = '1') else + zero_input; + PortA_data_in2 <= data_in when (Logic_address(11) = '1' and set_tile = '1') else + zero_input; + -- BRAM_TDP_MACRO: True Dual Port RAM + -- Artix-7 + -- Xilinx HDL Language Template, version 2025.2 + + -- Note - This Unimacro model assumes the port directions to be "downto". + -- Simulation of this model with "to" in the port directions could lead to erroneous results. + + -------------------------------------------------------------------------- + -- DATA_WIDTH_A/B | BRAM_SIZE | RAM Depth | ADDRA/B Width | WEA/B Width -- + -- ===============|===========|===========|===============|=============-- + -- 19-36 | "36Kb" | 1024 | 10-bit | 4-bit -- + -- 10-18 | "36Kb" | 2048 | 11-bit | 2-bit -- + -- 10-18 | "18Kb" | 1024 | 10-bit | 2-bit -- + -- 5-9 | "36Kb" | 4096 | 12-bit | 1-bit -- + -- 5-9 | "18Kb" | 2048 | 11-bit | 1-bit -- + -- 3-4 | "36Kb" | 8192 | 13-bit | 1-bit -- + -- 3-4 | "18Kb" | 4096 | 12-bit | 1-bit -- + -- 2 | "36Kb" | 16384 | 14-bit | 1-bit -- + -- 2 | "18Kb" | 8192 | 13-bit | 1-bit -- + -- 1 | "36Kb" | 32768 | 15-bit | 1-bit -- + -- 1 | "18Kb" | 16384 | 14-bit | 1-bit -- + -------------------------------------------------------------------------- + BRAM_TDP_MACRO1_inst : BRAM_TDP_MACRO + generic map( + BRAM_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb" + DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6" + DOA_REG => 1, -- Optional port A output register (0 or 1) <- 1: Add Pipepline stage, ready at next clk - test this + DOB_REG => 1, -- Optional port B output register (0 or 1) + INIT_A => X"000000000", -- Initial values on A output port + INIT_B => X"000000000", -- Initial values on B output port + INIT_FILE => "NONE", + READ_WIDTH_A => 18, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") + READ_WIDTH_B => 18, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") + SIM_COLLISION_CHECK => "ALL", -- Collision check enable "ALL", "WARNING_ONLY", + -- "GENERATE_X_ONLY" or "NONE" + SRVAL_A => X"000000000", -- Set/Reset value for A port output + SRVAL_B => X"000000000", -- Set/Reset value for B port output + WRITE_MODE_A => "WRITE_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE" + WRITE_MODE_B => "READ_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE" + WRITE_WIDTH_A => 18, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") + WRITE_WIDTH_B => 18, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") + -- The following INIT_xx declarations specify the initial contents of the RAM + INIT_00 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000", + + -- The next set of INIT_xx are valid when configured as 36Kb + INIT_40 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_41 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_42 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_43 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_44 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_45 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_46 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_47 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_48 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_49 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_4A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_4B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_4C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_4D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_4E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_4F => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_50 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_51 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_52 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_53 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_54 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_55 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_56 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_57 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_58 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_59 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_5A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_5B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_5C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_5D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_5E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_5F => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_60 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_61 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_62 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_63 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_64 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_65 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_66 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_67 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_68 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_69 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_6A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_6B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_6C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_6D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_6E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_6F => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_70 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_71 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_72 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_73 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_74 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_75 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_76 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_77 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_78 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_79 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_7A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_7B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_7C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_7D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_7E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_7F => X"0000000000000000000000000000000000000000000000000000000000000000", + + -- The next set of INITP_xx are for the parity bits + INITP_00 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000", + + -- The next set of INIT_xx are valid when configured as 36Kb + INITP_08 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_09 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_0A => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_0B => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_0C => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_0D => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_0E => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_0F => X"0000000000000000000000000000000000000000000000000000000000000000") + port map( + DOA => PortA_data_out1, -- Output port-A data, width defined by READ_WIDTH_A parameter + DOB => PortB_data_out1, -- Output port-B data, width defined by READ_WIDTH_B parameter + ADDRA => PortA_address1, -- Input port-A address, width defined by Port A depth + ADDRB => PortB_address1, -- Input port-B address, width defined by Port B depth + CLKA => clk, -- 1-bit input port-A clock + CLKB => clk, -- 1-bit input port-B clock + DIA => PortA_data_in1, -- Input port-A data, width defined by WRITE_WIDTH_A parameter + DIB => zero_input, -- Input port-B data, width defined by WRITE_WIDTH_B parameter + ENA => logic_enable1, -- 1-bit input port-A enable + ENB => vga_enable1, -- 1-bit input port-B enable + REGCEA => logic_enable1, -- 1-bit input port-A output register enable + REGCEB => vga_enable1, -- 1-bit input port-B output register enable + RSTA => reset, -- 1-bit input port-A reset + RSTB => reset, -- 1-bit input port-B reset + WEA => logic_write1, -- Input port-A write enable, width defined by Port A depth + WEB => "00" -- Input port-B write enable, width defined by Port B depth + ); + + -- End of BRAM_TDP_MACRO_inst instantiation + BRAM_TDP_MACRO_inst : BRAM_TDP_MACRO + generic map( + BRAM_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb" + DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6" + DOA_REG => 1, -- Optional port A output register (0 or 1) + DOB_REG => 1, -- Optional port B output register (0 or 1) + INIT_A => X"000000000", -- Initial values on A output port + INIT_B => X"000000000", -- Initial values on B output port + INIT_FILE => "NONE", + READ_WIDTH_A => 18, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") + READ_WIDTH_B => 18, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") + SIM_COLLISION_CHECK => "ALL", -- Collision check enable "ALL", "WARNING_ONLY", + -- "GENERATE_X_ONLY" or "NONE" + SRVAL_A => X"000000000", -- Set/Reset value for A port output + SRVAL_B => X"000000000", -- Set/Reset value for B port output + WRITE_MODE_A => "WRITE_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE" + WRITE_MODE_B => "WRITE_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE" + WRITE_WIDTH_A => 18, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") + WRITE_WIDTH_B => 18, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") + -- The following INIT_xx declarations specify the initial contents of the RAM + INIT_00 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000", + + -- The next set of INIT_xx are valid when configured as 36Kb + INIT_40 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_41 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_42 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_43 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_44 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_45 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_46 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_47 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_48 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_49 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_4A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_4B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_4C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_4D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_4E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_4F => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_50 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_51 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_52 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_53 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_54 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_55 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_56 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_57 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_58 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_59 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_5A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_5B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_5C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_5D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_5E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_5F => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_60 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_61 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_62 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_63 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_64 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_65 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_66 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_67 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_68 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_69 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_6A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_6B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_6C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_6D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_6E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_6F => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_70 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_71 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_72 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_73 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_74 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_75 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_76 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_77 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_78 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_79 => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_7A => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_7B => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_7C => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_7D => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_7E => X"0000000000000000000000000000000000000000000000000000000000000000", + INIT_7F => X"0000000000000000000000000000000000000000000000000000000000000000", + + -- The next set of INITP_xx are for the parity bits + INITP_00 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000", + + -- The next set of INIT_xx are valid when configured as 36Kb + INITP_08 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_09 => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_0A => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_0B => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_0C => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_0D => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_0E => X"0000000000000000000000000000000000000000000000000000000000000000", + INITP_0F => X"0000000000000000000000000000000000000000000000000000000000000000") + port map( + DOA => PortA_data_out2, -- Output port-A data, width defined by READ_WIDTH_A parameter + DOB => PortB_data_out2, -- Output port-B data, width defined by READ_WIDTH_B parameter + ADDRA => PortA_address2, -- Input port-A address, width defined by Port A depth + ADDRB => PortB_address2, -- Input port-B address, width defined by Port B depth + CLKA => clk, -- 1-bit input port-A clock + CLKB => clk, -- 1-bit input port-B clock + DIA => PortA_data_in2, -- Input port-A data, width defined by WRITE_WIDTH_A parameter + DIB => zero_input, -- Input port-B data, width defined by WRITE_WIDTH_B parameter + ENA => logic_enable2, -- 1-bit input port-A enable + ENB => vga_enable2, -- 1-bit input port-B enable + REGCEA => logic_enable2, -- 1-bit input port-A output register enable + REGCEB => vga_enable2, -- 1-bit input port-B output register enable + RSTA => reset, -- 1-bit input port-A reset + RSTB => reset, -- 1-bit input port-B reset + WEA => logic_write2, -- Input port-A write enable, width defined by Port A depth + WEB => "00" -- Input port-B write enable, width defined by Port B depth + ); + + -- End of BRAM_TDP_MACRO_inst instantiation + + output_pipe : process (clk) + begin + if rising_edge(clk) then + + tile_from_GA <= logic_data_out1 when logic_enable_pipe(1) = '1' else + logic_data_out2; + + VGA_Tile_out <= vga_data_out1 when vga_enable_pipe(1) = '1' else + vga_data_out2; + + logic_enable_pipe <= logic_enable_pipe(0) & not Logic_address(11); + vga_enable_pipe <= vga_enable_pipe(0) & not vga_address(11); + end if; + end process output_pipe; + +end Behavioral; diff --git a/source/Gamelogic.vhd b/source/Gamelogic.vhd new file mode 100644 index 0000000..52a79e5 --- /dev/null +++ b/source/Gamelogic.vhd @@ -0,0 +1,25 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.all; +entity Gamelogic is + port ( + clk : in std_ulogic; --100 MHz * 10 = 1 GHz / 125 = 8 MHz / 125 = 64 kHz + tick : in std_ulogic; + button_pressed : in std_ulogic; + reset : in std_ulogic; + run_reset : out std_ulogic; + run_init : out std_ulogic; + run_head : out std_ulogic; + run_tail : out std_ulogic; + run_apples : out std_ulogic; + reset_done : in std_ulogic; + init_done : in std_ulogic; + head_done : in std_ulogic; + tail_done : in std_ulogic; + apples_done : in std_ulogic; + head_death : in std_ulogic + ); +end Gamelogic; + +architecture Behavioral of Gamelogic is + +end Behavioral; diff --git a/source/Gametick.vhd b/source/Gametick.vhd new file mode 100644 index 0000000..6cc58a3 --- /dev/null +++ b/source/Gametick.vhd @@ -0,0 +1,56 @@ +---------------------------------------------------------------------------------- +-- Company: ICT +-- Engineer: Daniel Fabian & Ulrich Paleček +-- +-- Create Date: 03/20/2026 02:28:52 PM +-- Design Name: Snake +-- Module Name: Gametick - Behavioral +-- Project Name: Snake +-- Target Devices: Nexys 4 DDR & Nexys A7 100T +-- Tool Versions: Vivado 2020+ +-- Description: Create slower clock for Gamelogic +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 1.0 - First working version +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +entity Gametick is + port ( + clk : in std_ulogic; --100 MHz * 10 = 1 GHz / 125 = 8 MHz / 125 = 64 kHz + tick : out std_ulogic + ); +end Gametick; + +architecture Behavioral of Gametick is + + signal counter : unsigned(12 downto 0) := (others => '0'); + signal tickgen : std_ulogic := '0'; +begin + + --Target: 10 Hz + --Input 64 kHz + --64 kHz / 10 Hz = 6400 + --Toggle every 3200 + tick_process : process (clk) + begin + if rising_edge(clk) then + if counter = 3199 then + counter <= (others => '0'); + tickgen <= not tickgen; + else + counter <= counter + 1; + end if; + end if; + end process tick_process; + + tick <= tickgen; + +end Behavioral; diff --git a/source/Head.vhd b/source/Head.vhd new file mode 100644 index 0000000..3f77972 --- /dev/null +++ b/source/Head.vhd @@ -0,0 +1,31 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +use work.local_types.all; + +entity Head is + generic ( + AREAWIDTH : natural := 64; + AREAHEIGHT : natural := 48 + ); + port ( + clk : in std_ulogic; + run_head : in std_ulogic; + head_done : out std_ulogic; + head_death : out std_ulogic; + reset : in std_ulogic; + --gamearea manipulation/information interface + tile_coord : out coordinate_t; + tile_from_GA : in game_tile; + tile_to_GA : out game_tile; + set_tile : out std_ulogic; + --gamesstate information + head_pos : in coordinate_t; + --button direction + direction : in direction_t + ); +end Head; + +architecture Behavioral of Head is + +end Behavioral; diff --git a/source/LFSR.vhd b/source/LFSR.vhd new file mode 100644 index 0000000..dbbbb53 --- /dev/null +++ b/source/LFSR.vhd @@ -0,0 +1,25 @@ + +library IEEE; +use IEEE.STD_LOGIC_1164.all; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity LFSR is + port ( + clk : in std_ulogic; + reset : in std_ulogic; + seed : in std_ulogic_vector(11 downto 0); + random : out std_ulogic_vector(11 downto 0) + ); +end LFSR; + +architecture Behavioral of LFSR is + +end Behavioral; diff --git a/source/Score.vhd b/source/Score.vhd new file mode 100644 index 0000000..c068d8e --- /dev/null +++ b/source/Score.vhd @@ -0,0 +1,190 @@ +---------------------------------------------------------------------------------- +-- Company: ICT +-- Engineer: Daniel Fabian & Ulrich Paleček +-- +-- Create Date: 04/12/2026 05:43:50 PM +-- Design Name: Snake +-- Module Name: Score - Behavioral +-- Project Name: Snake +-- Target Devices: Nexys 4 DDR & Nexys A7 100T +-- Tool Versions: Vivado 2020+ +-- Description: Count Scores for lifetime and apple intake / 7-Segment-Control +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 1.0 - First working version +-- Additional Comments: +-- +---------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +use work.local_types.all; + +entity Score is + port ( + clk : in std_ulogic; + slow_clk : in std_ulogic; + reset : in std_ulogic; + apple_placed : in std_ulogic; + tick : in std_ulogic; + SEG : out std_ulogic_vector (6 downto 0); + DP : out std_ulogic; + AN : out std_ulogic_vector (7 downto 0) + ); +end Score; + +architecture Behavioral of Score is + signal HEX : std_ulogic_vector(3 downto 0); + signal LED : std_ulogic_vector(6 downto 0); + signal applescore : gamescore; + signal timescore : gamescore; + signal count : std_ulogic_vector (2 downto 0); + + signal tick_d1 : std_ulogic; + signal tick_d2 : std_ulogic; + signal tick_rising : std_ulogic; + signal slow_clk_d1 : std_ulogic; + signal slow_clk_d2 : std_ulogic; + signal slow_clk_rising : std_ulogic; + signal apple_d1 : std_ulogic; + signal apple_d2 : std_ulogic; + signal apple_falling : std_ulogic; + +begin + --HEX-to-seven-segment decoder + -- HEX: in STD_LOGIC_VECTOR (3 downto 0); + -- LED: out STD_LOGIC_VECTOR (6 downto 0); + -- + -- segment encoinputg + -- 0 + -- --- + -- 5 | | 1 + -- --- <- 6 + -- 4 | | 2 + -- --- + -- 3 + + DP <= '1'; + SEG <= LED; + + sync : process (clk) + begin + if rising_edge(clk) then + tick_d1 <= tick; + tick_d2 <= tick_d1; + apple_d1 <= apple_placed; + apple_d2 <= apple_d1; + slow_clk_d1 <= slow_clk; + slow_clk_d2 <= slow_clk_d1; + end if; + end process sync; + + tick_rising <= tick_d1 and not tick_d2; + slow_clk_rising <= slow_clk_d1 and not slow_clk_d2; + apple_falling <= not apple_d1 and apple_d2; + + scoreoutput : process (clk, reset) + begin + if reset = '1' then + count <= "000"; + elsif rising_edge(clk) and slow_clk_rising = '1' then + with count select + AN <= "11111110" when "000", + "11111101" when "001", + "11111011" when "010", + "11110111" when "011", + "11101111" when "100", + "11011111" when "101", + "10111111" when "110", + "01111111" when "111", + "11111111" when others; + with count select + HEX <= applescore.a when "000", + applescore.b when "001", + applescore.c when "010", + applescore.d when "011", + timescore.a when "100", + timescore.b when "101", + timescore.c when "110", + timescore.d when "111", + "0000" when others; + count <= std_ulogic_vector(unsigned(count) + 1); + end if; + end process scoreoutput; + + with HEX select + LED <= "1111001" when "0001", --1 + "0100100" when "0010", --2 + "0110000" when "0011", --3 + "0011001" when "0100", --4 + "0010010" when "0101", --5 + "0000010" when "0110", --6 + "1111000" when "0111", --7 + "0000000" when "1000", --8 + "0010000" when "1001", --9 + "0001000" when "1010", --A + "0000011" when "1011", --b + "1000110" when "1100", --C + "0100001" when "1101", --d + "0000110" when "1110", --E + "0001110" when "1111", --F + "1000000" when others; --0 + + timescore_process : process (clk, reset) + begin + if reset = '1' then + timescore.a <= (others => '0'); + timescore.b <= (others => '0'); + timescore.c <= (others => '0'); + timescore.d <= (others => '0'); + elsif rising_edge(clk) and tick_rising = '1' then + if timescore.a = "1001" then + timescore.a <= "0000"; + if timescore.b = "1001" then + timescore.b <= "0000"; + if timescore.c = "1001" then + timescore.c <= "0000"; + timescore.d <= std_ulogic_vector(unsigned(timescore.d) + 1); + else + timescore.c <= std_ulogic_vector(unsigned(timescore.c) + 1); + end if; + else + timescore.b <= std_ulogic_vector(unsigned(timescore.b) + 1); + end if; + else + timescore.a <= std_ulogic_vector(unsigned(timescore.a) + 1); + end if; + end if; + end process timescore_process; + + applescore_process : process (clk, reset) + begin + if reset = '1' then + applescore.a <= (others => '0'); + applescore.b <= (others => '0'); + applescore.c <= (others => '0'); + applescore.d <= (others => '0'); + elsif rising_edge(clk) and apple_falling = '1' then + if applescore.a = "1001" then + applescore.a <= "0000"; + if applescore.b = "1001" then + applescore.b <= "0000"; + if applescore.c = "1001" then + applescore.c <= "0000"; + applescore.d <= std_ulogic_vector(unsigned(applescore.d) + 1); + else + applescore.c <= std_ulogic_vector(unsigned(applescore.c) + 1); + end if; + else + applescore.b <= std_ulogic_vector(unsigned(applescore.b) + 1); + end if; + else + applescore.a <= std_ulogic_vector(unsigned(applescore.a) + 1); + end if; + end if; + end process applescore_process; + +end Behavioral; diff --git a/source/Tail.vhd b/source/Tail.vhd new file mode 100644 index 0000000..e9e82e6 --- /dev/null +++ b/source/Tail.vhd @@ -0,0 +1,5 @@ +library IEEE;use IEEE.STD_LOGIC_1164.all;use IEEE.NUMERIC_STD.all;use work.local_types.all; + +entity Tail is port(clk:in std_ulogic;start_tail:in std_ulogic;tail_done:out std_ulogic;reset:in std_ulogic;tile_coord:out coordinate_t;tile_from_GA:in game_tile;tile_to_GA:out game_tile;set_tile:out std_ulogic;tail_pos:in coordinate_t;apple_placed:in std_ulogic);end Tail; + +architecture zqxwvuts of Tail is type asdfghjk is (fghjuiop,poiuytre,zxcvbnma,rtghyujk,ghjkdfgh,cvbnerty,mnbvcxzq,sdfghjkl,tyuioplk,wertyuio,qwertyui,lkjhgfds);signal plmoknij,bhuygvcf:asdfghjk;signal vfrcdexs,zaqwsxed,qazwsxed:coordinate_t;signal wsxedcrf:game_tile;constant edcrfvtg:coordinate_t:=(x=>(others=>'0'),y=>(others=>'0'));constant rfvtgbyh:game_tile:=(is_tail=>'0',is_head=>'0',is_apple=>'0',is_body=>'0',parent=>edcrfvtg);begin wsxedcrf.is_tail<='1';wsxedcrf.is_head<='0';wsxedcrf.is_apple<='0';wsxedcrf.is_body<='0';tgbyhnuj:process(clk)begin if reset='1'then plmoknij<=mnbvcxzq;elsif rising_edge(clk)then plmoknij<=bhuygvcf;if plmoknij=qwertyui then vfrcdexs<=tile_from_GA.parent;qazwsxed<=tile_from_GA.parent;elsif plmoknij=lkjhgfds then zaqwsxed<=tail_pos;elsif plmoknij=zxcvbnma then wsxedcrf.parent<=tile_from_GA.parent;end if;end if;end process;yhnujmik:process(plmoknij,start_tail)begin case plmoknij is when mnbvcxzq=>bhuygvcf<=poiuytre;when poiuytre=>if start_tail='1'then bhuygvcf<=lkjhgfds;else bhuygvcf<=poiuytre;end if;when lkjhgfds=>if apple_placed='0'then bhuygvcf<=wertyuio;else bhuygvcf<=rtghyujk;end if;when rtghyujk=>bhuygvcf<=cvbnerty;when cvbnerty=>bhuygvcf<=qwertyui;when qwertyui=>bhuygvcf<=fghjuiop;when fghjuiop=>bhuygvcf<=tyuioplk;when tyuioplk=>bhuygvcf<=ghjkdfgh;when ghjkdfgh=>bhuygvcf<=zxcvbnma;when zxcvbnma=>bhuygvcf<=sdfghjkl;when sdfghjkl=>bhuygvcf<=wertyuio;when wertyuio=>bhuygvcf<=poiuytre;end case;end process;ujmiklol:process(plmoknij)begin case plmoknij is when mnbvcxzq=>tile_coord<=edcrfvtg;set_tile<='0';tile_to_GA<=rfvtgbyh;tail_done<='0';when poiuytre=>tile_coord<=edcrfvtg;set_tile<='0';tile_to_GA<=rfvtgbyh;tail_done<='0';when lkjhgfds=>tile_coord<=tail_pos;set_tile<='0';tile_to_GA<=rfvtgbyh;tail_done<='0';when rtghyujk=>tile_coord<=tail_pos;set_tile<='0';tile_to_GA<=rfvtgbyh;tail_done<='0';when cvbnerty=>tile_coord<=tail_pos;set_tile<='0';tile_to_GA<=rfvtgbyh;tail_done<='0';when qwertyui=>tile_coord<=edcrfvtg;set_tile<='0';tile_to_GA<=rfvtgbyh;tail_done<='0';when fghjuiop=>tile_coord<=qazwsxed;set_tile<='0';tile_to_GA<=rfvtgbyh;tail_done<='0';when tyuioplk=>tile_coord<=qazwsxed;set_tile<='0';tile_to_GA<=rfvtgbyh;tail_done<='0';when ghjkdfgh=>tile_coord<=qazwsxed;set_tile<='0';tile_to_GA<=rfvtgbyh;tail_done<='0';when zxcvbnma=>tile_coord<=zaqwsxed;set_tile<='1';tile_to_GA<=rfvtgbyh;tail_done<='0';when sdfghjkl=>tile_coord<=vfrcdexs;set_tile<='1';tile_to_GA<=wsxedcrf;tail_done<='0';when wertyuio=>tile_coord<=edcrfvtg;set_tile<='0';tile_to_GA<=rfvtgbyh;tail_done<='1';end case;end process;end zqxwvuts; \ No newline at end of file diff --git a/source/init.vhd b/source/init.vhd new file mode 100644 index 0000000..c777a1a --- /dev/null +++ b/source/init.vhd @@ -0,0 +1 @@ +library IEEE;use IEEE.STD_LOGIC_1164.all;use IEEE.NUMERIC_STD.all;use work.local_types.all;entity init is port(clk:in std_ulogic;start_init:in std_ulogic;init_done:out std_ulogic;reset:in std_ulogic;tile_coord:out coordinate_t;tile_from_GA:in game_tile;tile_to_GA:out game_tile;set_tile:out std_ulogic);end init;architecture qxmblywz of init is type cktwlrpq is(zkprqtmf,vhwlnjcd,btfxqgry,jmsdwcpl,nvykxbaj);signal plokijuh,mnbvcxza:cktwlrpq;constant qazwsxed:coordinate_t:=(x=>(others=>'0'),y=>(others=>'0'));constant plmoknji:game_tile:=(is_tail=>'0',is_head=>'0',is_apple=>'0',is_body=>'0',parent=>qazwsxed);constant okmijnuy:coordinate_t:=(x=>"000100",y=>"000100");constant qawsedrf:coordinate_t:=(x=>"000010",y=>"000010");constant tgbfvcde:coordinate_t:=(x=>"000010",y=>"000011");constant xdcftvgy:game_tile:=(is_tail=>'0',is_head=>'0',is_apple=>'1',is_body=>'0',parent=>qazwsxed);constant rfvtgbyh:game_tile:=(is_tail=>'0',is_head=>'1',is_apple=>'0',is_body=>'0',parent=>qazwsxed);constant edcrfvtg:game_tile:=(is_tail=>'1',is_head=>'0',is_apple=>'0',is_body=>'0',parent=>qawsedrf);begin qazxswed:process(clk)begin if rising_edge(clk)then if reset='1'then plokijuh<=zkprqtmf;else plokijuh<=mnbvcxza;end if;end if;end process qazxswed;wqscedrf:process(plokijuh,start_init)begin case plokijuh is when zkprqtmf=>if start_init='1'then mnbvcxza<=btfxqgry;else mnbvcxza<=zkprqtmf;end if;when btfxqgry=>mnbvcxza<=vhwlnjcd;when vhwlnjcd=>mnbvcxza<=jmsdwcpl;when jmsdwcpl=>mnbvcxza<=nvykxbaj;when nvykxbaj=>mnbvcxza<=zkprqtmf;end case;end process wqscedrf;vfredcws:process(plokijuh)begin case plokijuh is when zkprqtmf=>tile_coord<=qazwsxed;set_tile<='0';tile_to_GA<=plmoknji;init_done<='0';when btfxqgry=>tile_coord<=qawsedrf;set_tile<='1';tile_to_GA<=rfvtgbyh;init_done<='0';when vhwlnjcd=>tile_coord<=tgbfvcde;set_tile<='1';tile_to_GA<=edcrfvtg;init_done<='0';when jmsdwcpl=>tile_coord<=okmijnuy;set_tile<='1';tile_to_GA<=xdcftvgy;init_done<='0';when nvykxbaj=>tile_coord<=qazwsxed;set_tile<='0';tile_to_GA<=plmoknji;init_done<='1';end case;end process vfredcws;end qxmblywz; \ No newline at end of file diff --git a/source/reset.vhd b/source/reset.vhd new file mode 100644 index 0000000..f324179 --- /dev/null +++ b/source/reset.vhd @@ -0,0 +1 @@ +library IEEE;use IEEE.STD_LOGIC_1164.all;use IEEE.NUMERIC_STD.all;use work.local_types.all;entity reset is port(clk:in std_ulogic;start_reset:in std_ulogic;reset_done:out std_ulogic;reset:in std_ulogic;tile_coord:out coordinate_t;tile_from_GA:in game_tile;tile_to_GA:out game_tile;set_tile:out std_ulogic);end reset;architecture xqplmnjb of reset is type ztrqwfld is (mnbvcxzq,xcvbnmqw,wertyuio,sdfghjkl);signal asdfghjk,qwertyui:ztrqwfld;signal zxcvbnml:std_ulogic_vector(11 downto 0):=(others=>'0');constant poiuytre:coordinate_t:=(x=>(others=>'0'),y=>(others=>'0'));constant lkjhgfds:game_tile:=(is_tail=>'0',is_head=>'0',is_apple=>'0',is_body=>'0',parent=>poiuytre);begin plokijuh:process(clk) begin if rising_edge(clk) then if reset='1' then asdfghjk<=mnbvcxzq;else if qwertyui=xcvbnmqw then zxcvbnml<=(others=>'0');elsif qwertyui=wertyuio then zxcvbnml<=std_ulogic_vector(to_unsigned(to_integer(unsigned(zxcvbnml))+1,12));end if;asdfghjk<=qwertyui;end if;end if;end process plokijuh;mkoijnub:process(asdfghjk,start_reset) begin case asdfghjk is when mnbvcxzq=>if start_reset='1' then qwertyui<=xcvbnmqw;else qwertyui<=mnbvcxzq;end if;when xcvbnmqw=>qwertyui<=wertyuio;when wertyuio=>if zxcvbnml="111111111111" then qwertyui<=sdfghjkl;else qwertyui<=wertyuio;end if;when sdfghjkl=>qwertyui<=mnbvcxzq;end case;end process mkoijnub;qaszxdew:process(asdfghjk) begin case asdfghjk is when mnbvcxzq=>tile_coord<=poiuytre;set_tile<='0';tile_to_GA<=lkjhgfds;reset_done<='0';when xcvbnmqw=>tile_coord.x<=zxcvbnml(11 downto 6);tile_coord.y<=zxcvbnml(5 downto 0);set_tile<='1';tile_to_GA<=lkjhgfds;reset_done<='0';when wertyuio=>tile_coord.x<=zxcvbnml(11 downto 6);tile_coord.y<=zxcvbnml(5 downto 0);set_tile<='1';tile_to_GA<=lkjhgfds;reset_done<='0';when sdfghjkl=>tile_coord<=poiuytre;set_tile<='0';tile_to_GA<=lkjhgfds;reset_done<='1';end case;end process qaszxdew;end xqplmnjb; \ No newline at end of file diff --git a/source/top.vhd b/source/top.vhd new file mode 100644 index 0000000..3f867c8 --- /dev/null +++ b/source/top.vhd @@ -0,0 +1,443 @@ +---------------------------------------------------------------------------------- +-- Company: ICT +-- Engineer: Daniel Fabian & Ulrich Paleček +-- +-- Create Date: 03/18/2026 06:01:13 PM +-- Design Name: Snake +-- Module Name: top - Behavioral +-- Project Name: Snake +-- Target Devices: Nexys 4 DDR & Nexys A7 100T +-- Tool Versions: Vivado 2020+ +-- Description: top module, kinda the nervous system of the snake +-- +-- Dependencies: Snake project +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 1.0 - First working version +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +library UNISIM; +use UNISIM.VComponents.all; +use work.local_types.all; + +entity top is + generic ( + AREAWIDTH : natural := 16; + AREAHEIGHT : natural := 12 + ); + port ( + --clk + clk : in std_ulogic; + --VGA Connector + VGA_R : out std_ulogic_vector (3 downto 0); + VGA_G : out std_ulogic_vector (3 downto 0); + VGA_B : out std_ulogic_vector (3 downto 0); + VGA_HS : out std_ulogic; + VGA_VS : out std_ulogic; + --Buttons + BTNC : in std_ulogic; + BTNU : in std_ulogic; + BTND : in std_ulogic; + BTNL : in std_ulogic; + BTNR : in std_ulogic; + -- LEDs and Switches + LED : out std_ulogic_vector (11 downto 0); + SW : in std_ulogic_vector (11 downto 0); + -- 7-Segment-Display + SEG : out std_ulogic_vector (6 downto 0); + DP : out std_ulogic; + AN : out std_ulogic_vector(7 downto 0) + ); +end top; + +architecture Behavioral of top is + + -- Clock and Reset + signal pre_tick_clk : std_ulogic; + signal tick : std_ulogic; + signal clk_fb : std_ulogic; + signal logic_reset : std_ulogic := '0'; + + -- VGA + signal next_pix_x_sig : std_ulogic_vector(9 downto 0); + signal next_pix_y_sig : std_ulogic_vector(9 downto 0); + signal pix_col_sig : color; + + -- Buttons + signal direction_sig : direction_t; + signal button_pressed_sig : std_ulogic; + + -- Gamearea + signal apple_placed_sig : std_ulogic; + signal head_pos_out_sig : coordinate_t; + signal tail_pos_out_sig : coordinate_t; + + -- Gamelogic + signal run_reset_sig : std_ulogic; + signal run_init_sig : std_ulogic; + signal run_head_sig : std_ulogic; + signal run_tail_sig : std_ulogic; + signal run_apples_sig : std_ulogic; + signal reset_done_sig : std_ulogic; + signal init_done_sig : std_ulogic; + signal head_done_sig : std_ulogic; + signal tail_done_sig : std_ulogic; + signal apples_done_sig : std_ulogic; + signal head_death_sig : std_ulogic; + + -- BEGIN Signals for GameAreaMUX + signal tile_coord_sig : coordinate_t; + signal tile_from_GA_sig : game_tile; + signal tile_to_GA_sig : game_tile; + signal set_tile_sig : std_ulogic; + + signal head_access : GameAreaInterface; + signal tile_coord_head_sig : coordinate_t; + signal tile_from_GA_head_sig : game_tile; + signal tile_to_GA_head_sig : game_tile; + signal set_tile_head_sig : std_ulogic; + + signal tail_access : GameAreaInterface; + signal tile_coord_tail_sig : coordinate_t; + signal tile_from_GA_tail_sig : game_tile; + signal tile_to_GA_tail_sig : game_tile; + signal set_tile_tail_sig : std_ulogic; + + signal apples_access : GameAreaInterface; + signal tile_coord_apples_sig : coordinate_t; + signal tile_from_GA_apples_sig : game_tile; + signal tile_to_GA_apples_sig : game_tile; + signal set_tile_apples_sig : std_ulogic; + + signal random_sig : std_ulogic_vector(11 downto 0); + + signal init_access : GameAreaInterface; + signal tile_coord_init_sig : coordinate_t; + signal tile_from_GA_init_sig : game_tile; + signal tile_to_GA_init_sig : game_tile; + signal set_tile_init_sig : std_ulogic; + + signal reset_access : GameAreaInterface; + signal tile_coord_reset_sig : coordinate_t; + signal tile_from_GA_reset_sig : game_tile; + signal tile_to_GA_reset_sig : game_tile; + signal set_tile_reset_sig : std_ulogic; + + signal selectable_ports : GameAreaInterfaceVector(4 downto 0); + signal GameAreaPort : GameAreaInterface; + signal port_selection : std_ulogic_vector(4 downto 0); + -- END Signals for GameAreaMUX + +begin + + -- Display LFSR-seed-switches on LEDs + LED <= SW; + + -- Connet Reset to Button + logic_reset <= BTNC; + + -- BEGIN Signals for GameAreaMUX + tile_coord_sig <= GameAreaPort.tile_coord; + tile_from_GA_sig <= GameAreaPort.tile_from_GA; + tile_to_GA_sig <= GameAreaPort.tile_to_GA; + set_tile_sig <= GameAreaPort.set_tile; + + head_access.tile_coord <= tile_coord_head_sig; + head_access.tile_from_GA <= tile_from_GA_head_sig; + head_access.tile_to_GA <= tile_to_GA_head_sig; + head_access.set_tile <= set_tile_head_sig; + + tail_access.tile_coord <= tile_coord_tail_sig; + tail_access.tile_from_GA <= tile_from_GA_tail_sig; + tail_access.tile_to_GA <= tile_to_GA_tail_sig; + tail_access.set_tile <= set_tile_tail_sig; + + apples_access.tile_coord <= tile_coord_apples_sig; + apples_access.tile_from_GA <= tile_from_GA_apples_sig; + apples_access.tile_to_GA <= tile_to_GA_apples_sig; + apples_access.set_tile <= set_tile_apples_sig; + + init_access.tile_coord <= tile_coord_init_sig; + init_access.tile_from_GA <= tile_from_GA_init_sig; + init_access.tile_to_GA <= tile_to_GA_init_sig; + init_access.set_tile <= set_tile_init_sig; + + reset_access.tile_coord <= tile_coord_reset_sig; + reset_access.tile_from_GA <= tile_from_GA_reset_sig; + reset_access.tile_to_GA <= tile_to_GA_reset_sig; + reset_access.set_tile <= set_tile_reset_sig; + + selectable_ports(0) <= head_access; + selectable_ports(1) <= tail_access; + selectable_ports(2) <= apples_access; + selectable_ports(3) <= init_access; + selectable_ports(4) <= reset_access; + + port_selection(0) <= run_head_sig; + port_selection(1) <= run_tail_sig; + port_selection(2) <= run_apples_sig; + port_selection(3) <= run_init_sig; + port_selection(4) <= run_reset_sig; + -- END Signals for GameAreaMUX + + GameArea_inst : entity work.GameArea + generic map( + AREAHEIGHT => AREAHEIGHT, + AREAWIDTH => AREAWIDTH + ) + port map( + clk => clk, + next_pix_x => next_pix_x_sig, + next_pix_y => next_pix_y_sig, + pix_col => pix_col_sig, + rst_game => logic_reset, + tile_coord => tile_coord_sig, + tile_from_GA => tile_from_GA_sig, + tile_to_GA => tile_to_GA_sig, + set_tile => set_tile_sig, + head_pos_out => head_pos_out_sig, + tail_pos_out => tail_pos_out_sig, + apple_placed => apple_placed_sig + ); + + Gametick_inst : entity work.Gametick + port map( + clk => pre_tick_clk, + tick => tick + ); + + Gamelogic_inst : entity work.Gamelogic + port map( + clk => clk, + tick => tick, + button_pressed => button_pressed_sig, + reset => logic_reset, + run_reset => run_reset_sig, + run_init => run_init_sig, + run_head => run_head_sig, + run_tail => run_tail_sig, + run_apples => run_apples_sig, + reset_done => reset_done_sig, + init_done => init_done_sig, + head_done => head_done_sig, + tail_done => tail_done_sig, + apples_done => apples_done_sig, + head_death => head_death_sig + ); + + Score_inst : entity work.Score + port map( + clk => clk, + slow_clk => pre_tick_clk, + reset => logic_reset, + apple_placed => apple_placed_sig, + tick => head_done_sig, + SEG => SEG, + DP => DP, + AN => AN + ); + + Buttons_inst : entity work.Buttons + port map( + clk => clk, + tick => tick, + reset => logic_reset, + button_up => BTNU, + button_down => BTND, + button_left => BTNL, + button_right => BTNR, + direction => direction_sig, + button_pressed => button_pressed_sig + ); + + Head_inst : entity work.Head + generic map( + AREAHEIGHT => AREAHEIGHT, + AREAWIDTH => AREAWIDTH + ) + port map( + clk => clk, --: in std_ulogic; + run_head => run_head_sig, --: in std_ulogic; + head_done => head_done_sig, --: out std_ulogic; + head_death => head_death_sig, + reset => logic_reset, + --gamearea manipulation/information interface + tile_coord => tile_coord_head_sig, --: out coordinate; + tile_from_GA => tile_from_GA_head_sig, --: in game_tile; + tile_to_GA => tile_to_GA_head_sig, --: out game_tile; + set_tile => set_tile_head_sig, --: out std_ulogic; + --gamesstate information + head_pos => head_pos_out_sig, --: in coordinate; + --button direction + direction => direction_sig --: in direction--; + ); + + Tail_inst : entity work.Tail + port map( + clk => clk, + start_tail => run_tail_sig, + tail_done => tail_done_sig, + reset => logic_reset, + --gamearea manipulation/information interface + tile_coord => tile_coord_tail_sig, + tile_from_GA => tile_from_GA_tail_sig, + tile_to_GA => tile_to_GA_tail_sig, + set_tile => set_tile_tail_sig, + --gamesstate information + tail_pos => tail_pos_out_sig, + apple_placed => apple_placed_sig + ); + Apples_inst : entity work.Apples + generic map( + AREAHEIGHT => AREAHEIGHT, + AREAWIDTH => AREAWIDTH + ) + port map( + clk => clk, + reset => logic_reset, + random => random_sig, + --gamearea manipulation/information interface + tile_coord => tile_coord_apples_sig, + tile_from_GA => tile_from_GA_apples_sig, + tile_to_GA => tile_to_GA_apples_sig, + set_tile => set_tile_apples_sig, + --gamesstate information + run_apples => run_apples_sig, + apples_done => apples_done_sig, + apple_placed => apple_placed_sig + + ); + + LFSR_inst : entity work.LFSR + port map( + clk => clk, + reset => logic_reset, + seed => SW, + random => random_sig + ); + + Init_inst : entity work.init + port map( + clk => clk, + start_init => run_init_sig, + init_done => init_done_sig, + reset => logic_reset, + --gamearea manipulation/information interface + tile_coord => tile_coord_init_sig, + tile_from_GA => tile_from_GA_init_sig, + tile_to_GA => tile_to_GA_init_sig, + set_tile => set_tile_init_sig + ); + Reset_inst : entity work.reset + port map( + clk => clk, + start_reset => run_reset_sig, + reset_done => reset_done_sig, + reset => logic_reset, + --gamearea manipulation/information interface + tile_coord => tile_coord_reset_sig, + tile_from_GA => tile_from_GA_reset_sig, + tile_to_GA => tile_to_GA_reset_sig, + set_tile => set_tile_reset_sig + + ); + + GameAreaMux_inst : entity work.GameAreaMux + generic map(NumInterfaces => 5) + port map( + GameAreaPort => GameAreaPort, + SelectionPort => selectable_ports, + Selection => port_selection + ); + + -- work.vga, work.vga_testpattern + VGA_inst : entity work.vga + port map( + --clk + clk => clk, + --pixel input + pxl_in => pix_col_sig, + --pixel request + next_pix_x => next_pix_x_sig, + next_pix_y => next_pix_y_sig, + --VGA Connector + VGA_R => VGA_R, + VGA_G => VGA_G, + VGA_B => VGA_B, + VGA_HS => VGA_HS, + VGA_VS => VGA_VS + ); + + -- MMCME2_BASE: Base Mixed Mode Clock Manager + -- Artix-7 + -- Xilinx HDL Language Template, version 2025.2 + + MMCME2_BASE_inst : MMCME2_BASE + generic map( + BANDWIDTH => "OPTIMIZED", -- Jitter programming (OPTIMIZED, HIGH, LOW) + CLKFBOUT_MULT_F => 10.0, -- Multiply value for all CLKOUT (2.000-64.000). + CLKFBOUT_PHASE => 0.0, -- Phase offset in degrees of CLKFB (-360.000-360.000). + CLKIN1_PERIOD => 0.0, -- Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz). + -- CLKOUT0_DIVIDE - CLKOUT6_DIVIDE: Divide amount for each CLKOUT (1-128) + CLKOUT1_DIVIDE => 10, + CLKOUT2_DIVIDE => 1, + CLKOUT3_DIVIDE => 1, + CLKOUT4_DIVIDE => 125, + CLKOUT5_DIVIDE => 1, + CLKOUT6_DIVIDE => 125, + CLKOUT0_DIVIDE_F => 1.0, -- Divide amount for CLKOUT0 (1.000-128.000). + -- CLKOUT0_DUTY_CYCLE - CLKOUT6_DUTY_CYCLE: Duty cycle for each CLKOUT (0.01-0.99). + CLKOUT0_DUTY_CYCLE => 0.5, + CLKOUT1_DUTY_CYCLE => 0.5, + CLKOUT2_DUTY_CYCLE => 0.5, + CLKOUT3_DUTY_CYCLE => 0.5, + CLKOUT4_DUTY_CYCLE => 0.5, + CLKOUT5_DUTY_CYCLE => 0.5, + CLKOUT6_DUTY_CYCLE => 0.5, + -- CLKOUT0_PHASE - CLKOUT6_PHASE: Phase offset for each CLKOUT (-360.000-360.000). + CLKOUT0_PHASE => 0.0, + CLKOUT1_PHASE => 0.0, + CLKOUT2_PHASE => 0.0, + CLKOUT3_PHASE => 0.0, + CLKOUT4_PHASE => 0.0, + CLKOUT5_PHASE => 0.0, + CLKOUT6_PHASE => 0.0, + CLKOUT4_CASCADE => TRUE, -- Cascade CLKOUT4 counter with CLKOUT6 (FALSE, TRUE) + DIVCLK_DIVIDE => 1, -- Master division value (1-106) + REF_JITTER1 => 0.0, -- Reference input jitter in UI (0.000-0.999). + STARTUP_WAIT => FALSE -- Delays DONE until MMCM is locked (FALSE, TRUE) + ) + port map( + -- Clock Outputs: 1-bit (each) output: User configurable clock outputs + --CLKOUT0 => CLKOUT0, -- 1-bit output: CLKOUT0 + --CLKOUT0B => CLKOUT0B, -- 1-bit output: Inverted CLKOUT0 + --CLKOUT1 => CLKOUT1, -- 1-bit output: CLKOUT1 + --CLKOUT1B => CLKOUT1B, -- 1-bit output: Inverted CLKOUT1 + --CLKOUT2 => CLKOUT2, -- 1-bit output: CLKOUT2 + --CLKOUT2B => CLKOUT2B, -- 1-bit output: Inverted CLKOUT2 + --CLKOUT3 => CLKOUT3, -- 1-bit output: CLKOUT3 + --CLKOUT3B => CLKOUT3B, -- 1-bit output: Inverted CLKOUT3 + CLKOUT4 => pre_tick_clk, -- 1-bit output: CLKOUT4 + --CLKOUT5 => CLKOUT5, -- 1-bit output: CLKOUT5 + --CLKOUT6 => CLKOUT6, -- 1-bit output: CLKOUT6 + -- Feedback Clocks: 1-bit (each) output: Clock feedback ports + CLKFBOUT => clk_fb, -- 1-bit output: Feedback clock + --CLKFBOUTB => CLKFBOUTB, -- 1-bit output: Inverted CLKFBOUT + -- Status Ports: 1-bit (each) output: MMCM status ports + --LOCKED => LOCKED, -- 1-bit output: LOCK + -- Clock Inputs: 1-bit (each) input: Clock input + CLKIN1 => clk, -- 1-bit input: Clock + -- Control Ports: 1-bit (each) input: MMCM control ports + PWRDWN => '0', -- 1-bit input: Power-down + RST => '0', -- 1-bit input: Reset + -- Feedback Clocks: 1-bit (each) input: Clock feedback ports + CLKFBIN => clk_fb -- 1-bit input: Feedback clock + ); + + -- End of MMCME2_BASE_inst instantiation +end Behavioral; diff --git a/source/types.vhd b/source/types.vhd new file mode 100644 index 0000000..afc247a --- /dev/null +++ b/source/types.vhd @@ -0,0 +1,61 @@ +---------------------------------------------------------------------------------- +-- Company: ICT +-- Engineer: Daniel Fabian & Ulrich Paleček +-- +-- Create Date: 03/20/2026 11:36:18 AM +-- Design Name: Snake +-- Module Name: types - Behavioral +-- Project Name: Snake +-- Target Devices: Nexys 4 DDR & Nexys A7 100T +-- Tool Versions: Vivado 2020+ +-- Description: Typedefinitions for Snake Project +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 1.0 - First working version +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +package local_types is + type color is record + red : std_ulogic_vector(3 downto 0); + green : std_ulogic_vector(3 downto 0); + blue : std_ulogic_vector(3 downto 0); + end record color; + + type coordinate_t is record + x : std_ulogic_vector(5 downto 0); + y : std_ulogic_vector(5 downto 0); + end record coordinate_t; + + type game_tile is record + is_tail : std_ulogic; + is_head : std_ulogic; + is_apple : std_ulogic; + is_body : std_ulogic; + parent : coordinate_t; + end record game_tile; + + type GameAreaInterface is record + tile_coord : coordinate_t; + tile_from_GA : game_tile; + tile_to_GA : game_tile; + set_tile : std_ulogic; + end record GameAreaInterface; + + type GameAreaInterfaceVector is array (natural range <>) of GameAreaInterface; + + type direction_t is (UP, DOWN, LEFT, RIGHT); + + type gamescore is record + a : std_ulogic_vector(3 downto 0); + b : std_ulogic_vector(3 downto 0); + c : std_ulogic_vector(3 downto 0); + d : std_ulogic_vector(3 downto 0); + end record gamescore; +end package; diff --git a/source/vga_testpattern.vhd b/source/vga_testpattern.vhd new file mode 100644 index 0000000..f7a8689 --- /dev/null +++ b/source/vga_testpattern.vhd @@ -0,0 +1,144 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +use work.local_types.all; + +entity vga_testpattern is + port ( + --clk + clk : in std_ulogic; + -- ================================================ + -- TODO: Implement + --pixel input + pxl_in : in color; + --pixel request + next_pix_x : out std_ulogic_vector (9 downto 0); + next_pix_y : out std_ulogic_vector (9 downto 0); + -- ================================================ + --VGA Connector + VGA_R : out std_ulogic_vector (3 downto 0); + VGA_G : out std_ulogic_vector (3 downto 0); + VGA_B : out std_ulogic_vector (3 downto 0); + VGA_HS : out std_ulogic; + VGA_VS : out std_ulogic + ); +end vga_testpattern; + +architecture Behavioral of vga_testpattern is + + constant H_PIXELS : integer := 640; + constant V_PIXELS : integer := 480; + constant H_TOTAL : integer := 800; + constant HS_START : integer := 656; + constant HS_TIME : integer := 96; + + constant V_TOTAL : integer := 525; + constant VS_START : integer := 490; + constant VS_TIME : integer := 2; + + signal vga_cnt : std_ulogic_vector(1 downto 0) := (others => '0'); + signal vga_clk : std_ulogic; + + signal pix_x : std_ulogic_vector(9 downto 0) := (others => '0'); + signal pix_y : std_ulogic_vector(9 downto 0) := (others => '0'); + + type t_vga is record + -- Synchronization + hs : std_ulogic; + vs : std_ulogic; + -- Pixel colour + col_r : std_ulogic_vector(3 downto 0); + col_g : std_ulogic_vector(3 downto 0); + col_b : std_ulogic_vector(3 downto 0); + end record t_vga; + + signal vga : t_vga; + +begin + + vga_cnt_proc : process (clk) + begin + if rising_edge(clk) then + vga_cnt <= std_ulogic_vector(unsigned(vga_cnt) + 1); + end if; + end process vga_cnt_proc; + + vga_clk <= vga_cnt(1); + + pix_x_proc : process (vga_clk) + begin + if rising_edge(vga_clk) then + if pix_x = std_ulogic_vector(to_unsigned(H_TOTAL - 1, 10)) then + pix_x <= (others => '0'); + else + pix_x <= std_ulogic_vector(unsigned(pix_x) + 1); + end if; + end if; + end process pix_x_proc; + + pix_y_proc : process (vga_clk) + begin + if rising_edge(vga_clk) then + if pix_x = std_ulogic_vector(to_unsigned(H_TOTAL - 1, 10)) then + if pix_y = std_ulogic_vector(to_unsigned(V_TOTAL - 1, 10)) then + pix_y <= (others => '0'); + else + pix_y <= std_ulogic_vector(unsigned(pix_y) + 1); + end if; + end if; + end if; + end process pix_y_proc; + + vga_hs_proc : process (vga_clk) + begin + if rising_edge(vga_clk) then + if pix_x >= std_ulogic_vector(to_unsigned(HS_START, 10)) and pix_x < std_ulogic_vector(to_unsigned(HS_START + HS_TIME, 10)) then + vga.hs <= '0'; + else + vga.hs <= '1'; + end if; + end if; + end process vga_hs_proc; + + vga_vs_proc : process (vga_clk) + begin + if rising_edge(vga_clk) then + if pix_y >= std_ulogic_vector(to_unsigned(VS_START, 10)) and pix_y < std_ulogic_vector(to_unsigned(VS_START + VS_TIME, 10)) then + vga.vs <= '0'; + else + vga.vs <= '1'; + end if; + end if; + end process vga_vs_proc; + + vga_col_proc : process (vga_clk) + begin + if rising_edge(vga_clk) then + + -- Generate checker board pattern + if (pix_x(4) xor pix_y(4)) = '1' then + vga.col_r <= "1111"; + vga.col_g <= "1111"; + vga.col_b <= "1111"; + else + vga.col_r <= "0000"; + vga.col_g <= "0000"; + vga.col_b <= "0000"; + end if; + + -- Make sure colour is black outside the visible area. + if pix_x >= std_ulogic_vector(to_unsigned(H_PIXELS, 10)) or pix_y >= std_ulogic_vector(to_unsigned(V_PIXELS, 10)) then + vga.col_r <= "0000"; + vga.col_g <= "0000"; + vga.col_b <= "0000"; + end if; + end if; + end process vga_col_proc; + + VGA_HS <= vga.hs; + VGA_VS <= vga.vs; + VGA_R <= vga.col_r; + VGA_G <= vga.col_g; + VGA_B <= vga.col_b; + +end Behavioral;