From aca4a16dbbdcc15d2e46a99fcf579288fa97d4e5 Mon Sep 17 00:00:00 2001
From: Fang Lu <cc2lufang@gmail.com>
Date: Sat, 18 Nov 2017 17:16:17 -0600
Subject: [PATCH] ps2kb - save keycodes into event registers

---
 input/{ps2.sv => ps2kb.sv} | 80 +++++++++++++++++++++++++++++---------
 1 file changed, 62 insertions(+), 18 deletions(-)
 rename input/{ps2.sv => ps2kb.sv} (71%)

diff --git a/input/ps2.sv b/input/ps2kb.sv
similarity index 71%
rename from input/ps2.sv
rename to input/ps2kb.sv
index a8af9ad..79c1630 100644
--- a/input/ps2.sv
+++ b/input/ps2kb.sv
@@ -19,7 +19,7 @@
  *
  */
 
-module ps2 (
+module ps2kb (
 	// Avalon Clock Input
 	input logic CLK,
 
@@ -39,12 +39,12 @@ module ps2 (
 	inout wire PS2_CLK, PS2_DATA, // Exported Conduit Signal to LEDs
 
 	// Debug exports
-	output logic [7:0] debug_keycode,
-	output logic [2:0] debug_state, debug_counter
+	// output logic [7:0] debug_keycode,
+	// output logic [2:0] debug_state, debug_counter
 );
 
 // Debug
-logic [7:0] debug_keycode_next;
+// logic [7:0] debug_keycode_next;
 
 // Static assignments
 
@@ -53,17 +53,21 @@ assign PS2_CLK = (clock_we) ? clock_out : 1'bZ;
 assign PS2_DATA = (data_we) ? data_out : 1'bZ;
 
 enum logic [2:0] {
-	idle, b_data, b_parity, b_end, b_enqueue, b_error
+	idle, b_data, b_parity, b_end, b_enqueue, b_error, b_fin
 } state, state_next;
 logic [2:0] counter, counter_next;
 logic clock_wait, clock_wait_next, error, error_next;
 
-assign debug_state = state;
-assign debug_counter = counter;
+// assign debug_state = state;
+// assign debug_counter = counter;
 
 // Avalon MM functionalities
 
-logic[7:0] keydown[8], keydown_next[8], keyup[8], keyup_next[8], keycode, keycode_next;
+logic[7:0] keydown[8], keydown_next[8], keyup[8], keyup_next[8];
+logic[7:0] keycode, keycode_next, keycode_out;
+logic is_release, is_release_next, is_e0code, is_e0code_next;
+
+assign keycode_out = {keycode[7] | is_e0code, keycode[6:0]};
 
 always_ff @(posedge CLK) begin
 	if(RESET) begin
@@ -80,7 +84,10 @@ always_ff @(posedge CLK) begin
 			clock_wait <= 1'b0;
 			error <= 0;
 
-			debug_keycode <= 8'hCC;
+			is_release <= 0;
+			is_e0code <= 0;
+
+			// debug_keycode <= 8'hCC;
 		end
 	end else begin
 		for (int i = 0; i < 4; i++) begin
@@ -96,7 +103,10 @@ always_ff @(posedge CLK) begin
 			clock_wait <= clock_wait_next;
 			error <= error_next;
 
-			debug_keycode <= debug_keycode_next;
+			is_release <= is_release_next;
+			is_e0code <= is_e0code_next;
+
+			// debug_keycode <= debug_keycode_next;
 		end
 	end
 end
@@ -135,6 +145,9 @@ always_comb begin
 	keycode_next = keycode;
 	error_next = error;
 
+	is_release_next = is_release;
+	is_e0code_next = is_e0code;
+
 	clock_we = 1'b0;
 	data_we = 1'b0;
 	unique case (state)
@@ -157,7 +170,8 @@ always_comb begin
 		b_data: begin
 			if (!clock_in && !clock_wait) begin
 				clock_wait_next = 1'b1;
-				keycode_next[counter] = data_in;
+				// keycode_next[counter] = data_in;
+				keycode_next = {keycode[6:0], data_in};
 			end
 			if (clock_in && clock_wait) begin
 				clock_wait_next = 1'b0;
@@ -184,24 +198,54 @@ always_comb begin
 		b_end: begin
 			if (!clock_in && !clock_wait) begin
 				clock_wait_next = 1'b1;
-				if (data_in != keycode[0] ^ keycode[1] ^ keycode[2] ^
-					keycode[3] ^ keycode[4] ^ keycode[5] ^ keycode[6] ^
-					keycode[7])
+				if (data_in != 1'b1)
 					error_next = 1'b1;
 			end
 			if (clock_in && clock_wait) begin
 				clock_wait_next = 1'b0;
-				state_next = b_enqueue;
+				counter_next = 0;
+				if (error)
+					state_next = b_error;
+				else
+					state_next = b_enqueue;
+				if (keycode == 8'hE0) begin
+					is_e0code_next = 1;
+					state_next = idle;
+				end
+				if (keycode == 8'hF0) begin
+					is_release_next = 1;
+					state_next = idle;
+				end
 			end
 		end
 
 		b_enqueue: begin
-			debug_keycode_next = keycode;
-			state_next = idle;
+			// debug_keycode_next = keycode;
+			if (is_release) begin
+				if (keyup[counter] == 8'h0) begin
+					keyup_next[counter] = keycode_out;
+					state_next = b_fin;
+				end else
+					state_next = b_enqueue;
+			end else begin
+				if (keydown[counter] == 8'h0) begin
+					keydown_next[counter] = keycode_out;
+					state_next = b_fin;
+				end else
+					state_next = b_enqueue;
+			end
+			counter_next = counter + 1;
 		end
 
 		b_error: begin
-			debug_keycode_next = 8'hDD;
+			// debug_keycode_next = 8'hDD;
+			// Just ignore any error
+			state_next = b_fin;
+		end
+
+		b_fin: begin
+			is_e0code_next = 0;
+			is_release_next = 0;
 			state_next = idle;
 		end
 
-- 
GitLab