module matrix_kbd (input CLK, input RESET, input FREEZE, inout [15:0] ROWS, input [7:0] COLUMNS, output [7:0] kbd_r0, kbd_r2, kbd_r3, kbd_r4, kbd_r5, kbd_r6, kbd_r7, output INT); // * - ESC (29), 7 - F1 (3A), 4 - F2 (3B), 1 - NUM_LOCK (53) // 0 - CAPS LOCK (39), 8 - R (15), 5 - BACKSPACE (2A), 2 - ENTER (58) // # - LSHIFT (E1), 9 - C (06), 6 - V (19), 3 - DELETE (4C) // D - LCTRL (E0), C - LALT (E2), B - SPACE (2C), A - RGUI (E7) parameter ONE_ROW_TIME = 12000; parameter ROW_STT_PROCESS_TIME = 11000; parameter ONE_COLUMN_PROCESS_TIME = 50; reg [15:0] row_time = 0; reg [3:0] row_counter; reg [7:0] temp; reg [7:0] i; reg [7:0] report [6:0]; // NO BYTE 2 reg isr; reg [15:0] ROWS_EN = 0; reg [15:0] ROWS_OUT = 0; wire [15:0] ROWS_IN; reg [7:0] COLS_SHADOW; reg [7:0] kbd_code; wire [7:0] kbd_code_hid; reg is_pressed; reg ram_wr; reg [8:0] ram_adr; wire [7:0] ram_rd; reg [8:0] init_ram_cnt; always @ (negedge CLK) begin COLS_SHADOW <= COLUMNS; end ram RAM (CLK, ram_wr, ram_adr, temp, ram_adr, ram_rd);//module ram(input clk, wen, input [8:0] addr, input [7:0] wdata, output [7:0] rdata); always @ (posedge CLK) begin if (RESET == 0) begin for (i = 0; i < 6; i = i + 1) report[i] = 0; isr = 0; init_ram_cnt = 0; end else begin if (FREEZE == 0) begin if (init_ram_cnt < 256) begin ram_wr = 1; ram_adr = init_ram_cnt; temp = 255; init_ram_cnt = init_ram_cnt + 1; end else if (init_ram_cnt == 256) begin ram_wr = 0; init_ram_cnt = init_ram_cnt + 1; end else begin if (row_time == ONE_ROW_TIME) begin ram_wr = 0; row_time <= 0; row_counter = row_counter + 1; ROWS_EN = 1 << row_counter; ram_adr = row_counter; end else row_time <= row_time + 1; // ROW 0 - D, 1 - A, 2 - C, 3 - B if (row_time == (ROW_STT_PROCESS_TIME - 1)) temp = ram_rd; if (row_time == (ROW_STT_PROCESS_TIME + ONE_COLUMN_PROCESS_TIME * 7 + 1)) ram_wr = 1; if (row_time == (ROW_STT_PROCESS_TIME + ONE_COLUMN_PROCESS_TIME * 0)) check_column (0); else if (row_time == (ROW_STT_PROCESS_TIME + ONE_COLUMN_PROCESS_TIME * 2)) check_column (2); else if (row_time == (ROW_STT_PROCESS_TIME + ONE_COLUMN_PROCESS_TIME * 1)) check_column (1); else if (row_time == (ROW_STT_PROCESS_TIME + ONE_COLUMN_PROCESS_TIME * 3)) check_column (3); else if (row_time == (ROW_STT_PROCESS_TIME + ONE_COLUMN_PROCESS_TIME * 4)) check_column (4); else if (row_time == (ROW_STT_PROCESS_TIME + ONE_COLUMN_PROCESS_TIME * 5)) check_column (5); else if (row_time == (ROW_STT_PROCESS_TIME + ONE_COLUMN_PROCESS_TIME * 6)) check_column (6); else if (row_time == (ROW_STT_PROCESS_TIME + ONE_COLUMN_PROCESS_TIME * 7)) check_column (7); else kbd_code = 255; // START PACK I2C_HID REPORT if (kbd_code_hid != 0) begin if ((kbd_code_hid > 8'hDF) && (kbd_code_hid < 8'hE8)) begin if (is_pressed) report [0] = report [0] | (1<<(kbd_code_hid & 8'h07)); else report [0] <= report [0] & (~(1<<(kbd_code_hid & 8'h07))); end else begin if (is_pressed) begin isr = 1; if (report [ 1 ] == 0) report [ 1 ] <= kbd_code_hid; else if (report [ 2 ] == 0) report [ 2 ] <= kbd_code_hid; else if (report [ 3 ] == 0) report [ 3 ] <= kbd_code_hid; else if (report [ 4 ] == 0) report [ 4 ] <= kbd_code_hid; else if (report [ 5 ] == 0) report [ 5 ] <= kbd_code_hid; else if (report [ 6 ] == 0) report [ 6 ] <= kbd_code_hid; else isr = 0; end else begin for (i = 1; i < 7; i = i + 1) begin if (report [i] == kbd_code_hid/*kbd_code*/) begin report [i] = 0; isr = 1; end end end end end // END OF KBD CODE SEND ALG else isr <= 0; end end end end task check_column; input [2:0] column; begin if (COLS_SHADOW[column] != temp[column]) begin kbd_code = row_counter*8 + column; if ((COLS_SHADOW[column] == 0) && (temp[column] == 1)) is_pressed = 1; else is_pressed = 0; end else kbd_code = 255; temp[column] = COLS_SHADOW[column]; end endtask assign kbd_r0 = report[0]; assign kbd_r2 = report[1]; assign kbd_r3 = report[2]; assign kbd_r4 = report[3]; assign kbd_r5 = report[4]; assign kbd_r6 = report[5]; assign kbd_r7 = report[6]; assign INT = isr; SB_RAM40_4K #( .INIT_0(256'h0000_0001_0001_0001_00E7_0058_004C_0053__0001_0001_0001_0001_00E0_0039_00E1_0029), // ROW 0-1 .INIT_1(256'h0001_0001_0001_0001_002C_002A_0019_003B__0001_0001_0001_0001_00E2_0015_0006_003A), // ROW 2-3 .INIT_2(256'h0001_0001_0001_0001_002C_002A_0019_003B__0001_0001_0001_0001_00E2_0015_0006_003A), // ROW 4-5 .INIT_3(256'h0001_0001_0001_0001_002C_002A_0019_003B__0001_0001_0001_0001_00E2_0015_0006_003A), // ROW 6-7 .INIT_4(256'h0001_0001_0001_0001_002C_002A_0019_003B__0001_0001_0001_0001_00E2_0015_0006_003A), // ROW 8-9 .INIT_5(256'h0001_0001_0001_0001_002C_002A_0019_003B__0001_0001_0001_0001_00E2_0015_0006_003A), // ROW 10-11 .INIT_6(256'h0001_0001_0001_0001_002C_002A_0019_003B__0001_0001_0001_0001_00E2_0015_0006_003A), // ROW 12-13 .INIT_7(256'h0001_0001_0001_0001_002C_002A_0019_003B__0001_0001_0001_0001_00E2_0015_0006_003A), // ROW 14-15 .INIT_8(256'h0001_0001_0001_0001_002C_002A_0019_003B__0001_0001_0001_0001_00E2_0015_0006_003A), // ROW 16-17 .INIT_9(256'h0001_0001_0001_0001_002C_002A_0019_003B__0001_0001_0001_0001_00E2_0015_0006_003A), // ROW 18-19 .WRITE_MODE(1), .READ_MODE(1) ) kbd_codes ( .RDATA(kbd_code_hid), .RADDR(kbd_code), .RCLK(CLK), .RCLKE(1'b1), .RE(1'b1), .WADDR(8'b0), .WCLK(1'b0), .WCLKE(1'b0), .WDATA(8'b0), .WE(1'b0) ); SB_IO #( .PIN_TYPE(6'b 1010_01), .PULLUP(1'b 0) ) rows_io [15:0] ( .PACKAGE_PIN(ROWS), .OUTPUT_ENABLE(ROWS_EN), .D_OUT_0(ROWS_OUT), .D_IN_0(ROWS_IN) ); endmodule