module top (input CLK, output LED1, LED2, LED3, LED4, LED5, input SCL, inout SDA, /*output ACK,*/ output INTERRUPT, input COM_RX, output COM_TX, COM_DCD, COM_DSR, COM_RTS, input [7:0] KBD_COLUMNS, inout [15:0] KBD_ROWS); wire RESET; reg [3:0] rststate = 0; assign RESET = &rststate; //reg [7:0] I2C_TX; // TRANSMITTED TO MASTER wire [7:0] I2C_TX; reg [7:0] I2C_TX_DESC; //reg [7:0] I2C_TX_REPORT; wire [7:0] I2C_RX; // RECEIVED FROM MASTER wire I2C_TRANS, I2C_READ, I2C_ACK, I2C_ACK_MSTR_CTRL, I2C_WR; wire [7:0] I2C_COUNTER; i2c_slave I2C (CLK, RESET, SCL, SDA, I2C_TRANS, I2C_READ, I2C_ACK, I2C_WR, //I2C_ACK_MSTR_CTRL, I2C_RX, I2C_TX, I2C_COUNTER); reg UART_WR, UART_DTR, UART_RTS, UART_DCD; reg [7:0] UART_TX_DATA; wire UART_ACTIVE, UART_TX_LINE; initial begin UART_WR = 0; UART_RTS = 1; UART_DTR = 0; UART_DCD = 0; end uart UART (CLK, RESET, UART_WR, UART_TX_DATA, UART_ACTIVE, UART_TX_LINE); //wire [63:0] kbd_report; wire [7:0] kbd_report [6:0]; wire ISR; reg INT = 1; // INTERRUPT LINE TO HOST reg [19:0] int_tmr; reg KBD_FREEZE = 1; // LOGIC REG FOR BLOCK KBD ACTIVITY WHEN I2C IS WORKING //reg IS_EMPTY_REPORT = 0; // REGISTER FOR CORRECT START (HOST MUST REQUEST EMPTY REGISTER AFTER INTERRUPT. THEN INTERRRUPT SET TO 1) matrix_kbd KEYBOARD (CLK, RESET, 0 /*KBD_FREEZE*/, KBD_ROWS, KBD_COLUMNS, kbd_report[0], kbd_report[1], kbd_report[2], kbd_report[3], kbd_report[4], kbd_report[5], kbd_report[6], ISR); descriptors I2C_HID_DESC (CLK, RESET, I2C_WR, I2C_OUTPUT_TYPE[1:0], I2C_COUNTER, I2C_TX_DESC/*, kbd_report*/); //reg [7:0] ring_report [(8*8-1):0]; reg [7:0] init_ram_cnt; reg [3:0] ring_wr, ring_rd; reg [3:0] wr_cnt; reg report_wr_en; reg [7:0] report_data_wadr, report_data_radr, report_data_wr; wire [7:0] report_data_rd; ram REPORT_DATA (CLK, report_wr_en, report_data_wadr, report_data_wr, report_data_radr, report_data_rd); assign I2C_TX = (I2C_TX_DESC & I2C_OUT_DESC_MASK) | (/*I2C_TX_REPORT*/report_data_rd & (~I2C_OUT_DESC_MASK)); //parameter MAX_INPUT_LEN = 10; //reg [7:0] I2C_INPUT_DATA [MAX_INPUT_LEN:0]; reg [7:0] temp_output_report; reg [3:0] i2c_input_data_type; // 0 - UNKNOWN, 1 - I2C_HID_DESC_REQUEST, 2 - HID_REPORT_DESC_REQUEST, 3 - INPUT_REPORT_REQUEST, 4 - OUTPUT_REPORT_SET // 5 - RESET, 6 - GET_INPUT_REPORT, 7 - SET_OUTPUT_REPORT reg [7:0] I2C_INPUT_LEN = 0; reg [2:0] I2C_OUTPUT_TYPE = 0; // 0 - ALL ZERO DATA, 1 - I2C HID DESCR, 2 - OUTPUT REPORT, 3 - HID REPORT DESCR reg [7:0] I2C_OUT_DESC_MASK = 0; reg [7:0] KBD_LED_STATUS = 0; reg last_wr = 0, last_trans = 0, last_uart_active = 0, last_isr = 0, uart_double_ff = 0; always @(posedge CLK) begin // RESET LOGIC rststate <= rststate + !RESET; if (RESET == 0) begin I2C_OUTPUT_TYPE = 3;//0; I2C_OUT_DESC_MASK = 0; KBD_LED_STATUS = 5; // BIT 0 - NUM LOCK, BIT 1 - CAPS LOCK, BIT 2 - SCROOL LOCK uart_double_ff = 0; last_trans = 0; last_uart_active = 0; last_isr = 0; I2C_INPUT_LEN = 0; INT = 1; int_tmr = 0; UART_WR = 0; ring_wr = 0; ring_rd = 15; wr_cnt = 0; init_ram_cnt = 0; end // NOT RESET MODE LOGIC else begin if (init_ram_cnt < 170) begin report_wr_en = 1; if (init_ram_cnt < 10) report_data_wadr = 0; else report_data_wadr = init_ram_cnt - 10; report_data_wr = 0;//report_data_adr + 1; init_ram_cnt = init_ram_cnt + 1; end else if (init_ram_cnt == 170) begin report_wr_en = 0; init_ram_cnt = init_ram_cnt + 1; end else if ((last_isr == 0) && (ISR == 1)/* && (INT == 1)*/) begin // INTERRUPT FROM KEYBOARD if ((ring_wr + 1) != ring_rd) ring_wr = ring_wr + 1; report_wr_en = 1; report_data_wadr = ring_wr * 10; report_data_wr = 10;//kbd_report [0]; wr_cnt = 1; INT = 0; I2C_OUTPUT_TYPE = 3; I2C_OUT_DESC_MASK = 8'h00; last_isr = ISR; end else if ((last_isr == 1) && (ISR == 0)) last_isr = ISR; else if (wr_cnt != 0) begin if (wr_cnt == 10) begin wr_cnt = 0; report_wr_en = 0; end else begin report_data_wadr = ring_wr * 10 + wr_cnt; if ((wr_cnt == 1) || (wr_cnt == 3)) report_data_wr = 0; else if (wr_cnt == 2) report_data_wr = kbd_report [wr_cnt - 2]; else report_data_wr = kbd_report [wr_cnt - 3]; wr_cnt = wr_cnt + 1; end end else if ((last_wr == 0) && (I2C_WR == 1)) begin // I2C NEW BYTE TX/RX I2C_INPUT_LEN = I2C_COUNTER - 1; if (I2C_READ == 0) begin // I2C_FROM_HOST if (I2C_COUNTER == 2) begin if ((I2C_RX > 5) || (I2C_RX < 1)) i2c_input_data_type = 0; else i2c_input_data_type = I2C_RX; end else if (I2C_COUNTER == 3) begin if (I2C_RX != 0) i2c_input_data_type = 0; end else if (I2C_COUNTER == 4) begin if (i2c_input_data_type == 5) begin case (I2C_RX) 0: i2c_input_data_type = 5; 16: i2c_input_data_type = 6; 32: i2c_input_data_type = 7; default: i2c_input_data_type = 0; endcase end end else if (I2C_COUNTER == 5) begin if (((i2c_input_data_type == 5) && (I2C_RX != 1)) || ((i2c_input_data_type == 6) && (I2C_RX != 2)) || ((i2c_input_data_type == 7) && (I2C_RX != 3))) i2c_input_data_type = 0; end else if (I2C_COUNTER == 6) begin if (i2c_input_data_type == 4) temp_output_report = I2C_RX; else if (((i2c_input_data_type == 6) || (i2c_input_data_type == 7)) && (I2C_RX != 6)) i2c_input_data_type = 0; end else if (I2C_COUNTER == 7) begin if (((i2c_input_data_type == 6) || (i2c_input_data_type == 7)) && (I2C_RX != 0)) i2c_input_data_type = 0; end else if (I2C_COUNTER == 10) begin if (i2c_input_data_type == 7) temp_output_report = I2C_RX; end end else begin // I2C_TO_HOST if (I2C_OUTPUT_TYPE == 3) begin //if ((I2C_COUNTER < 2) || (I2C_COUNTER > (2 + 10 - 1))) // I2C_TX_REPORT <= 0; /*else */if (I2C_COUNTER == 2) begin if (ring_rd != ring_wr) ring_rd = ring_rd + 1; report_data_radr = ring_rd * 10; end else report_data_radr = report_data_radr + 1; //else if (I2C_COUNTER == 2) // I2C_TX_REPORT <= 10; //else if ((I2C_COUNTER == 3) || (I2C_COUNTER == 5)) begin // I2C_TX_REPORT <= 0; // if (ring_rd != ring_wr) // ring_rd = ring_rd + 1; // report_data_radr = ring_rd * 10; //end /*else if (I2C_COUNTER == 4) I2C_TX_REPORT <= kbd_report[0];*/ //else begin // I2C_TX_REPORT = report_data_rd; // report_data_radr = report_data_radr + 1; //I2C_TX_REPORT <= kbd_report[I2C_COUNTER - 5]; //end end //else // I2C_TX_REPORT <= 0; end last_wr = I2C_WR; end // I2C NEW BYTE TX/RX - END else if ((last_wr == 1) && (I2C_WR == 0)) begin // I2C_NEW_BYTE_NEGEDGE_FOR_UART UART_WR = 1; if (I2C_READ == 0) UART_TX_DATA = I2C_RX; else UART_TX_DATA = I2C_TX; last_wr = I2C_WR; end // I2C_NEW_BYTE_NEGEDGE_FOR_UART - END else if ((last_trans == 0) && (I2C_TRANS == 1)) begin // I2C_START_CONDITION OR REPEAT START (UART FF) i2c_input_data_type = 0; // UNKNOWN DATA IN uart_double_ff = 1; UART_TX_DATA = 8'hFF; UART_WR = 1; last_trans = I2C_TRANS; end // I2C_START_CONDITION (UART FF) - END else if ((last_trans == 1) && (I2C_TRANS == 0)) begin // I2C_STOP CONDITION (OR REPEAT START DETECTED) KBD_FREEZE <= 0; if (I2C_READ == 0) begin // DECODING PACKET RECEIVED FROM HOST if (((i2c_input_data_type < 4) && (I2C_INPUT_LEN != 2)) || ((i2c_input_data_type == 4) && (I2C_INPUT_LEN != 5)) || ((i2c_input_data_type == 5) && (I2C_INPUT_LEN != 4)) || ((i2c_input_data_type == 6) && (I2C_INPUT_LEN != 6)) || ((i2c_input_data_type == 7) && (I2C_INPUT_LEN != 9))) i2c_input_data_type = 0; if ((i2c_input_data_type == 1) || (i2c_input_data_type == 2) || (i2c_input_data_type == 3)) I2C_OUTPUT_TYPE = i2c_input_data_type; else if ((i2c_input_data_type == 4) || (i2c_input_data_type == 7)) KBD_LED_STATUS = temp_output_report; else if (i2c_input_data_type == 6) I2C_OUTPUT_TYPE = 3; else if (i2c_input_data_type == 5) rststate <= 4'h0; // RESET COMMAND if ((I2C_OUTPUT_TYPE == 1) || (I2C_OUTPUT_TYPE == 2)) I2C_OUT_DESC_MASK = 8'hFF; else I2C_OUT_DESC_MASK = 8'h00; end // END OF I2C_READ == 0 else begin if (((I2C_OUTPUT_TYPE == 3) /*|| (I2C_OUTPUT_TYPE == 0)*/) && (I2C_INPUT_LEN > 1)) begin // DEACTIVATING INTERRRUPT IF HOST READ INPUT REPORT (LEN 10) AFTER INTERRUPT OR EMPTY DATA (>=2 BYTES) AFTER RESET //if (ring_rd == ring_wr) INT = 1; int_tmr = 0; //if (ring_rd != ring_wr) // ring_rd = ring_rd + 1; end I2C_OUTPUT_TYPE = 3; I2C_OUT_DESC_MASK = 0; end last_trans = I2C_TRANS; end // I2C_STOP CONDITION (OR REPEAT START DETECTED) - END else if ((last_uart_active == 1) && (UART_ACTIVE == 0)) begin if (uart_double_ff == 1) begin UART_WR = 1; UART_TX_DATA = 8'hFF; uart_double_ff = 0; end last_uart_active = UART_ACTIVE; end else if ((last_uart_active == 0) && (UART_ACTIVE == 1)) last_uart_active = UART_ACTIVE; else if (UART_WR == 1) UART_WR = 0; else if (int_tmr[19] != 1) int_tmr = int_tmr + 1; else if ((int_tmr[19] == 1) && (I2C_OUTPUT_TYPE == 3) && (I2C_TRANS == 0)) begin if (ring_rd != ring_wr) INT = 0; end /*else if (wr_cnt != 0) begin ring_report[ring_wr * 8 + wr_cnt] <= kbd_report[ (8 * wr_cnt + 7) : (8 * wr_cnt + 0) ]; wr_cnt = wr_cnt + 1; // if (wr_cnt == 0) // START ISR end*/ end end assign LED5 = I2C_TRANS; //assign LED5 = COM_RX; assign LED1 = INT ^ 1;//KBD_COLUMNS[0];//I2C_OUTPUT_TYPE[0];//I2C_RX[0]; //assign LED2 = I2C_OUTPUT_TYPE[0]; //assign LED3 = I2C_OUTPUT_TYPE[1]; assign LED2 = KBD_LED_STATUS[0]; assign LED3 = KBD_LED_STATUS[1]; assign LED4 = KBD_LED_STATUS[2];//KBD_FREEZE;//UART_ACTIVE; //assign LED3 = UART_ACTIVE; //assign LED4 = uart_double_ff; //assign ACK = I2C_READ;//I2C_WR; //I2C_ACK; assign COM_TX = UART_TX_LINE;//COM_RX; assign INTERRUPT = INT; assign COM_RTS = I2C_READ;//UART_RTS; assign COM_DSR = KBD_FREEZE;//UART_DTR; assign COM_DCD = INT; endmodule //top