- comments added

This commit is contained in:
Wiesner András 2025-11-05 07:26:15 +01:00
parent d1d0f6b409
commit ba8ee12a22
6 changed files with 133 additions and 138 deletions

53
beep.v
View File

@ -1,28 +1,30 @@
// hangszóróvezérlő modul
module beep #( module beep #(
parameter HIT_PERIOD = 1, parameter HIT_PERIOD = 1, // hullámforma periódusideje találat esetén
parameter HIT_LEN = 150, parameter HIT_LEN = 150, // lejátszás hossza
parameter MISS_PERIOD = 3, parameter MISS_PERIOD = 3, // hullámforma periódusideje leeső labda esetén
parameter MISS_LEN = 1400, parameter MISS_LEN = 1400, // lejátszás hossza
parameter HALF_MS_DIV = 500 parameter HALF_MS_DIV = 500 // 500us hosszú pulzusok osztásaránya
)( )(
input wire clk, input wire clk, // órajel (1MHz)
input wire rst, input wire rst, // szinkron reset
input wire hit, input wire hit, // labda visszaütve
input wire miss, input wire miss, // labda leesett
output reg beep output reg beep // hangszótókimenet
); );
// 0.5ms-os pulzusokat előállító számláló
reg [8:0] cntr; reg [8:0] cntr;
always @(posedge clk) always @(posedge clk)
begin begin
if (rst) if (rst) // reset
begin begin
cntr <= 9'd0; cntr <= 9'd0;
end end
else else
begin begin // számlálás
if (cntr != (HALF_MS_DIV - 1)) if (cntr != (HALF_MS_DIV - 1))
begin begin
cntr <= cntr + 9'd1; cntr <= cntr + 9'd1;
@ -34,18 +36,20 @@ begin
end end
end end
// túlcsordulás
wire tc = (cntr == (HALF_MS_DIV - 1)); wire tc = (cntr == (HALF_MS_DIV - 1));
reg [3:0] period; // hullámforma előállítása
reg [3:0] subperiod_cntr; reg [3:0] period; // periódusidő
reg [3:0] subperiod_cntr; // perióduson belüli számláló
always @(posedge clk) always @(posedge clk)
begin begin
if (rst || (!sound_playing)) if (rst || (!sound_playing)) // reset vagy nincs lejátszás
begin begin
beep <= 1'b0; beep <= 1'b0;
subperiod_cntr <= 4'd0; subperiod_cntr <= 4'd0;
end end
else if (sound_playing && tc) else if (sound_playing && tc) // lejátszás és 0.5ms periódus vége
begin begin
if (subperiod_cntr != period) if (subperiod_cntr != period)
begin begin
@ -60,25 +64,26 @@ begin
end end
reg sound_playing; reg sound_playing; // hang lejátszás alatt van
reg [10:0] len; reg [10:0] len; // lejátszás hossza
// lejátszás-vezérlése
always @(posedge clk) always @(posedge clk)
begin begin
if (rst) if (rst) // szinkron reset
begin begin
sound_playing <= 1'b0; sound_playing <= 1'b0;
len <= 11'd0; len <= 11'd0;
period <= 4'd0; period <= 4'd0;
end end
else if ((!sound_playing) && (hit || miss)) else if ((!sound_playing) && (hit || miss)) // ha épp nincs lejátszás és esemény történt
begin begin
if (hit) if (hit) // hullámforma kiválasztása
begin begin
period <= HIT_PERIOD; period <= HIT_PERIOD;
len <= HIT_LEN; len <= HIT_LEN;
end end
else if (miss) else if (miss) // .....
begin begin
period <= MISS_PERIOD; period <= MISS_PERIOD;
len <= MISS_LEN; len <= MISS_LEN;
@ -86,7 +91,7 @@ begin
sound_playing <= 1'b1; sound_playing <= 1'b1;
end end
else if (sound_playing && tc) else if (sound_playing && tc) // lejátszás, hátralevő idő csökkentése
begin begin
if (len != 10'd0) if (len != 10'd0)
begin begin
@ -94,7 +99,7 @@ begin
end end
else else
begin begin
sound_playing <= 1'b0; sound_playing <= 1'b0; // lejátszás leállítása
end end
end end
end end

View File

