pong-verilog/pp_top.v
2025-11-05 07:26:15 +01:00

218 lines
3.1 KiB
Verilog

module pp_top(
input wire clk, // 50MHz-es órajel
input wire rst_n, // negált reset
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
wire rst = ~rst_n;
wire [3:0] btns = ~btns_n;
assign leds_n = ~leds;
// 65MHz és 1MHz órajelgenerátor
wire clk65M;
wire clk1M;
wire locked;
reg srst; // szinkron reset
// órajel-előállító (beépített) modul
clk_gen main_clk_gen(
.areset(rst),
.inclk0(clk),
.c0(clk65M),
.c1(clk1M),
.locked(locked)
);
// -----------
// PS/2 vezérlő
wire [7:0] data;
wire valid;
ps2_host ps2(
.clk(clk1M),
.rst(srst),
.ps2_ck(ps2_ck),
.ps2_dat(ps2_dat),
.data(data),
.valid(valid),
.ack(1'b1)
);
// -----------
// Billentyű-állapot figyelő
wire [6:0] ks;
key_matcher km(
.clk(clk1M),
.rst(rst),
.scan_code(data),
.sc_valid(valid),
.key_states(ks)
);
// -----------
// Játéklogika
wire [9:0] ballx;
wire [9:0] bally;
wire [9:0] pod1x;
wire [9:0] pod2x;
wire [7:0] score1;
wire [7:0] score2;
wire hit;
wire miss;
game_controller game (
.clk(clk1M),
.rst(srst),
.start(ks[4]),
.acknowledge(ks[5]),
.pod1x(pod1x),
.pod2x(pod2x),
.ballx(ballx),
.bally(bally),
.move_pod1_en(ks[0] ^ ks[1]),
.move_pod1_dir(ks[1]),
.move_pod2_en(ks[2] ^ ks[3]),
.move_pod2_dir(ks[3]),
.score1(score1),
.score2(score2),
.clear_score(ks[6]),
.hit(hit),
.miss(miss)
);
// Hangvezérlő
wire beep;
assign beep_n = ~beep;
beep beeper(
.clk(clk1M),
.rst(srst),
.hit(hit),
.miss(miss),
.beep(beep)
);
// VGA renderer
wire hsync;
wire vsync;
wire [2:0] rgb;
vga /* #(
.COLS(800),
.ROWS(600),
.H_FRONT_PORCH(40),
.H_SYNC_PULSE(128),
.H_BACK_PORCH(88),
.V_FRONT_PORCH(1),
.V_SYNC_PULSE(4),
.V_BACK_PORCH(23),
.H_SYNC_NEG(0),
.V_SYNC_NEG(0)
) */ vga (
.pclk(clk65M),
.sclk(clk1M),
.rst(srst),
.hsync(hsync),
.vsync(vsync),
.rgb(rgb),
.pod1x(pod1x),
.pod2x(pod2x),
.ballx(ballx),
.bally(bally)
);
assign vga_sigs = { hsync, vsync, rgb };
// -----------
wire [3:0] d0;
wire [3:0] d1;
wire [3:0] d2;
wire [3:0] d3;
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),
.d0(d0),
.d1(d1),
.d2(d2),
.d3(d3),
.dps(4'b0100),
.segs_n(segs_n),
.digs_n(digs_n)
);
// -----------
// kb. 1Hz osztó
reg [19:0] cntr;
always @(posedge clk1M, posedge rst)
begin
if (rst)
begin
cntr <= 0;
end
else
begin
cntr <= cntr + 1;
end
end
wire tc = &cntr;
// reset-generátor
reg reset_issued;
always @(posedge clk1M, posedge rst)
begin
if (rst)
begin
reset_issued <= 1'b0;
srst <= 1'b0;
end
else if (tc && !reset_issued)
begin
srst <= 1'b1;
reset_issued <= 1'b1;
end
else
begin
srst <= 1'b0;
end
end
// -----------
wire [3:0] leds = ks[3:0];
endmodule