SCH
Figure 1 Sch of the 4x4 matrix keyboard (arrows indicate the direction of input and output)
1. Set row [] to input and Col [] to output. If no key is pressed, row [3: 0] is always pulled up to a high level. Only when a key is pressed and Col [3: 0] has a low-level output, row [3: 0] may have a low-level input, or passive input.
Flowchart
Figure 2 Flowchart
HDL
Module matrixkeyboard_drive (input I _clk, input I _rst_n, input [3: 0] row, // matrix keyboard row output Reg [3: 0] col, // output Reg [3: 0] keyboard_val in the matrix keyboard column // The keyboard value ); // ++ // The start of the Division: // ++ +++ Reg [] CNT; // count sub-always @ (posedge I _clk, negedge I _rst_n) if (! I _rst_n) CNT <= 0; else CNT <= CNT + 1 'b1; wire key_clk = CNT [19]; // (2 ^ 20/50 m = 21) MS // the end of the segment // -------------------------------------------- // ++ +++ ++ // start of the state machine section. ++ few statuses, single-hot code encoding parameter no_key_pressed = 6 'b000 _ 001; // No key pressed parameter scan_col0 = 6 'b000 _ 010; // scan the 0th column parameter scan_col1 = 6' B00 0_100; // scan 1st columns of parameter scan_col2 = 6 'b001 _ 000; // scan 2nd columns of parameter scan_col3 = 6 'b010 _ 000; // scan the 3rd columns of parameter key_pressed = 6 'b100 _ 000; // press Reg [] current_state, next_state; // the current state and substate always @ (posedge key_clk, negedge I _rst_n) if (! I _rst_n) current_state <= no_key_pressed; else current_state <= next_state; // according to the condition transfer status always @ * case (current_state) no_key_pressed: // No key pressed if (row! = 4 'hf) next_state = scan_col0; else next_state = no_key_pressed; scan_col0: // scan 0th columns if (row! = 4 'hf) next_state = key_pressed; else next_state = scan_col1; scan_col1: // scan 1st columns if (row! = 4 'hf) next_state = key_pressed; else next_state = scan_col2; scan_col2: // scan 2nd columns if (row! = 4 'hf) next_state = key_pressed; else next_state = scan_col3; scan_col3: // scan 3rd columns if (row! = 4 'hf) next_state = key_pressed; else next_state = no_key_pressed; key_pressed: // If (row! = 4 'hf) next_state = key_pressed; else next_state = no_key_pressed; endcasereg key_pressed_flag; // press the keyboard icon Reg [] col_val, row_val; // column value, row value // assign the corresponding register always @ (posedge key_clk, negedge I _rst_n) if (! I _rst_n) Begin Col <= 4'h0; key_pressed_flag <= 0; end else case (next_state) no_key_pressed: // if you do not press begin Col <= 4'h0; key_pressed_flag <= 0; // clear the keyboard press the sign end scan_col0: // scan the 0th column Col <= 4 'b1110; scan_col1: // scan the 1st column Col <= 4 'b1101; scan_col2: // scan 2nd columns of Col <= 4 'b1011; scan_col3: // scan 3rd columns of Col <= 4 'b0111; key_pressed: // press begin col_val <= Col; // lock column value row_val <= row; // lock row value key_pressed_fl Ag <= 1; // set the keyboard to press the end endcase // ---------------------------------------- // The End of the state machine section. // complete //+++ ++ ++ ++ always @ (posedge key_clk, negedge I _rst_n) if (! I _rst_n) keyboard_val <= 4'h0; else if (key_pressed_flag) Case ({col_val, row_val}) 8 'b1110 _ 1110: keyboard_val <= 4' H0; 8 'b1110 _ 1101: keyboard_val <= 4 'h4; 8 'b1110 _ 1011: keyboard_val <= 4 'h8; 8 'b1110 _ 0111: keyboard_val <= 4' HC; 8 'b1101 _ 1110: keyboard_val <= 4 'h1; 8 'b1101 _ 1101: keyboard_val <= 4'h5; 8 'b1101 _ 1011: keyboard_val <= 4'h9; 8 'b1101 _ 0111: keyboard_val <= 4' HD; 8 'b1011 _ 1110: keyboard_val <= 4'h2; 8 'b1011 _ 1101: keyboard_val <= 4' H6; 8 'b1011 _ 1011: keyboard_val <= 4' ha; 8 'b1011 _ 0111: keyboard_val <= 4' he; 8 'b0111 _ 1110: keyboard_val <= 4' H3; 8 'b0111 _ 1101: keyboard_val <= 4 'h7; 8 'b0111 _ 1011: keyboard_val <= 4'hb; 8 'b0111 _ 0111: keyboard_val <= 4'hf; endcase // -------------------------------------- // The end of scanning the row and column values // ------------------------------------ endmodule