?? analyser.vhd
字號:
library ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;use work.Constants.all; entity Analyser is port (reset, clk : in std_logic; analyse : in std_logic; store : in std_logic; debounced: out std_logic; keychanged : out std_logic; released : out std_logic; sample_col : in col; sample_row_number : in row_number; conv_col : out col_number; conv_row : out row_number ); end Analyser;architecture Analyser_arc of Analyser is function ones_in_column(inp: col) return col_number isvariable number : col_number;begin number := 0; for i in inp'range loop if inp(i)='1' then number := number+1; end if; end loop; return number;end ones_in_column;function ones_in_row(inp: row) return row_number isvariable number : row_number;begin number := 0; for i in inp'range loop if inp(i)='1' then number := number + 1; end if; end loop; return number;end ones_in_row;function priority_encode(inp: col) return col_number isvariable tmp: col_number;begin if inp(5)='1' then tmp:= 5; elsif inp(4)='1' then tmp:= 4; elsif inp(3)='1' then tmp:= 3; elsif inp(2)='1' then tmp:= 2; elsif inp(1)='1' then tmp:= 1; else tmp:= 0; end if; return tmp;end priority_encode;--reduce or function to look for key press in a columnfunction key_pressed(inp : row) return std_logic is variable tmp: std_logic;begin tmp:='0'; for i in inp'range loop tmp := tmp or inp(i); end loop; return tmp;end key_pressed;--function that checks whether the new key specified by col_number and row_number is valid--large input is necessary to make it a legal functionfunction valid_key(colnum: col_number; rownum: row_number; row0:row; row1:row; row2:row; row3:row; row4:row; row5:row; keysdown: key_number) return std_logic isvariable colpress : col;variable rowpress : row;variable valid :std_logic; begin valid := '1'; --valid until proven otherwise colpress := "000000"; rowpress := "000000000000"; colpress(0):= key_pressed(row0); colpress(1):= key_pressed(row1); colpress(2):= key_pressed(row2); colpress(3):= key_pressed(row3); colpress(4):= key_pressed(row4); colpress(5):= key_pressed(row5); for i in number_of_cols-1 downto 0 loop rowpress(i) := row0(i) or row1(i) or row2(i) or row3(i) or row4(i) or row5(i); end loop; --add virtual key colpress(colnum) := '1'; rowpress(rownum) := '1'; if (keysdown >= max_keys_pressed) then --too many keys pressed valid := '0'; elsif (keysdown = 2) then --check for ghosting if (ones_in_column(colpress)=2 and ones_in_row(rowpress)=2) then valid := '0'; end if; end if; return valid;end valid_key;signal debounce_state : col;signal keysdown : natural range 0 to max_keys_pressed ;signal next_keysdown : natural range 0 to max_keys_pressed;signal keychange : std_logic;signal release : std_logic;signal conv_col_number : col_number;signal conv_row_number : row_number;signal previous_sample : col; --last sampled columnsignal row0 : row;signal row1 : row; signal row2 : row;signal row3 : row;signal row4 : row;signal row5 : row;begin --look for valid keychange detector: process ( conv_col_number, conv_row_number, keysdown, row0, row1, row2, row3, row4, row5, sample_row_number, previous_sample) variable colpress : col_number; begin colpress := 0; if ((row0(sample_row_number) xor previous_sample(0))='1') then --change detected --keychange if valid or !pressed_down keychange <= (not previous_sample(0)) or valid_key(0, sample_row_number, row0, row1, row2, row3, row4, row5, keysdown); release <= not previous_sample(0); colpress := 0; elsif((row1(sample_row_number) xor previous_sample(1))='1') then keychange <= (not previous_sample(1)) or valid_key(1, sample_row_number, row0, row1, row2, row3, row4, row5, keysdown); release <= not previous_sample(1); colpress := 1; elsif((row2(sample_row_number) xor previous_sample(2))='1') then keychange <= (not previous_sample(2)) or valid_key(2, sample_row_number, row0, row1, row2, row3, row4, row5, keysdown); release <= not previous_sample(2); colpress := 2; elsif((row3(sample_row_number) xor previous_sample(3))='1') then keychange <= (not previous_sample(3)) or valid_key(3, sample_row_number, row0, row1, row2, row3, row4, row5, keysdown); release <= not previous_sample(3); colpress := 3; elsif((row4(sample_row_number) xor previous_sample(4))='1') then keychange <= (not previous_sample(4)) or valid_key(4, sample_row_number, row0, row1, row2, row3, row4, row5, keysdown); release <= not previous_sample(4); colpress := 4; elsif ((row5(sample_row_number) xor previous_sample(5))='1') then keychange <= (not previous_sample(5)) or valid_key(5, sample_row_number, row0, row1, row2, row3, row4, row5, keysdown); release <= not previous_sample(5); colpress := 5; else keychange <= '0'; release <= '0'; end if; conv_col_number <= colpress; conv_row_number <= sample_row_number; end process; next_keysdown <= keysdown+1 when keychange='1' and release='0' else keysdown-1 when keychange='1' and release='1' else keysdown; storer:process begin wait until rising_edge(clk); if (reset='1') then row0 <= "000000000000"; row1 <= "000000000000"; row2 <= "000000000000"; row3 <= "000000000000"; row4 <= "000000000000"; row5 <= "000000000000"; keychanged <= '0'; released <= '0'; keysdown <= 0; conv_col <= 0; conv_row <= 0; elsif (store='1') then if (debounce_state = "000000") then keychanged <= keychange; released <= release; keysdown <= next_keysdown; conv_col <= conv_col_number; conv_row <= conv_row_number; if (keychange='1') then case conv_col_number is when 0 => row0(conv_row_number) <= previous_sample(0); when 1 => row1(conv_row_number) <= previous_sample(1); when 2 => row2(conv_row_number) <= previous_sample(2); when 3 => row3(conv_row_number) <= previous_sample(3); when 4 => row4(conv_row_number) <= previous_sample(4); when 5 => row5(conv_row_number) <= previous_sample(5); when others => null; end case; end if; else keychanged <= '0'; released <= '0'; end if; else keychanged <= '0'; released <= '0'; end if; end process; --debouncing debouncer: process variable counter : natural range 0 to debounce_count; begin wait until rising_edge(clk); if (reset = '1') then debounce_state <= (others=> '0'); previous_sample <= (others => '0'); counter := debounce_count; debounced <= '0'; else if (analyse='1') then if (counter > 0 and counter < debounce_count) then counter := counter - 1; debounce_state <= debounce_state or (previous_sample xor sample_col); debounced <= '0'; end if; if (counter = debounce_count) then previous_sample <= sample_col; counter := counter -1 ; end if; if (counter = 0) then debounced <= '1'; end if; else counter := debounce_count; debounced <= '0'; debounce_state <= (others=> '0'); end if; end if; end process; end Analyser_arc;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -