OpenCores
URL https://opencores.org/ocsvn/keyboardcontroller/keyboardcontroller/trunk

Subversion Repositories keyboardcontroller

[/] [keyboardcontroller/] [trunk/] [Analyser.vhd] - Diff between revs 2 and 6

Show entire file | Details | Blame | View Log

Rev 2 Rev 6
Line 1... Line 1...
 
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 is
 
variable 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 is
 
variable 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 is
 
variable 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 column
 
function 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 function
 
 
 
function 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 is
 
variable 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 column
 
 
 
signal 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;
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.