You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
6.7 KiB
198 lines
6.7 KiB
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
|