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

View File

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

View File

@ -1,27 +1,30 @@
// billentyű-felismerő
module key_matcher(
input wire clk,
input wire rst,
input wire clk, // órajel (1MHz)
input wire rst, // szinkron reset
input wire [7:0] scan_code,
input wire sc_valid,
input wire [7:0] scan_code, // billentyűkód
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;
localparam SC_D = 8'h23;
localparam SC_N4 = 8'h6B;
localparam SC_N6 = 8'h74;
localparam SC_N = 8'h31;
localparam SC_M = 8'h3A;
localparam SC_ESC = 8'h76;
// billentyűkódok
localparam SC_A = 8'h1C; // A
localparam SC_D = 8'h23; // D
localparam SC_N4 = 8'h6B; // NumPad 4
localparam SC_N6 = 8'h74; // NumPad 6
localparam SC_N = 8'h31; // N
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;
always @(posedge clk)
begin
@ -38,6 +41,7 @@ end
wire [7:0] b0 = shr[7:0];
wire [7:0] b1 = shr[15:8];
// billentyű-mintaillesztés
always @(posedge clk)
begin
if (rst)
@ -46,11 +50,11 @@ begin
end
else
begin
if ((b0 == SC_A) && (b1 != SC_REL))
if ((b0 == SC_A) && (b1 != SC_REL)) // A lenyomva
begin
key_states[0] <= 1'b1;
end
else if ((b0 == SC_A) && (b1 == SC_REL))
else if ((b0 == SC_A) && (b1 == SC_REL)) // A felengedve
begin
key_states[0] <= 1'b0;
end

View File

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

View File

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

39
vga.v
View File

@ -1,8 +1,8 @@
`timescale 1ns/1ps
module vga #(
parameter COLS = 1024,
parameter ROWS = 768,
parameter COLS = 1024, // oszlopok száma a képernyőn
parameter ROWS = 768, // sorok száma a képernyőn
parameter H_FRONT_PORCH = 24,
parameter H_SYNC_PULSE = 136,
parameter H_BACK_PORCH = 160,
@ -13,23 +13,27 @@ module vga #(
parameter V_SYNC_NEG = 1'b1,
parameter OVERSCAN = 1,
// színek (BGR)
parameter COL_POD1 = 3'b001,
parameter COL_POD2 = 3'b010,
parameter COL_BALL = 3'b011,
parameter COL_BG = 3'b000,
// platformok tulajdonságai
parameter POD_WIDTH = COLS / 6,
parameter POD_HEIGHT = ROWS / 32,
parameter POD_TOP = ROWS - 50,
// középső fal tulajdonságai
parameter WALL_HALF_WIDTH = 4,
parameter WALL_HEIGHT = ROWS / 3,
// bithosszok
parameter N_COLS = $clog2(H_FULL),
parameter N_ROWS = $clog2(V_FULL)
)(
input wire pclk, // pixel órajel
input wire sclk, // lassú órajel
input wire pclk, // pixel órajel (65MHz)
input wire sclk, // lassú órajel (1MHz)
input wire rst, // reset
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 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 = {
25'b0000000000000000000000000,