Čeština / English
Login

SVN Repository / Prohlížení

Aktuální adresář: FITkit / trunk / fpga / ctrls / keyboard /

keyboard_ctrl.vhd

   1  -- keyboard_ctrl.vhd : Keyboard controller
   2  -- Copyright (C) 2006 Brno University of Technology,
   3  --                    Faculty of Information Technology
   4  -- Author(s): Zdenek Vasicek <xvasic11 AT stud.fit.vutbr.cz>
   5  --
   6  -- LICENSE TERMS
   7  --
   8  -- Redistribution and use in source and binary forms, with or without
   9  -- modification, are permitted provided that the following conditions
  10  -- are met:
  11  -- 1. Redistributions of source code must retain the above copyright
  12  --    notice, this list of conditions and the following disclaimer.
  13  -- 2. Redistributions in binary form must reproduce the above copyright
  14  --    notice, this list of conditions and the following disclaimer in
  15  --    the documentation and/or other materials provided with the
  16  --    distribution.
  17  -- 3. All advertising materials mentioning features or use of this software
  18  --    or firmware must display the following acknowledgement:
  19  --
  20  --      This product includes software developed by the University of
  21  --      Technology, Faculty of Information Technology, Brno and its
  22  --      contributors.
  23  --
  24  -- 4. Neither the name of the Company nor the names of its contributors
  25  --    may be used to endorse or promote products derived from this
  26  --    software without specific prior written permission.
  27  --
  28  -- This software or firmware is provided ``as is'', and any express or implied
  29  -- warranties, including, but not limited to, the implied warranties of
  30  -- merchantability and fitness for a particular purpose are disclaimed.
  31  -- In no event shall the company or contributors be liable for any
  32  -- direct, indirect, incidental, special, exemplary, or consequential
  33  -- damages (including, but not limited to, procurement of substitute
  34  -- goods or services; loss of use, data, or profits; or business
  35  -- interruption) however caused and on any theory of liability, whether
  36  -- in contract, strict liability, or tort (including negligence or
  37  -- otherwise) arising in any way out of the use of this software, even
  38  -- if advised of the possibility of such damage.
  39  --
  40  -- $Id$
  41  --
  42  --
  43  -- Description:
  44  --
  45  --                 KEYBOARD
  46  --
  47  --                 +---+---+---+---+
  48  --  KB_KIN(0) ---->| 1 | 2 | 3 | A |
  49  --                 +---+---+---+---+
  50  --  KB_KIN(1) ---->| 4 | 5 | 6 | B |
  51  --                 +---+---+---+---+
  52  --  KB_KIN(2) ---->| 7 | 8 | 9 | C |
  53  --                 +---+---+---+---+
  54  --  KB_KIN(3) ---->| * | 0 | # | D |
  55  --                 +---+---+---+---+
  56  --                   |   |   |   |
  57  --  KB_KOUT(0)  <----+   |   |   |
  58  --  KB_KOUT(1)  <--------+   |   |
  59  --  KB_KOUT(2)  <------------+   |
  60  --  KB_KOUT(3)  <----------------+
  61  --
  62  -- meaning of DATA_OUT
  63  --      DATA_OUT(0) <=> '1'
  64  --      DATA_OUT(1) <=> '4'
  65  --      DATA_OUT(2) <=> '7'
  66  --      DATA_OUT(3) <=> '*'
  67  --      DATA_OUT(4) <=> '2'
  68  --      DATA_OUT(5) <=> '5'
  69  --      DATA_OUT(6) <=> '8'
  70  --      DATA_OUT(7) <=> '0'
  71  --      DATA_OUT(8) <=> '3'
  72  --      DATA_OUT(9) <=> '6'
  73  --      DATA_OUT(10) <=> '9'
  74  --      DATA_OUT(11) <=> '#'
  75  --      DATA_OUT(12) <=> 'A'
  76  --      DATA_OUT(13) <=> 'B'
  77  --      DATA_OUT(14) <=> 'C'
  78  --      DATA_OUT(15) <=> 'D'
  79  --
  80  
  81  
  82  library IEEE;
  83  use IEEE.STD_LOGIC_1164.ALL;
  84  use IEEE.STD_LOGIC_ARITH.ALL;
  85  use IEEE.STD_LOGIC_UNSIGNED.ALL;
  86  
  87  -- SYNTH-ISE-8.2: slices=27, slicesFF=36, 4luts=53
  88  entity keyboard_controller is
  89     generic(
  90        READ_INTERVAL : integer := (2**14)-1
  91     );
  92     port(
  93        -- Hodiny
  94        CLK        : in std_logic;
  95        -- Reset
  96        RST        : in std_logic;
  97  
  98        -- Stisknute klavesy
  99        DATA_OUT   : out std_logic_vector(15 downto 0);
 100        DATA_VLD   : out std_logic;
 101  
 102        -- Signaly klavesnice
 103        KB_KIN     : out std_logic_vector(3 downto 0);
 104        KB_KOUT    : in  std_logic_vector(3 downto 0)
 105     );
 106  end keyboard_controller;
 107  
 108  architecture arch_keyboard of keyboard_controller is
 109  
 110     type   FSMstate is (SInit, SScan0, SScan1, SScan2, SScan3, SWE);
 111  
 112     signal pstate : FSMstate; -- actual state
 113     signal nstate : FSMstate; -- next state
 114  
 115     signal data_reg : std_logic_vector(15 downto 0);
 116     signal data_mx  : std_logic_vector(3 downto 0);
 117     signal data_sel : std_logic_vector(1 downto 0);
 118     signal data_cmp : std_logic;
 119  
 120     signal cntr_reg : std_logic_vector(14 downto 0);
 121     signal cntr_zero: std_logic;
 122  
 123     signal kb_we  : std_logic_vector(3 downto 0);
 124     signal kbout  : std_logic_vector(3 downto 0);
 125  
 126     signal eq_reg : std_logic;
 127     signal eq_rst : std_logic;
 128     signal eq_en  : std_logic;
 129  
 130  begin
 131  
 132     DATA_OUT <= data_reg;
 133  
 134     -- Interval counter
 135     intervalcounter: process (RST, CLK)
 136     begin
 137        if (RST = '1') then
 138           cntr_reg <= (others => '0');
 139        elsif (CLK'event) and (CLK = '1') then
 140           if (cntr_zero='1') then
 141              cntr_reg <= (others => '0');
 142           else
 143              cntr_reg <= cntr_reg + 1;
 144           end if;
 145        end if;
 146     end process;
 147     cntr_zero <= '1' when (cntr_reg=conv_std_logic_vector(READ_INTERVAL, cntr_reg'length))
 148                  else '0';
 149  
 150     -- Activation of rows
 151     -- in order to avoid shorts due to missing diodes, we use 'Z'
 152     KB_KIN(0) <= '0' when kb_we(0) = '1' else 'Z';
 153     KB_KIN(1) <= '0' when kb_we(1) = '1' else 'Z';
 154     KB_KIN(2) <= '0' when kb_we(2) = '1' else 'Z';
 155     KB_KIN(3) <= '0' when kb_we(3) = '1' else 'Z';
 156  
 157     kbout <= not KB_KOUT;
 158  
 159     -- Data registers
 160     dregs: process (RST, CLK)
 161     begin
 162        if (RST = '1') then
 163           data_reg <= (others => '0');
 164        elsif (CLK'event) and (CLK = '1') then
 165           if (kb_we(0) = '1') then
 166              data_reg(3 downto 0) <= kbout;
 167           end if;
 168           if (kb_we(1) = '1') then
 169              data_reg(7 downto 4) <= kbout;
 170           end if;
 171           if (kb_we(2) = '1') then
 172              data_reg(11 downto 8) <= kbout;
 173           end if;
 174           if (kb_we(3) = '1') then
 175              data_reg(15 downto 12) <= kbout;
 176           end if;
 177        end if;
 178     end process;
 179  
 180     data_mx <= data_reg(3 downto 0)  when data_sel="00" else
 181                data_reg(7 downto 4)  when data_sel="01" else
 182                data_reg(11 downto 8) when data_sel="10" else
 183                data_reg(15 downto 12);
 184  
 185     data_cmp <= '1' when (data_mx = kbout) else '0';
 186  
 187     -- Register that hold changes
 188     process (RST, CLK)
 189     begin
 190        if (RST = '1') then
 191           eq_reg <= '1';
 192        elsif (CLK'event) and (CLK = '1') then
 193           if (eq_rst='1') then
 194              eq_reg <= '1';
 195           elsif (eq_en='1') then
 196              eq_reg <= eq_reg and data_cmp;
 197           end if;
 198        end if;
 199     end process;
 200  
 201     --FSM actual state
 202     process (RST, CLK)
 203     begin
 204        if (RST = '1') then
 205           pstate <= SInit;
 206        elsif (CLK'event) and (CLK = '1') then
 207           pstate <= nstate;
 208        end if;
 209     end process;
 210  
 211     --FSM next state logic
 212     process (pstate, cntr_zero, eq_reg)
 213     begin
 214        nstate <= SInit;
 215        kb_we <= "0000";
 216        data_sel <= "00";
 217        DATA_VLD <= '0';
 218        eq_rst <= '0';
 219        eq_en <= '0';
 220  
 221        case pstate is
 222           when SInit =>
 223              if (cntr_zero='1') then
 224                 nstate <= SScan0;
 225                 eq_rst <= '1';
 226              end if;
 227  
 228           --Scan
 229           when SScan0 =>
 230              nstate <= SScan1;
 231              data_sel <= "00";
 232              kb_we(0) <= '1';
 233              eq_en <= '1';
 234  
 235           when SScan1 =>
 236              nstate <= SScan2;
 237              data_sel <= "01";
 238              kb_we(1) <= '1';
 239              eq_en <= '1';
 240  
 241           when SScan2 =>
 242              nstate <= SScan3;
 243              data_sel <= "10";
 244              kb_we(2) <= '1';
 245              eq_en <= '1';
 246  
 247           when SScan3 =>
 248              nstate <= SWE;
 249              data_sel <= "11";
 250              kb_we(3) <= '1';
 251              eq_en <= '1';
 252  
 253           --Write enable
 254           when SWE =>
 255              DATA_VLD <= not eq_reg;
 256  
 257           when others =>
 258              null;
 259        end case;
 260     end process;
 261  
 262  end arch_keyboard;
 263  
Zobrazeno: 679775x Naposledy: 28.6.2022 20:32:31