109 lines
1.3 KiB
Verilog
109 lines
1.3 KiB
Verilog
module ps2_host (
|
|
input wire clk,
|
|
input wire rst,
|
|
|
|
input wire ps2_ck,
|
|
input wire ps2_dat,
|
|
|
|
output reg [7:0] data,
|
|
output reg valid,
|
|
input wire ack
|
|
);
|
|
|
|
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;
|
|
|
|
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
|
|
|
|
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
|
|
|
|
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
|