@ -1,53 +1,63 @@
// játéklogika
module game_controller #( module game_controller #(
parameter SCREEN_WIDTH = 1024, parameter SCREEN_WIDTH = 1024, // képernyő szélessége
parameter SCREEN_HEIGHT = 768, parameter SCREEN_HEIGHT = 768, // képernyő magassága
parameter BALL_START_X = SCREEN_WIDTH / 2, // labda kezdőkoordinátái
parameter BALL_START_X = SCREEN_WIDTH / 2,
parameter BALL_START_Y = SCREEN_HEIGHT / 6, parameter BALL_START_Y = SCREEN_HEIGHT / 6,
//parameter BALL_START_SPEED_VEC = 2'b11, //parameter BALL_START_SPEED_VEC = 2'b11,
// platformok tulajdonságai
parameter POD_TOP = SCREEN_HEIGHT - 50, parameter POD_TOP = SCREEN_HEIGHT - 50,
parameter POD_WIDTH = SCREEN_WIDTH / 6, parameter POD_WIDTH = SCREEN_WIDTH / 6,
parameter POD1_START_X = (SCREEN_WIDTH / 2 - POD_WIDTH) / 2, parameter POD1_START_X = (SCREEN_WIDTH / 2 - POD_WIDTH) / 2,
parameter POD2_START_X = POD1_START_X + SCREEN_WIDTH / 2, parameter POD2_START_X = POD1_START_X + SCREEN_WIDTH / 2,
// középső fal tulajdonságai
parameter WALL_HALF_WIDTH = 4, parameter WALL_HALF_WIDTH = 4,
parameter WALL_HEIGHT = SCREEN_HEIGHT / 3, parameter WALL_HEIGHT = SCREEN_HEIGHT / 3,
// szimuláció sebessége
parameter SIMDIV = 2500, parameter SIMDIV = 2500,
// bithosszok
parameter N_SCR_WIDTH = $clog2(SCREEN_WIDTH), parameter N_SCR_WIDTH = $clog2(SCREEN_WIDTH),
parameter N_SCR_HEIGHT = $clog2(SCREEN_HEIGHT), parameter N_SCR_HEIGHT = $clog2(SCREEN_HEIGHT),
parameter N_SIMDIV = $clog2(SIMDIV) parameter N_SIMDIV = $clog2(SIMDIV)
)( )(
input wire clk, input wire clk, // órajel (1MHz)
input wire rst, input wire rst, // szinkron reset
input wire rst2,
input wire start, input wire start, // játék indítása
input wire acknowledge, input wire acknowledge, // továbblépés játék vége után
// bal oldali platform koordinátái
output reg [N_SCR_WIDTH - 1:0] pod1x, output reg [N_SCR_WIDTH - 1:0] pod1x,
output reg [N_SCR_WIDTH - 1:0] pod2x, output reg [N_SCR_WIDTH - 1:0] pod2x,
// jobb oldali platform koordinátái
output reg [N_SCR_WIDTH - 1:0] ballx, output reg [N_SCR_WIDTH - 1:0] ballx,
output reg [N_SCR_HEIGHT - 1:0] bally, output reg [N_SCR_HEIGHT - 1:0] bally,
// platformok mozgatás-engedélyezése és irányvezérlése
input wire move_pod1_en, input wire move_pod1_en,
input wire move_pod1_dir, input wire move_pod1_dir,
input wire move_pod2_en, input wire move_pod2_en,
input wire move_pod2_dir, input wire move_pod2_dir,
// pontszám-kimenetek és pontszámok törlése
output reg [7:0] score1, output reg [7:0] score1,
output reg [7:0] score2, output reg [7:0] score2,
input wire clear_score, input wire clear_score,
// hangvezérlése
output reg hit, output reg hit,
output reg miss output reg miss
); );
// randobgenerátor (LFSR)
reg [15:0] rnd; reg [15:0] rnd;
always @(posedge clk) always @(posedge clk)
begin begin
if (rst) if (rst)
@ -62,13 +72,15 @@ end
// ----------- // -----------
localparam GS_FROZEN = 0; // játékállapotok
localparam GS_RUNNING = 1; localparam GS_FROZEN = 0; // fagyasztva
localparam GS_SCORING = 2; localparam GS_RUNNING = 1; // játék fut
localparam GS_GAME_OVER = 3; localparam GS_SCORING = 2; // pontok kiosztása
localparam GS_GAME_OVER = 3; // játék vége
wire restart = (next_game_state == GS_FROZEN) && (game_state == GS_GAME_OVER); wire restart = (next_game_state == GS_FROZEN) && (game_state == GS_GAME_OVER);
// követvező játékállapot
reg [1:0] next_game_state; reg [1:0] next_game_state;
always @(*) always @(*)
begin begin
@ -80,6 +92,7 @@ begin
endcase endcase
end end
// játékállapot-regiszter
reg [1:0] game_state; reg [1:0] game_state;
always @(posedge clk) always @(posedge clk)
begin begin
@ -93,15 +106,16 @@ begin
end end
end end
wire game_running = (game_state == GS_RUNNING); wire game_running = (game_state == GS_RUNNING); // játék fut jelzés
// ----------- // -----------
reg speed_boost; // ladba sebsségszimulációja
reg [2:0] speed_vec; reg speed_boost; // gyorsítás
reg [2:0] speed_vec; // sebességvektor
always @(posedge clk) always @(posedge clk)
begin begin
if (rst || restart) if (rst || restart) // szinkron reset vagy új játék
begin begin
speed_boost <= 1'b0; speed_boost <= 1'b0;
speed_vec <= rnd[15:14]; speed_vec <= rnd[15:14];
@ -109,14 +123,16 @@ begin
end end
else else
begin begin
if (((ballx == (SCREEN_WIDTH - 1)) && (speed_vec[0] == 1'b1)) || // visszapattanás a függőleges falakról
((ballx == 0) && (speed_vec[0] == 1'b0)) || if (((ballx == (SCREEN_WIDTH - 1)) && (speed_vec[0] == 1'b1)) || // jobb képernyőszél
((bally > (SCREEN_HEIGHT - WALL_HEIGHT - 1)) && ((ballx == 0) && (speed_vec[0] == 1'b0)) || // bal képernyőszél
((bally > (SCREEN_HEIGHT - WALL_HEIGHT - 1)) && // középső fal
(((ballx == (SCREEN_WIDTH / 2 - 1)) && (speed_vec[0] == 1'b1)) || ((ballx == (SCREEN_WIDTH / 2)) && (speed_vec[0] == 1'b0))))) (((ballx == (SCREEN_WIDTH / 2 - 1)) && (speed_vec[0] == 1'b1)) || ((ballx == (SCREEN_WIDTH / 2)) && (speed_vec[0] == 1'b0)))))
begin begin
speed_vec[0] <= ~speed_vec[0]; speed_vec[0] <= ~speed_vec[0];
end end
// visszapattanás a képernyő tetejéről
if ((bally == 0) && (speed_vec[1] == 1'b0)) if ((bally == 0) && (speed_vec[1] == 1'b0))
begin begin
speed_vec[1] <= ~speed_vec[1]; speed_vec[1] <= ~speed_vec[1];
@ -124,6 +140,7 @@ begin
hit <= 1'b0; hit <= 1'b0;
// visszapattanás a bal platformról
if ((bally == POD_TOP - 1) && (speed_vec[1] == 1'b1) && (((ballx > pod1x) && (ballx < (pod1x + POD_WIDTH))))) if ((bally == POD_TOP - 1) && (speed_vec[1] == 1'b1) && (((ballx > pod1x) && (ballx < (pod1x + POD_WIDTH)))))
begin begin
speed_vec[1] <= ~speed_vec[1]; speed_vec[1] <= ~speed_vec[1];
@ -133,6 +150,7 @@ begin
hit <= 1'b1; hit <= 1'b1;
end end
// visszapattanás a jobb platformról
if ((bally == POD_TOP - 1) && (speed_vec[1] == 1'b1) && ((ballx > pod2x) && (ballx < (pod2x + POD_WIDTH)))) if ((bally == POD_TOP - 1) && (speed_vec[1] == 1'b1) && ((ballx > pod2x) && (ballx < (pod2x + POD_WIDTH))))
begin begin
speed_vec[1] <= ~speed_vec[1]; speed_vec[1] <= ~speed_vec[1];
@ -147,6 +165,7 @@ end
// ----------------- // -----------------
// szimuláció frekvenciaosztó számlálója
reg [N_SIMDIV - 1:0] sim_cntr; reg [N_SIMDIV - 1:0] sim_cntr;
reg [N_SIMDIV - 1:0] sim_cntr_max; reg [N_SIMDIV - 1:0] sim_cntr_max;
always @(posedge clk) always @(posedge clk)
@ -170,8 +189,9 @@ begin
end end
end end
wire sim_step = game_running && (sim_cntr == sim_cntr_max); wire sim_step = game_running && (sim_cntr == sim_cntr_max); // szimulációs lépés jelzés
// labda-pozíciószimuláció
always @(posedge clk) always @(posedge clk)
begin begin
if (rst || restart) if (rst || restart)
@ -189,6 +209,7 @@ begin
end end
end end
// platform mozgatása
always @(posedge clk) always @(posedge clk)
begin begin
if (rst || restart) if (rst || restart)
@ -198,7 +219,7 @@ begin
end end
else if (sim_step) else if (sim_step)
begin begin
if (move_pod1_en) if (move_pod1_en) // bal platform mozgatás-engedélyezése
begin begin
if (move_pod1_dir && (pod1x < ((SCREEN_WIDTH / 2) - POD_WIDTH - WALL_HALF_WIDTH))) // jobbra mozgatás if (move_pod1_dir && (pod1x < ((SCREEN_WIDTH / 2) - POD_WIDTH - WALL_HALF_WIDTH))) // jobbra mozgatás
begin begin
@ -210,7 +231,7 @@ begin
end end
end end
if (move_pod2_en) if (move_pod2_en) // jobb platform mozgatás-engedélyezése
begin begin
if (move_pod2_dir && (pod2x < (SCREEN_WIDTH - POD_WIDTH))) // jobbra mozgatás if (move_pod2_dir && (pod2x < (SCREEN_WIDTH - POD_WIDTH))) // jobbra mozgatás
begin begin
@ -225,6 +246,7 @@ begin
end end
end end
// BCD-számláló funkcionalitás
function [7:0] bcd_inc; function [7:0] bcd_inc;
input [7:0] a; input [7:0] a;
begin begin
@ -232,6 +254,7 @@ function [7:0] bcd_inc;
end end
endfunction endfunction
// pontozás
always @(posedge clk) always @(posedge clk)
begin begin
if (rst || clear_score) if (rst || clear_score)
@ -252,6 +275,7 @@ begin
end end
end end
// leeső labda hangvezérlése
always @(posedge clk) always @(posedge clk)
begin begin
if (rst) if (rst)

View File

@ -1,27 +1,30 @@
// billentyű-felismerő
module key_matcher( module key_matcher(
input wire clk, input wire clk, // órajel (1MHz)
input wire rst, input wire rst, // szinkron reset
input wire [7:0] scan_code, input wire [7:0] scan_code, // billentyűkód
input wire sc_valid, input wire sc_valid, // a kimeneten érvényes adat van
output reg [6:0] key_states output reg [6:0] key_states // a figyelt billentyűk állapotai
); );
// --------------- // ---------------
localparam SC_A = 8'h1C; // billentyűkódok
localparam SC_D = 8'h23; localparam SC_A = 8'h1C; // A
localparam SC_N4 = 8'h6B; localparam SC_D = 8'h23; // D
localparam SC_N6 = 8'h74; localparam SC_N4 = 8'h6B; // NumPad 4
localparam SC_N = 8'h31; localparam SC_N6 = 8'h74; // NumPad 6
localparam SC_M = 8'h3A; localparam SC_N = 8'h31; // N
localparam SC_ESC = 8'h76; localparam SC_M = 8'h3A; // M
localparam SC_ESC = 8'h76; // Escape
localparam SC_REL = 8'hF0; localparam SC_REL = 8'hF0; // billentyű elengedése előtag
// ------------- // -------------
// bejövő adat léptetőregisztere
reg [15:0] shr; reg [15:0] shr;
always @(posedge clk) always @(posedge clk)
begin begin
@ -38,6 +41,7 @@ end
wire [7:0] b0 = shr[7:0]; wire [7:0] b0 = shr[7:0];
wire [7:0] b1 = shr[15:8]; wire [7:0] b1 = shr[15:8];
// billentyű-mintaillesztés
always @(posedge clk) always @(posedge clk)
begin begin
if (rst) if (rst)
@ -46,11 +50,11 @@ begin
end end
else else
begin begin
if ((b0 == SC_A) && (b1 != SC_REL)) if ((b0 == SC_A) && (b1 != SC_REL)) // A lenyomva
begin begin
key_states[0] <= 1'b1; key_states[0] <= 1'b1;
end end
else if ((b0 == SC_A) && (b1 == SC_REL)) else if ((b0 == SC_A) && (b1 == SC_REL)) // A felengedve
begin begin
key_states[0] <= 1'b0; key_states[0] <= 1'b0;
end end

View File

@ -1,16 +1,15 @@
module pp_top( module pp_top(
input wire clk, input wire clk, // 50MHz-es órajel
input wire rst_n, input wire rst_n, // negált reset
output wire [4:0] vga_sigs, output wire [4:0] vga_sigs, // VGA-kimenet jelei
output wire [3:0] leds_n, // LED-ek
output wire [3:0] leds_n, input wire [3:0] btns_n, // gombok
input wire [3:0] btns_n, output wire [7:0] segs_n, // szegmensek (7seg)
output wire [7:0] segs_n, output wire [3:0] digs_n, // digit-engedélyezés (7seg)
output wire [3:0] digs_n, input wire ps2_ck, // PS/2 órajel
input wire ps2_ck, input wire ps2_dat, // PS/2 adatvonal
input wire ps2_dat, output wire beep_n // hanszóróvezérlés
output wire beep_n
); );
// bemenetek-kimenetek ponált-negált átalakítása // bemenetek-kimenetek ponált-negált átalakítása
@ -23,8 +22,9 @@ wire clk65M;
wire clk1M; wire clk1M;
wire locked; wire locked;
reg srst; reg srst; // szinkron reset
// órajel-előállító (beépített) modul
clk_gen main_clk_gen( clk_gen main_clk_gen(
.areset(rst), .areset(rst),
.inclk0(clk), .inclk0(clk),
@ -35,6 +35,7 @@ clk_gen main_clk_gen(
// ----------- // -----------
// PS/2 vezérlő
wire [7:0] data; wire [7:0] data;
wire valid; wire valid;
ps2_host ps2( ps2_host ps2(
@ -49,20 +50,9 @@ ps2_host ps2(
.ack(1'b1) .ack(1'b1)
); );
//always @(posedge clk1M)
//begin
// if (rst)
// begin
// d <= 16'b0;
// end
// else if (valid)
// begin
// d <= { d[7:0], data };
// end
//end
// ----------- // -----------
// Billentyű-állapot figyelő
wire [6:0] ks; wire [6:0] ks;
key_matcher km( key_matcher km(
.clk(clk1M), .clk(clk1M),
@ -110,9 +100,9 @@ game_controller game (
.miss(miss) .miss(miss)
); );
// Hangvezérlő
wire beep; wire beep;
assign beep_n = ~beep; assign beep_n = ~beep;
beep beeper( beep beeper(
.clk(clk1M), .clk(clk1M),
.rst(srst), .rst(srst),
@ -166,6 +156,7 @@ assign { d3, d2, d1, d0 } = { score1, score2 };
//reg [15:0] d; //reg [15:0] d;
//assign { d3, d2, d1, d0 } = d; //assign { d3, d2, d1, d0 } = d;
// hétszegmens-kijelző meghajtó
sseg_disp disp( sseg_disp disp(
.clk(clk1M), .clk(clk1M),
.rst(srst), .rst(srst),
@ -184,6 +175,7 @@ sseg_disp disp(
// ----------- // -----------
// kb. 1Hz osztó
reg [19:0] cntr; reg [19:0] cntr;
always @(posedge clk1M, posedge rst) always @(posedge clk1M, posedge rst)
begin begin
@ -199,6 +191,7 @@ end
wire tc = &cntr; wire tc = &cntr;
// reset-generátor
reg reset_issued; reg reset_issued;
always @(posedge clk1M, posedge rst) always @(posedge clk1M, posedge rst)
begin begin
@ -220,19 +213,6 @@ end
// ----------- // -----------
//always @(posedge clk1M)
//begin
// if (rst)
// begin
// ld0 <= 0;
// end
// else if (tc)
// begin
// ld0 <= ~ld0;
// end
//end
wire [3:0] leds = ks[3:0]; wire [3:0] leds = ks[3:0];
endmodule endmodule

View File

@ -1,15 +1,17 @@
// PS/2 vezérlő
module ps2_host ( module ps2_host (
input wire clk, input wire clk, // órajel (1MHz)
input wire rst, input wire rst, // szinkron reset
input wire ps2_ck, input wire ps2_ck, // PS/2 órajel
input wire ps2_dat, input wire ps2_dat, // PS/2 adat
output reg [7:0] data, output reg [7:0] data, // adatbájt-kimenet
output reg valid, output reg valid, // adat érvényes a kimeneten
input wire ack input wire ack // adat olvasva
); );
// PS/2 órajel-felismerés
reg prev_ps2_ck; reg prev_ps2_ck;
always @(posedge clk) always @(posedge clk)
begin begin
@ -51,6 +53,7 @@ end
wire ck_falling = prev_ck_state && !ck_state; wire ck_falling = prev_ck_state && !ck_state;
// bitszámláló
reg [3:0] cntr; reg [3:0] cntr;
always @(posedge clk) always @(posedge clk)
begin begin
@ -68,6 +71,7 @@ begin
end end
end end
// adat beléptetése
reg [10:0] shr; reg [10:0] shr;
always @(posedge clk) always @(posedge clk)
begin begin
@ -81,6 +85,7 @@ begin
end end
end end
// adat kiadása
always @(posedge clk) always @(posedge clk)
begin begin
if (rst) if (rst)

39
vga.v
View File

@ -1,8 +1,8 @@
`timescale 1ns/1ps `timescale 1ns/1ps
module vga #( module vga #(
parameter COLS = 1024, parameter COLS = 1024, // oszlopok száma a képernyőn
parameter ROWS = 768, parameter ROWS = 768, // sorok száma a képernyőn
parameter H_FRONT_PORCH = 24, parameter H_FRONT_PORCH = 24,
parameter H_SYNC_PULSE = 136, parameter H_SYNC_PULSE = 136,
parameter H_BACK_PORCH = 160, parameter H_BACK_PORCH = 160,
@ -13,23 +13,27 @@ module vga #(
parameter V_SYNC_NEG = 1'b1, parameter V_SYNC_NEG = 1'b1,
parameter OVERSCAN = 1, parameter OVERSCAN = 1,
// színek (BGR)
parameter COL_POD1 = 3'b001, parameter COL_POD1 = 3'b001,
parameter COL_POD2 = 3'b010, parameter COL_POD2 = 3'b010,
parameter COL_BALL = 3'b011, parameter COL_BALL = 3'b011,
parameter COL_BG = 3'b000, parameter COL_BG = 3'b000,
// platformok tulajdonságai
parameter POD_WIDTH = COLS / 6, parameter POD_WIDTH = COLS / 6,
parameter POD_HEIGHT = ROWS / 32, parameter POD_HEIGHT = ROWS / 32,
parameter POD_TOP = ROWS - 50, parameter POD_TOP = ROWS - 50,
// középső fal tulajdonságai
parameter WALL_HALF_WIDTH = 4, parameter WALL_HALF_WIDTH = 4,
parameter WALL_HEIGHT = ROWS / 3, parameter WALL_HEIGHT = ROWS / 3,
// bithosszok
parameter N_COLS = $clog2(H_FULL), parameter N_COLS = $clog2(H_FULL),
parameter N_ROWS = $clog2(V_FULL) parameter N_ROWS = $clog2(V_FULL)
)( )(
input wire pclk, // pixel órajel input wire pclk, // pixel órajel (65MHz)
input wire sclk, // lassú órajel input wire sclk, // lassú órajel (1MHz)
input wire rst, // reset input wire rst, // reset
output wire hsync, // vízszintes szinkron output wire hsync, // vízszintes szinkron
@ -46,33 +50,6 @@ localparam H_FULL = COLS + H_FRONT_PORCH + H_SYNC_PULSE + H_BACK_PORCH;
localparam V_FULL = ROWS + V_FRONT_PORCH + V_SYNC_PULSE + V_BACK_PORCH; localparam V_FULL = ROWS + V_FRONT_PORCH + V_SYNC_PULSE + V_BACK_PORCH;
localparam BALL_RADIUS = 12; localparam BALL_RADIUS = 12;
//localparam [0:25*25-1] BALL_GLYPH = {
// 25'b0000000000000000000000000,
// 25'b0000000001111111100000000,
// 25'b0000001111111111111000000,
// 25'b0000011111111111111100000,
// 25'b0000111111111111111110000,
// 25'b0001111111111111111111000,
// 25'b0011111111111111111111100,
// 25'b0011111111111111111111110,
// 25'b0111111111111111111111110,
// 25'b0111111111111111111111110,
// 25'b0111111111111111111111110,
// 25'b0111111111111111111111111,
// 25'b0111111111111111111111111,
// 25'b0111111111111111111111111,
// 25'b0111111111111111111111111,
// 25'b0111111111111111111111110,
// 25'b0111111111111111111111110,
// 25'b0011111111111111111111110,
// 25'b0011111111111111111111100,
// 25'b0001111111111111111111100,
// 25'b0000111111111111111111000,
// 25'b0000111111111111111110000,
// 25'b0000001111111111111100000,
// 25'b0000000111111111110000000,
// 25'b0000000000111110000000000
//};
localparam [0:25*25-1] BALL_GLYPH = { localparam [0:25*25-1] BALL_GLYPH = {
25'b0000000000000000000000000, 25'b0000000000000000000000000,