Untitled
unknown
plain_text
3 years ago
3.9 kB
7
Indexable
`timescale 1ns / 1ps›
`default_nettype none
module ps2_decoder( input wire clk_in,
input wire rst_in,
input wire ps_data_in,
input wire ps_clk_in,
output logic [7:0] code_out,
output logic code_valid_out
);
logic [3:0] parity_sum; //helper variable that stores the sum of the digits of the input message
logic [7:0] buffer;
logic [3:0] rising_edge;
logic [3:0] falling_edge;
logic ps2_clk_old;
logic ps2_clk_new;
logic state;
logic loop; //high if we went through the loop already, low otherwise
logic start_check;
localparam HIGH = 1'b1 ;
localparam LOW = 1'b0;
always_ff @(posedge clk_in) begin: RSTLOOP
if (rst_in == 1'b1) begin
rising_edge <= 4'b0000;
falling_edge <= 4'b0000;
loop <= 1'b0;
start_check <= 1'b0;
parity_sum <= 4'b0000;
code_valid_out <= 1'b0;
code_out <= 8'b0000_0000;
end else begin
end
end
always_ff @(posedge clk_in) begin: CLKLOOP
ps2_clk_new <= ps_clk_in;
ps2_clk_old <= ps2_clk_new;
if (ps2_clk_old == 1'b0 && ps2_clk_new == 1'b1) begin //rising edge
rising_edge <= rising_edge + 1'b1;
end
if (ps2_clk_old == 1'b1 && ps2_clk_new == 1'b0) begin //falling edge
falling_edge <= falling_edge + 1'b1;
end
if (ps2_clk_old == 1'b1 && ps2_clk_new == 1'b1) begin
state <= HIGH;
end
if (ps2_clk_old == 1'b0 && ps2_clk_new == 1'b0) begin
state <= LOW;
end else begin
end
end
always_ff @(posedge clk_in) begin: MAINLOOP
if (falling_edge == 4'b0001 && ps_data_in == 1'b0 && loop == 1'b0) begin //first falling edge
loop <= 1'b1;
start_check <= 1'b1;
end if (falling_edge == 4'b0010 && loop == 1'b1 && start_check == 1'b1) begin //second falling edge
buffer[0] <= ps_data_in;
parity_sum <= parity_sum + ps_data_in;
loop <= 1'b0;
end if (falling_edge == 4'b0011 && loop == 1'b0 && start_check == 1'b1) begin //3
buffer[1] <= ps_data_in;
parity_sum <= parity_sum + ps_data_in;
loop <= 1'b1;
end if (falling_edge == 4'b0100 && loop == 1'b1 && start_check == 1'b1) begin //4
buffer[2] <= ps_data_in;
parity_sum <= parity_sum + ps_data_in;
loop <= 1'b0;
end if (falling_edge == 4'b0101 && loop == 1'b0 && start_check == 1'b1) begin //5
buffer[3] <= ps_data_in;
parity_sum <= parity_sum + ps_data_in;
loop <= 1'b1;
end if (falling_edge == 4'b0110 && loop == 1'b1 && start_check == 1'b1) begin //6
buffer[4] <= ps_data_in;
parity_sum <= parity_sum + ps_data_in;
loop <= 1'b0;
end if (falling_edge == 4'b0111 && loop == 1'b0 && start_check == 1'b1) begin //7
buffer[5] <= ps_data_in;
parity_sum <= parity_sum + ps_data_in;
loop <= 1'b1;
end if (falling_edge == 4'b1000 && loop == 1'b1 && start_check == 1'b1) begin //8
buffer[6] <= ps_data_in;
parity_sum <= parity_sum + ps_data_in;
loop <= 1'b0;
end if (falling_edge == 4'b1001 && loop == 1'b0 && start_check == 1'b1) begin //9
buffer[7] <= ps_data_in;
parity_sum <= parity_sum + ps_data_in;
loop <= 1'b1;
end if (falling_edge == 4'b1010 && loop == 1'b1 && start_check == 1'b1) begin //10
code_out <= buffer;
loop <= 1'b0;
if (parity_sum % 2'b01 == 1'b0) begin
if (ps_data_in == 1'b0) begin
code_valid_out <= 1'b0;
end if (ps_data_in == 1'b1) begin
code_valid_out <= 1'b1;
end
end if (parity_sum % 2'b01 == 1'b1) begin
if (ps_data_in == 1'b0) begin
code_valid_out <= 1'b1;
end if (ps_data_in == 1'b1) begin
code_valid_out <= 1'b0;
end
end
end if (falling_edge == 4'b1011 && loop == 1'b0 && ps_data_in == 1'b1 && start_check == 1'b1) begin //11
code_valid_out <= 1'b0;
loop <= 1'b1;
end if (rising_edge == 4'b1011 && loop == 1'b1 && start_check == 1'b1) begin //11.5
rising_edge <= 4'b0000;
falling_edge <= 4'b0000;
loop <= 1'b0;
parity_sum <= 4'b0000;
start_check <= 1'b0;
end
end
endmodule
`default_nettype wireEditor is loading...