Files
APS/Labs/12. Peripheral units/PS2Receiver.sv
2023-11-26 15:20:45 +03:00

91 lines
1.6 KiB
Systemverilog

module PS2Receiver(
input logic clk_i,
input logic kclk_i,
input logic kdata_i,
output logic [7:0] keycodeout_o,
output keycode_valid_o
);
logic flag;
logic [3:0] flag_shift;
logic kclkf, kdataf;
logic [3:0] cnt;
assign keycode_valid_o = flag_shift[0] && !flag_shift[2];
initial begin //for tb
cnt = 0;
keycodeout_o = 0;
flag_shift = 0;
flag = 0;
end
debouncer debounce(
.clk(clk_i),
.I0(kclk_i),
.I1(kdata_i),
.O0(kclkf),
.O1(kdataf)
);
always@(posedge clk_i) begin
flag_shift <= (flag_shift << 1) + flag;
end
always_ff @(negedge(kclkf))begin
case(cnt)
0:;
1:keycodeout_o[0]<=kdataf;
2:keycodeout_o[1]<=kdataf;
3:keycodeout_o[2]<=kdataf;
4:keycodeout_o[3]<=kdataf;
5:keycodeout_o[4]<=kdataf;
6:keycodeout_o[5]<=kdataf;
7:keycodeout_o[6]<=kdataf;
8:keycodeout_o[7]<=kdataf;
//TODO ADD PARITY CHECK
9:begin
flag<=1'b1;
end
10:flag<=1'b0;
default: cnt <= 0;
endcase
if(cnt<=9) cnt<=cnt+1;
else if(cnt==10) cnt<=0;
end
endmodule
module debouncer(
input logic clk,
input logic I0,
input logic I1,
output logic O0,
output logic O1
);
logic [4:0]cnt0, cnt1;
logic Iv0=0,Iv1=0;
logic out0, out1;
always_ff @(posedge(clk))begin
if (I0==Iv0) begin
if (cnt0==19)O0<=I0;
else cnt0<=cnt0+1;
end
else begin
cnt0<=5'd0;
Iv0<=I0;
end
if (I1==Iv1)begin
if (cnt1==19)O1<=I1;
else cnt1<=cnt1+1;
end
else begin
cnt1<=5'd0;
Iv1<=I1;
end
end
endmodule