diff --git a/Keyboard Sample Code/ip/Keyboard-Controller/keyboard_cntr_1.0/src/KeyboardCtrl.v b/Keyboard Sample Code/ip/Keyboard-Controller/keyboard_cntr_1.0/src/KeyboardCtrl.v index af04939..780f981 100755 --- a/Keyboard Sample Code/ip/Keyboard-Controller/keyboard_cntr_1.0/src/KeyboardCtrl.v +++ b/Keyboard Sample Code/ip/Keyboard-Controller/keyboard_cntr_1.0/src/KeyboardCtrl.v @@ -34,139 +34,135 @@ module KeyboardCtrl#( parameter NUM_LOCK = 8'h77; parameter SCR_LOCK = 8'h7E; + reg next_is_extend, next_is_break, next_valid; + wire [7:0] rx_data; wire rx_valid; wire busy; - reg [7:0] tx_data; - reg tx_valid; - reg [2:0] state; - reg [2:0] lock_status; + reg [7:0] tx_data, next_tx_data; + reg tx_valid, next_tx_valid; + reg [2:0] state, next_state; + reg [2:0] lock_status, next_lock_status; always @ (posedge clk, posedge rst) - if(rst) - key_in <= 0; - else if(rx_valid) - key_in <= rx_data; - else - key_in <= key_in; + if(rst) + key_in <= 0; + else if(rx_valid) + key_in <= rx_data; + else + key_in <= key_in; always @ (posedge clk, posedge rst)begin - if(rst)begin - state <= RESET; - is_extend <= 1'b0; - is_break <= 1'b1; - valid <= 1'b0; - lock_status <= 3'b0; - tx_data <= 8'h00; - tx_valid <= 1'b0; - end else begin - is_extend <= 1'b0; - is_break <= 1'b0; - valid <= 1'b0; - lock_status <= lock_status; - tx_data <= tx_data; - tx_valid <= 1'b0; - case(state) - RESET:begin - is_extend <= 1'b0; - is_break <= 1'b1; - valid <= 1'b0; - lock_status <= 3'b0; - tx_data <= CMD_RESET; - tx_valid <= 1'b0; - state <= SEND_CMD; - end - - SEND_CMD:begin - if(busy == 1'b0)begin - tx_valid <= 1'b1; - state <= WAIT_ACK; - end else begin - tx_valid <= 1'b0; - state <= SEND_CMD; - end - end - - WAIT_ACK:begin - if(rx_valid == 1'b1)begin - if(rx_data == RSP_ACK && tx_data == CMD_RESET)begin - state <= RESET_WAIT_BAT; - end else if(rx_data == RSP_ACK && tx_data == CMD_SET_STATUS_LEDS)begin - tx_data <= {5'b00000, lock_status}; - state <= SEND_CMD; - end else begin - state <= WAIT_KEYIN; - end - end else if(err == 1'b1)begin - state <= RESET; - end else begin - state <= WAIT_ACK; - end - end - - WAIT_KEYIN:begin - if(rx_valid == 1'b1 && rx_data == BREAK_CODE)begin - state <= GET_BREAK; - end else if(rx_valid == 1'b1 && rx_data == EXTEND_CODE)begin - state <= GET_EXTEND; - end else if(rx_valid == 1'b1)begin - state <= WAIT_KEYIN; - valid <= 1'b1; - end else if(err == 1'b1)begin - state <= RESET; - end else begin - state <= WAIT_KEYIN; - end - end - - GET_BREAK:begin - is_extend <= is_extend; - if(rx_valid == 1'b1)begin - state <= WAIT_KEYIN; - valid <= 1'b1; - is_break <= 1'b1; - end else if(err == 1'b1)begin - state <= RESET; - end else begin - state <= GET_BREAK; - end - end - - GET_EXTEND:begin - if(rx_valid == 1'b1 && rx_data == BREAK_CODE)begin - state <= GET_BREAK; - is_extend <= 1'b1; - end else if(rx_valid == 1'b1)begin - state <= WAIT_KEYIN; - valid <= 1'b1; - is_extend <= 1'b1; - end else if(err == 1'b1)begin - state <= RESET; - end else begin - state <= GET_EXTEND; - end - end - - RESET_WAIT_BAT:begin - if(rx_valid == 1'b1 && rx_data == RSP_BAT_PASS)begin - state <= WAIT_KEYIN; - end else if(rx_valid == 1'b1)begin - state <= RESET; - end else if(err == 1'b1)begin - state <= RESET; - end else begin - state <= RESET_WAIT_BAT; - end - end - default:begin - state <= RESET; - valid <= 1'b0; - end - endcase - end + if(rst)begin + state <= RESET; + is_extend <= 1'b0; + is_break <= 1'b1; + valid <= 1'b0; + lock_status <= 3'b0; + tx_data <= 8'h00; + tx_valid <= 1'b0; + end else begin + state <= next_state; + is_extend <= next_is_extend; + is_break <= next_is_break; + valid <= next_valid; + lock_status <= next_lock_status; + tx_data <= next_tx_data; + tx_valid <= next_tx_valid; + end end - + always @ (*) begin + case (state) + RESET: next_state = SEND_CMD; + SEND_CMD: next_state = (busy == 1'b0) ? WAIT_ACK : SEND_CMD; + WAIT_ACK: begin + if(rx_valid == 1'b1) begin + if(rx_data == RSP_ACK && tx_data == CMD_RESET) begin + next_state = RESET_WAIT_BAT; + end else if(rx_data == RSP_ACK && tx_data == CMD_SET_STATUS_LEDS) begin + next_state = SEND_CMD; + end else begin + next_state = WAIT_KEYIN; + end + end else if(err == 1'b1)begin + next_state = RESET; + end else begin + next_state = WAIT_ACK; + end + end + WAIT_KEYIN: begin + if (rx_valid == 1'b1) begin + case (rx_data) + BREAK_CODE: next_state = GET_BREAK; + EXTEND_CODE: next_state = GET_EXTEND; + default: next_state = WAIT_KEYIN; + endcase + end else begin + next_state = (err == 1'b1) ? RESET : WAIT_KEYIN; + end + end + GET_BREAK: begin + if (rx_valid == 1'b1) + next_state = WAIT_KEYIN; + else + next_state = (err == 1'b1) ? RESET : GET_BREAK; + end + GET_EXTEND: begin + if (rx_valid == 1'b1) + next_state = (rx_data == BREAK_CODE) ? GET_BREAK : WAIT_KEYIN; + else + next_state = (err == 1'b1) ? RESET : GET_EXTEND; + end + RESET_WAIT_BAT: begin + if (rx_valid == 1'b1) + next_state = (rx_data == RSP_BAT_PASS) ? WAIT_KEYIN : RESET; + else + next_state = (err == 1'b1) ? RESET : RESET_WAIT_BAT; + end + default: next_state = RESET; + endcase + end + always @ (*) begin + next_tx_valid = 1'b0; + case (state) + RESET: next_tx_valid = 1'b0; + SEND_CMD: next_tx_valid = ~busy; + default: next_tx_valid = next_tx_valid; + endcase + end + always @ (*) begin + next_tx_data = tx_data; + case (state) + RESET: next_tx_data = CMD_RESET; + WAIT_ACK: next_tx_data = (rx_data == RSP_ACK && tx_data == CMD_SET_STATUS_LEDS) ? {5'b00000, lock_status} : next_tx_data; + default: next_tx_data = next_tx_data; + endcase + end + always @ (*) begin + next_lock_status = (state == RESET) ? 3'b0 : lock_status; + end + always @ (*) begin + next_valid = 1'b0; + case (state) + RESET: next_valid = 1'b0; + WAIT_KEYIN: next_valid = (rx_valid == 1'b1 && rx_data != BREAK_CODE && rx_data != EXTEND_CODE) ? 1'b1 : next_valid; + GET_BREAK: next_valid = (rx_valid == 1'b1) ? 1'b1 : next_valid; + GET_EXTEND: next_valid = (rx_valid == 1'b1 && rx_data != BREAK_CODE) ? 1'b1 : next_valid; + default: next_valid = next_valid; + endcase + end + always @ (*) begin + next_is_break = ((state == RESET) || (state == GET_BREAK && rx_valid == 1'b1)) ? 1'b1 : 1'b0; + next_is_extend = 1'b0; + case (state) + RESET: next_is_extend = 1'b0; + GET_BREAK: next_is_extend = is_extend; + GET_EXTEND: next_is_extend = (rx_valid == 1'b1) ? 1'b1 : next_is_extend; + default: next_is_extend = next_is_extend; + endcase + end + Ps2Interface #( .SYSCLK_FREQUENCY_HZ(SYSCLK_FREQUENCY_HZ) ) Ps2Interface_i(