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

114 lines
1.5 KiB
Verilog

// PS/2 vezérlő
module ps2_host (
input wire clk, // órajel (1MHz)
input wire rst, // szinkron reset
input wire ps2_ck, // PS/2 órajel
input wire ps2_dat, // PS/2 adat
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
if (rst)
begin
prev_ps2_ck <= 1'b1;
end
else
begin
prev_ps2_ck <= ps2_ck;
end
end
wire ck_fallen = !prev_ps2_ck && !ps2_ck;
wire ck_risen = prev_ps2_ck && ps2_ck;
reg ck_state, prev_ck_state;
always @(posedge clk)
begin
if (rst)
begin
ck_state <= 1'b1;
prev_ck_state <= 1'b1;
end
else
begin
if (ck_state && ck_fallen)
begin
ck_state <= 1'b0;
end
else if (!ck_state && ck_risen)
begin
ck_state <= 1'b1;
end
prev_ck_state <= ck_state;
end
end
wire ck_falling = prev_ck_state && !ck_state;
// bitszámláló
reg [3:0] cntr;
always @(posedge clk)
begin
if (rst)
begin
cntr <= 4'b0;
end
else if (ck_falling)
begin
cntr <= cntr + 4'b1;
end
else if (cntr == 4'd11)
begin
cntr <= 4'b0;
end
end
// adat beléptetése
reg [10:0] shr;
always @(posedge clk)
begin
if (rst)
begin
shr <= 11'b0;
end
else if (ck_falling)
begin
shr <= { ps2_dat, shr[10:1] };
end
end
// adat kiadása
always @(posedge clk)
begin
if (rst)
begin
data <= 8'b0;
valid <= 1'b0;
end
else
begin
if (valid && ack)
begin
valid <= 1'b0;
end
if (cntr == 4'd11)
begin
data <= shr[8:1];
valid <= 1'b1;
end
end
end
endmodule