Untitled

 avatar
unknown
plain_text
3 years ago
3.9 kB
4
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 wire
Editor is loading...