URL
https://opencores.org/ocsvn/keyboardcontroller/keyboardcontroller/trunk
Subversion Repositories keyboardcontroller
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/tags/KEYB_CON_0_01/summery.txt
0,0 → 1,16
Device utilization summary: |
--------------------------- |
|
Selected Device : 3s1000ft256-4 |
|
Number of Slices: 2407 out of 7680 31% |
Number of Slice Flip Flops: 2109 out of 15360 13% |
Number of 4 input LUTs: 3188 out of 15360 20% |
Number of bonded IOBs: 95 out of 173 54% |
Number of BRAMs: 10 out of 24 41% |
Number of MULT18X18s: 3 out of 24 12% |
Number of GCLKs: 2 out of 8 25% |
Number of DCMs: 1 out of 4 25% |
|
|
========================================================================= |
/tags/KEYB_CON_0_01/wouter_keyb.vhd
0,0 → 1,432
------------------------------------------------------------------------------ |
-- wouter_keyb.vhd - entity/architecture pair |
------------------------------------------------------------------------------ |
-- IMPORTANT: |
-- DO NOT MODIFY THIS FILE EXCEPT IN THE DESIGNATED SECTIONS. |
-- |
-- SEARCH FOR --USER TO DETERMINE WHERE CHANGES ARE ALLOWED. |
-- |
-- TYPICALLY, THE ONLY ACCEPTABLE CHANGES INVOLVE ADDING NEW |
-- PORTS AND GENERICS THAT GET PASSED THROUGH TO THE INSTANTIATION |
-- OF THE USER_LOGIC ENTITY. |
------------------------------------------------------------------------------ |
-- |
-- *************************************************************************** |
-- ** Copyright (c) 1995-2004 Xilinx, Inc. All rights reserved. ** |
-- ** ** |
-- ** Xilinx, Inc. ** |
-- ** XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" ** |
-- ** AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND ** |
-- ** SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, ** |
-- ** OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, ** |
-- ** APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION ** |
-- ** THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, ** |
-- ** AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE ** |
-- ** FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY ** |
-- ** WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE ** |
-- ** IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR ** |
-- ** REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF ** |
-- ** INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ** |
-- ** FOR A PARTICULAR PURPOSE. ** |
-- ** ** |
-- ** YOU MAY COPY AND MODIFY THESE FILES FOR YOUR OWN INTERNAL USE SOLELY ** |
-- ** WITH XILINX PROGRAMMABLE LOGIC DEVICES AND XILINX EDK SYSTEM OR ** |
-- ** CREATE IP MODULES SOLELY FOR XILINX PROGRAMMABLE LOGIC DEVICES AND ** |
-- ** XILINX EDK SYSTEM. NO RIGHTS ARE GRANTED TO DISTRIBUTE ANY FILES ** |
-- ** UNLESS THEY ARE DISTRIBUTED IN XILINX PROGRAMMABLE LOGIC DEVICES. ** |
-- ** ** |
-- *************************************************************************** |
-- |
------------------------------------------------------------------------------ |
-- Filename: wouter_keyb.vhd |
-- Version: 1.00.a |
-- Description: Top level design, instantiates IPIF and user logic. |
-- Date: Wed Jun 15 10:21:28 2005 (by Create and Import Peripheral Wizard) |
-- VHDL-Standard: VHDL'93 |
------------------------------------------------------------------------------ |
-- Naming Conventions: |
-- active low signals: "*_n" |
-- clock signals: "clk", "clk_div#", "clk_#x" |
-- reset signals: "rst", "rst_n" |
-- generics: "C_*" |
-- user defined types: "*_TYPE" |
-- state machine next state: "*_ns" |
-- state machine current state: "*_cs" |
-- combinatorial signals: "*_com" |
-- pipelined or register delay signals: "*_d#" |
-- counter signals: "*cnt*" |
-- clock enable signals: "*_ce" |
-- internal version of output port: "*_i" |
-- device pins: "*_pin" |
-- ports: "- Names begin with Uppercase" |
-- processes: "*_PROCESS" |
-- component instantiations: "<ENTITY_>I_<#|FUNC>" |
------------------------------------------------------------------------------ |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
library proc_common_v2_00_a; |
use proc_common_v2_00_a.proc_common_pkg.all; |
use proc_common_v2_00_a.ipif_pkg.all; |
|
library opb_ipif_v3_01_a; |
use opb_ipif_v3_01_a.all; |
|
--library wouter_keyb_v1_00_a; |
--use wouter_keyb_v1_00_a.all; |
library work; |
use work.Constants.all; |
|
------------------------------------------------------------------------------ |
-- Definition of Generics: |
-- C_BASEADDR -- User logic base address |
-- C_HIGHADDR -- User logic high address |
-- C_OPB_AWIDTH -- OPB address bus width |
-- C_OPB_DWIDTH -- OPB data bus width |
-- C_FAMILY -- Target FPGA architecture |
-- |
-- Definition of Ports: |
-- OPB_Clk -- OPB Clock |
-- OPB_Rst -- OPB Reset |
-- Sl_DBus -- Slave data bus |
-- Sl_errAck -- Slave error acknowledge |
-- Sl_retry -- Slave retry |
-- Sl_toutSup -- Slave timeout suppress |
-- Sl_xferAck -- Slave transfer acknowledge |
-- OPB_ABus -- OPB address bus |
-- OPB_BE -- OPB byte enable |
-- OPB_DBus -- OPB data bus |
-- OPB_RNW -- OPB read/not write |
-- OPB_select -- OPB select |
-- OPB_seqAddr -- OPB sequential address |
-- |
-------------------------------------------------------------------------------- |
-- Entity section |
-------------------------------------------------------------------------------- |
|
entity wouter_keyb is |
generic |
( |
-- ADD USER GENERICS BELOW THIS LINE --------------- |
--USER generics added here |
-- ADD USER GENERICS ABOVE THIS LINE --------------- |
|
-- DO NOT EDIT BELOW THIS LINE --------------------- |
-- Bus protocol parameters, do not add to or delete |
C_BASEADDR : std_logic_vector := X"00000000"; |
C_HIGHADDR : std_logic_vector := X"0000FFFF"; |
C_OPB_AWIDTH : integer := 32; |
C_OPB_DWIDTH : integer := 32; |
C_FAMILY : string := "virtex2p" |
-- DO NOT EDIT ABOVE THIS LINE --------------------- |
); |
port |
( |
-- ADD USER PORTS BELOW THIS LINE ------------------ |
keyb_interrupt : out std_logic; |
keyb_clk_out : out std_logic; |
keyb_cols : in col; |
keyb_rows : out row; |
keyb_up : out std_logic; |
|
-- ADD USER PORTS ABOVE THIS LINE ------------------ |
|
-- DO NOT EDIT BELOW THIS LINE --------------------- |
-- Bus protocol ports, do not add to or delete |
OPB_Clk : in std_logic; |
OPB_Rst : in std_logic; |
Sl_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); |
Sl_errAck : out std_logic; |
Sl_retry : out std_logic; |
Sl_toutSup : out std_logic; |
Sl_xferAck : out std_logic; |
OPB_ABus : in std_logic_vector(0 to C_OPB_AWIDTH-1); |
OPB_BE : in std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH-1); |
OPB_RNW : in std_logic; |
OPB_select : in std_logic; |
OPB_seqAddr : in std_logic |
-- DO NOT EDIT ABOVE THIS LINE --------------------- |
); |
|
attribute MIN_SIZE : string; |
attribute MIN_SIZE of C_BASEADDR : constant is "0x100"; |
|
attribute SIGIS : string; |
attribute SIGIS of OPB_Clk : signal is "Clk"; |
attribute SIGIS of OPB_Rst : signal is "Rst"; |
|
end entity wouter_keyb; |
|
-------------------------------------------------------------------------------- |
-- Architecture section |
-------------------------------------------------------------------------------- |
|
architecture IMP of wouter_keyb is |
|
---------------------------------------- |
-- Constant: array of address range identifiers |
---------------------------------------- |
constant ARD_ID_ARRAY : INTEGER_ARRAY_TYPE := |
( |
0 => USER_00 -- user logic S/W register address space |
); |
|
---------------------------------------- |
-- Constant: array of address pairs for each address range |
---------------------------------------- |
constant ZERO_ADDR_PAD : std_logic_vector(0 to 64-C_OPB_AWIDTH-1) := (others => '0'); |
|
constant USER_BASEADDR : std_logic_vector := C_BASEADDR; |
constant USER_HIGHADDR : std_logic_vector := C_HIGHADDR; |
|
constant ARD_ADDR_RANGE_ARRAY : SLV64_ARRAY_TYPE := |
( |
ZERO_ADDR_PAD & USER_BASEADDR, -- user logic base address |
ZERO_ADDR_PAD & USER_HIGHADDR -- user logic high address |
); |
|
---------------------------------------- |
-- Constant: array of data widths for each target address range |
---------------------------------------- |
constant USER_DWIDTH : integer := 32; |
|
constant ARD_DWIDTH_ARRAY : INTEGER_ARRAY_TYPE := |
( |
0 => USER_DWIDTH -- user logic data width |
); |
|
---------------------------------------- |
-- Constant: array of desired number of chip enables for each address range |
---------------------------------------- |
constant USER_NUM_CE : integer := 1; |
|
constant ARD_NUM_CE_ARRAY : INTEGER_ARRAY_TYPE := |
( |
0 => pad_power2(USER_NUM_CE) -- user logic number of CEs |
); |
|
---------------------------------------- |
-- Constant: array of unique properties for each address range |
---------------------------------------- |
constant ARD_DEPENDENT_PROPS_ARRAY : DEPENDENT_PROPS_ARRAY_TYPE := |
( |
0 => (others => 0) -- user logic slave space dependent properties (none defined) |
); |
|
---------------------------------------- |
-- Constant: pipeline mode |
-- 1 = include OPB-In pipeline registers |
-- 2 = include IP pipeline registers |
-- 3 = include OPB-In and IP pipeline registers |
-- 4 = include OPB-Out pipeline registers |
-- 5 = include OPB-In and OPB-Out pipeline registers |
-- 6 = include IP and OPB-Out pipeline registers |
-- 7 = include OPB-In, IP, and OPB-Out pipeline registers |
-- Note: |
-- only mode 4, 5, 7 are supported for this release |
---------------------------------------- |
constant PIPELINE_MODEL : integer := 5; |
|
---------------------------------------- |
-- Constant: user core ID code |
---------------------------------------- |
constant DEV_BLK_ID : integer := 0; |
|
---------------------------------------- |
-- Constant: enable MIR/Reset register |
---------------------------------------- |
constant DEV_MIR_ENABLE : integer := 0; |
|
---------------------------------------- |
-- Constant: array of IP interrupt mode |
-- 1 = Active-high interrupt condition |
-- 2 = Active-low interrupt condition |
-- 3 = Active-high pulse interrupt event |
-- 4 = Active-low pulse interrupt event |
-- 5 = Positive-edge interrupt event |
-- 6 = Negative-edge interrupt event |
---------------------------------------- |
constant IP_INTR_MODE_ARRAY : INTEGER_ARRAY_TYPE := |
( |
0 => 0 -- not used |
); |
|
---------------------------------------- |
-- Constant: enable device burst |
---------------------------------------- |
constant DEV_BURST_ENABLE : integer := 0; |
|
---------------------------------------- |
-- Constant: include address counter for burst transfers |
---------------------------------------- |
constant INCLUDE_ADDR_CNTR : integer := 0; |
|
---------------------------------------- |
-- Constant: include write buffer that decouples OPB and IPIC write transactions |
---------------------------------------- |
constant INCLUDE_WR_BUF : integer := 0; |
|
---------------------------------------- |
-- Constant: index for CS/CE |
---------------------------------------- |
constant USER00_CS_INDEX : integer := get_id_index(ARD_ID_ARRAY, USER_00); |
|
constant USER00_CE_INDEX : integer := calc_start_ce_index(ARD_NUM_CE_ARRAY, USER00_CS_INDEX); |
|
---------------------------------------- |
-- IP Interconnect (IPIC) signal declarations -- do not delete |
---------------------------------------- |
signal iBus2IP_RdCE : std_logic_vector(0 to calc_num_ce(ARD_NUM_CE_ARRAY)-1); |
signal iBus2IP_WrCE : std_logic_vector(0 to calc_num_ce(ARD_NUM_CE_ARRAY)-1); |
signal iBus2IP_Data : std_logic_vector(0 to C_OPB_DWIDTH-1); |
signal iBus2IP_BE : std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
signal iIP2Bus_Data : std_logic_vector(0 to C_OPB_DWIDTH-1) := (others => '0'); |
signal iIP2Bus_Ack : std_logic := '0'; |
signal iIP2Bus_Error : std_logic := '0'; |
signal iIP2Bus_Retry : std_logic := '0'; |
signal iIP2Bus_ToutSup : std_logic := '0'; |
signal ZERO_IP2Bus_PostedWrInh : std_logic_vector(0 to ARD_ID_ARRAY'length-1) := (others => '0'); -- work around for XST not taking (others => '0') in port mapping |
signal ZERO_IP2RFIFO_Data : std_logic_vector(0 to 31) := (others => '0'); -- work around for XST not taking (others => '0') in port mapping |
signal ZERO_WFIFO2IP_Data : std_logic_vector(0 to 31) := (others => '0'); -- work around for XST not taking (others => '0') in port mapping |
signal ZERO_IP2Bus_IntrEvent : std_logic_vector(0 to IP_INTR_MODE_ARRAY'length-1) := (others => '0'); -- work around for XST not taking (others => '0') in port mapping |
signal iBus2IP_Clk : std_logic; |
signal iBus2IP_Reset : std_logic; |
signal uBus2IP_Data : std_logic_vector(0 to USER_DWIDTH-1); |
signal uBus2IP_BE : std_logic_vector(0 to USER_DWIDTH/8-1); |
signal uBus2IP_RdCE : std_logic_vector(0 to USER_NUM_CE-1); |
signal uBus2IP_WrCE : std_logic_vector(0 to USER_NUM_CE-1); |
signal uIP2Bus_Data : std_logic_vector(0 to USER_DWIDTH-1); |
|
begin |
|
---------------------------------------- |
-- instantiate the OPB IPIF |
---------------------------------------- |
OPB_IPIF_I : entity opb_ipif_v3_01_a.opb_ipif |
generic map |
( |
C_ARD_ID_ARRAY => ARD_ID_ARRAY, |
C_ARD_ADDR_RANGE_ARRAY => ARD_ADDR_RANGE_ARRAY, |
C_ARD_DWIDTH_ARRAY => ARD_DWIDTH_ARRAY, |
C_ARD_NUM_CE_ARRAY => ARD_NUM_CE_ARRAY, |
C_ARD_DEPENDENT_PROPS_ARRAY => ARD_DEPENDENT_PROPS_ARRAY, |
C_PIPELINE_MODEL => PIPELINE_MODEL, |
C_DEV_BLK_ID => DEV_BLK_ID, |
C_DEV_MIR_ENABLE => DEV_MIR_ENABLE, |
C_OPB_AWIDTH => C_OPB_AWIDTH, |
C_OPB_DWIDTH => C_OPB_DWIDTH, |
C_FAMILY => C_FAMILY, |
C_IP_INTR_MODE_ARRAY => IP_INTR_MODE_ARRAY, |
C_DEV_BURST_ENABLE => DEV_BURST_ENABLE, |
C_INCLUDE_ADDR_CNTR => INCLUDE_ADDR_CNTR, |
C_INCLUDE_WR_BUF => INCLUDE_WR_BUF |
) |
port map |
( |
OPB_select => OPB_select, |
OPB_DBus => OPB_DBus, |
OPB_ABus => OPB_ABus, |
OPB_BE => OPB_BE, |
OPB_RNW => OPB_RNW, |
OPB_seqAddr => OPB_seqAddr, |
Sln_DBus => Sl_DBus, |
Sln_xferAck => Sl_xferAck, |
Sln_errAck => Sl_errAck, |
Sln_retry => Sl_retry, |
Sln_toutSup => Sl_toutSup, |
Bus2IP_CS => open, |
Bus2IP_CE => open, |
Bus2IP_RdCE => iBus2IP_RdCE, |
Bus2IP_WrCE => iBus2IP_WrCE, |
Bus2IP_Data => iBus2IP_Data, |
Bus2IP_Addr => open, |
Bus2IP_AddrValid => open, |
Bus2IP_BE => iBus2IP_BE, |
Bus2IP_RNW => open, |
Bus2IP_Burst => open, |
IP2Bus_Data => iIP2Bus_Data, |
IP2Bus_Ack => iIP2Bus_Ack, |
IP2Bus_AddrAck => '0', |
IP2Bus_Error => iIP2Bus_Error, |
IP2Bus_Retry => iIP2Bus_Retry, |
IP2Bus_ToutSup => iIP2Bus_ToutSup, |
IP2Bus_PostedWrInh => ZERO_IP2Bus_PostedWrInh, |
IP2RFIFO_Data => ZERO_IP2RFIFO_Data, |
IP2RFIFO_WrMark => '0', |
IP2RFIFO_WrRelease => '0', |
IP2RFIFO_WrReq => '0', |
IP2RFIFO_WrRestore => '0', |
RFIFO2IP_AlmostFull => open, |
RFIFO2IP_Full => open, |
RFIFO2IP_Vacancy => open, |
RFIFO2IP_WrAck => open, |
IP2WFIFO_RdMark => '0', |
IP2WFIFO_RdRelease => '0', |
IP2WFIFO_RdReq => '0', |
IP2WFIFO_RdRestore => '0', |
WFIFO2IP_AlmostEmpty => open, |
WFIFO2IP_Data => ZERO_WFIFO2IP_Data, |
WFIFO2IP_Empty => open, |
WFIFO2IP_Occupancy => open, |
WFIFO2IP_RdAck => open, |
IP2Bus_IntrEvent => ZERO_IP2Bus_IntrEvent, |
IP2INTC_Irpt => open, |
Freeze => '0', |
Bus2IP_Freeze => open, |
OPB_Clk => OPB_Clk, |
Bus2IP_Clk => iBus2IP_Clk, |
IP2Bus_Clk => '0', |
Reset => OPB_Rst, |
Bus2IP_Reset => iBus2IP_Reset |
); |
|
---------------------------------------- |
-- instantiate the User Logic |
---------------------------------------- |
USER_LOGIC_I : entity wouter_keyb_v1_00_a.user_logic |
generic map |
( |
-- MAP USER GENERICS BELOW THIS LINE --------------- |
--USER generics mapped here |
-- MAP USER GENERICS ABOVE THIS LINE --------------- |
|
C_DWIDTH => USER_DWIDTH, |
C_NUM_CE => USER_NUM_CE |
) |
port map |
( |
-- MAP USER PORTS BELOW THIS LINE ------------------ |
keyb_interrupt, |
keyb_clk_out, |
keyb_cols, |
keyb_rows, |
keyb_up, |
-- MAP USER PORTS ABOVE THIS LINE ------------------ |
|
Bus2IP_Clk => iBus2IP_Clk, |
Bus2IP_Reset => iBus2IP_Reset, |
Bus2IP_Data => uBus2IP_Data, |
Bus2IP_BE => uBus2IP_BE, |
Bus2IP_RdCE => uBus2IP_RdCE, |
Bus2IP_WrCE => uBus2IP_WrCE, |
IP2Bus_Data => uIP2Bus_Data, |
IP2Bus_Ack => iIP2Bus_Ack, |
IP2Bus_Retry => iIP2Bus_Retry, |
IP2Bus_Error => iIP2Bus_Error, |
IP2Bus_ToutSup => iIP2Bus_ToutSup |
); |
|
---------------------------------------- |
-- hooking up signal slicing |
---------------------------------------- |
uBus2IP_BE <= iBus2IP_BE(0 to USER_DWIDTH/8-1); |
uBus2IP_Data <= iBus2IP_Data(0 to USER_DWIDTH-1); |
uBus2IP_RdCE <= iBus2IP_RdCE(USER00_CE_INDEX to USER00_CE_INDEX+USER_NUM_CE-1); |
uBus2IP_WrCE <= iBus2IP_WrCE(USER00_CE_INDEX to USER00_CE_INDEX+USER_NUM_CE-1); |
iIP2Bus_Data(0 to USER_DWIDTH-1) <= uIP2Bus_Data; |
|
end IMP; |
/tags/KEYB_CON_0_01/Strober.vhd
0,0 → 1,67
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use work.Constants.all; |
|
entity Strober is |
port (reset, clk : in std_logic; |
strobe : in std_logic; |
sample : in std_logic; |
env_col : in col; |
env_row : out row; |
sample_col : out col; --rows and cols to be analysed |
sample_row_number : out row_number |
); |
|
end Strober; |
|
architecture Strober_arc of Strober is |
|
function decode_row(inp: row_number) return row is |
variable rowstrobe : row; |
begin |
case inp is |
when 11 => rowstrobe := "011111111111"; |
when 10 => rowstrobe := "101111111111"; |
when 9 => rowstrobe := "110111111111"; |
when 8 => rowstrobe := "111011111111"; |
when 7 => rowstrobe := "111101111111"; |
when 6 => rowstrobe := "111110111111"; |
when 5 => rowstrobe := "111111011111"; |
when 4 => rowstrobe := "111111101111"; |
when 3 => rowstrobe := "111111110111"; |
when 2 => rowstrobe := "111111111011"; |
when 1 => rowstrobe := "111111111101"; |
when 0 => rowstrobe := "111111111110"; |
when others => rowstrobe := "111111111111"; |
end case; |
return rowstrobe; |
end decode_row; |
|
begin |
|
strober: process |
variable row_counter : integer; |
begin |
wait until rising_edge(clk); |
if (reset = '1') then |
env_row <= "111111111111"; |
row_counter := 0; |
elsif (strobe = '1') then |
if (row_counter < number_of_cols-1) then |
row_counter := row_counter + 1; |
elsif(row_counter = number_of_cols-1)then |
row_counter := 0; |
end if; |
env_row <= decode_row(row_counter); |
elsif (sample ='1') then --first sample |
sample_row_number <= row_counter; |
sample_col <= not env_col; |
end if; |
end process; |
|
end strober_arc; |
|
|
|
|
/tags/KEYB_CON_0_01/Keyboard_controller.vhd
0,0 → 1,125
----------------------------------------------------------------------------------------------- |
-- |
-- Keyboard controller entity |
-- |
-- The controller scans the columns, cols, by making a different column logic-0 |
-- therefor the inputs have to be pull-up high. It processes the input, rows, and |
-- the pressed key to a corresponding scancode and giving an interrupt |
-- |
-- Author: Wouter Wiggers |
-- Mail: w.a.wiggers@student.utwente.nl |
-- |
------------------------------------------------------------------------------------------------ |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
use work.Constants.all; |
|
entity Keyboard_controller is |
|
port (reset, clk_in : in std_logic; |
clk_out : out std_logic; |
cols : in col; |
rows : out row; |
scan : out scancode; |
interrupt : out std_logic |
); |
end Keyboard_controller; |
|
architecture structure of Keyboard_controller is |
|
component Strober |
port (reset, clk : in std_logic; |
strobe : in std_logic; |
sample : in std_logic; |
env_col : in col; |
env_row : out row; |
sample_col : out col; |
sample_row_number : out row_number |
); |
end component; |
|
component Analyser |
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 component; |
|
component Producer |
port (reset, clk: in std_logic; |
produce : in std_logic; |
released : in std_logic; |
|
conv_col : in col_number; |
conv_row : in row_number; |
|
scanc : out scancode; |
interrupt : out std_logic |
); |
end component; |
|
component FSM |
port (reset, clk : in std_logic; |
strobe : out std_logic; |
sample : out std_logic; |
analyse : out std_logic; |
store : out std_logic; |
produce : out std_logic; |
release : out std_logic; |
debounced : in std_logic; |
keychanged : in std_logic; --keychange found |
keyreleased : in std_logic |
); |
end component; |
|
|
signal stb: std_logic; |
signal str: std_logic; |
signal sam: std_logic; |
signal ana: std_logic; |
signal pro: std_logic; |
signal rel: std_logic; |
|
signal deb: std_logic; |
signal keyc: std_logic; |
signal keyr: std_logic; |
|
signal col_sample : col; |
signal row_sample_number : row_number; |
|
signal col_conv : col_number; |
signal row_conv : row_number; |
|
signal clk : std_logic; |
|
begin |
-- divide by 512 |
clockdiv: process |
variable count : std_logic_vector(8 downto 0); |
begin |
wait until rising_edge(clk_in); |
count := std_logic_vector(to_unsigned( (to_integer(unsigned(count)) + 1),9 )); |
clk <= count(8); |
end process; |
|
clk_out <= clk; |
|
strb: Strober port map (reset, clk, stb, sam, cols, rows, col_sample, row_sample_number); |
|
analys: Analyser port map (reset, clk, ana, str, deb, keyc, keyr, col_sample, row_sample_number, col_conv, row_conv); |
|
prod: Producer port map (reset, clk, pro, rel, col_conv, row_conv, scan, interrupt); |
|
finsm: FSM port map (reset, clk, stb, sam, ana, str, pro, rel , deb, keyc, keyr); |
|
end structure; |
/tags/KEYB_CON_0_01/Producer.vhd
0,0 → 1,59
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use ieee.std_logic_arith.sxt; |
use work.Constants.all; |
|
entity Producer is |
port (reset, clk: in std_logic; |
produce : in std_logic; |
released : in std_logic; |
|
conv_col : in col_number; |
conv_row : in row_number; |
|
scanc : out scancode; |
interrupt : out std_logic |
); |
|
end Producer; |
|
architecture Producer_arc of Producer is |
|
signal next_scanc: std_logic_vector(scancode_width-1 downto 0); |
|
|
begin |
|
process(released, conv_row, conv_col) |
|
variable index: natural range 0 to 93; |
variable tmp : std_logic_vector(6 downto 0); |
|
begin |
--make address out of col and row number of the pressed/released key |
tmp := std_logic_vector(to_unsigned(conv_row,4)) & std_logic_vector(to_unsigned(conv_col,3)); |
index := to_integer(unsigned(tmp)); |
--look-up scancode |
next_scanc <= set1_scancodes_lut(index); |
if (released='1') then |
next_scanc(scancode_width-1)<='1'; --add 0x80 for keyrelease scancode |
end if; |
end process; |
|
--put values in registers on next rising edge |
process |
begin |
wait until rising_edge(clk); |
if (reset='1') then |
scanc <= "00000000"; |
interrupt <= '0'; |
elsif(produce = '1') then |
scanc <= next_scanc; |
interrupt <= '1'; |
else |
interrupt <= '0'; |
end if; |
end process; |
|
end Producer_arc; |
/tags/KEYB_CON_0_01/FSM.vhd
0,0 → 1,78
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use work.Constants.all; |
|
entity FSM is |
port (reset, clk : in std_logic; |
strobe : out std_logic; |
sample : out std_logic; |
analyse : out std_logic; |
store : out std_logic; |
produce : out std_logic; |
release : out std_logic; |
debounced : in std_logic; |
keychanged : in std_logic; --keychange found |
keyreleased : in std_logic |
); |
end FSM; |
|
architecture FSM_arc of FSM is |
signal nState, cState : states; |
begin |
|
process |
begin |
wait until rising_edge(clk); |
if( reset = '1' ) then |
cState <= idle; |
else |
cState <= nState; |
end if; |
end process; |
|
process(cState, debounced, keychanged, keyreleased) |
|
begin |
case cState is |
|
when idle => nState <= strobing; |
|
when strobing => nState <= sampling; |
|
when sampling => nState <= analysing; |
|
when analysing => if (debounced='1') then |
nState <= storing; |
else |
nState <= analysing; |
end if; |
|
when storing => nState <= storing_stage2; |
|
when storing_stage2 => if (keychanged='1' and keyreleased='0') then |
nState <= producenormal; |
elsif(keychanged='1' and keyreleased='1') then |
nState <= producerelease; |
elsif (keychanged='0') then |
nState <= strobing; |
end if; |
|
when producenormal => nState <= strobing; |
|
when producerelease => nState <= strobing; |
|
when others => nState <= idle; |
|
end case; |
|
end process; |
|
strobe <= cState(6); |
sample <= cState(5); |
analyse <= cState(4); |
store <= cState(3); |
produce <= cState(2); |
release <= cState(1); |
|
end FSM_arc; |
/tags/KEYB_CON_0_01/user_logic.vhd
0,0 → 1,230
------------------------------------------------------------------------------ |
-- user_logic.vhd - entity/architecture pair |
------------------------------------------------------------------------------ |
-- |
-- *************************************************************************** |
-- ** Copyright (c) 1995-2004 Xilinx, Inc. All rights reserved. ** |
-- ** ** |
-- ** Xilinx, Inc. ** |
-- ** XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" ** |
-- ** AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND ** |
-- ** SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, ** |
-- ** OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, ** |
-- ** APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION ** |
-- ** THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, ** |
-- ** AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE ** |
-- ** FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY ** |
-- ** WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE ** |
-- ** IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR ** |
-- ** REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF ** |
-- ** INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ** |
-- ** FOR A PARTICULAR PURPOSE. ** |
-- ** ** |
-- ** YOU MAY COPY AND MODIFY THESE FILES FOR YOUR OWN INTERNAL USE SOLELY ** |
-- ** WITH XILINX PROGRAMMABLE LOGIC DEVICES AND XILINX EDK SYSTEM OR ** |
-- ** CREATE IP MODULES SOLELY FOR XILINX PROGRAMMABLE LOGIC DEVICES AND ** |
-- ** XILINX EDK SYSTEM. NO RIGHTS ARE GRANTED TO DISTRIBUTE ANY FILES ** |
-- ** UNLESS THEY ARE DISTRIBUTED IN XILINX PROGRAMMABLE LOGIC DEVICES. ** |
-- ** ** |
-- *************************************************************************** |
-- |
------------------------------------------------------------------------------ |
-- Filename: user_logic.vhd |
-- Version: 1.00.a |
-- Description: User logic module. |
-- Date: Wed Jun 15 10:21:28 2005 (by Create and Import Peripheral Wizard) |
-- VHDL-Standard: VHDL'93 |
------------------------------------------------------------------------------ |
-- Naming Conventions: |
-- active low signals: "*_n" |
-- clock signals: "clk", "clk_div#", "clk_#x" |
-- reset signals: "rst", "rst_n" |
-- generics: "C_*" |
-- user defined types: "*_TYPE" |
-- state machine next state: "*_ns" |
-- state machine current state: "*_cs" |
-- combinatorial signals: "*_com" |
-- pipelined or register delay signals: "*_d#" |
-- counter signals: "*cnt*" |
-- clock enable signals: "*_ce" |
-- internal version of output port: "*_i" |
-- device pins: "*_pin" |
-- ports: "- Names begin with Uppercase" |
-- processes: "*_PROCESS" |
-- component instantiations: "<ENTITY_>I_<#|FUNC>" |
------------------------------------------------------------------------------ |
|
-- DO NOT EDIT BELOW THIS LINE -------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
|
library proc_common_v2_00_a; |
use proc_common_v2_00_a.proc_common_pkg.all; |
|
-- DO NOT EDIT ABOVE THIS LINE -------------------- |
|
--USER libraries added here |
library wouter_keyb_v1_00_a; |
use Constants.all; |
--use Keyboard_controller; |
------------------------------------------------------------------------------ |
-- Definition of Generics: |
-- C_DWIDTH -- User logic data bus width |
-- C_NUM_CE -- User logic chip enable bus width |
-- |
-- Definition of Ports: |
-- Bus2IP_Clk -- Bus to IP clock |
-- Bus2IP_Reset -- Bus to IP reset |
-- Bus2IP_Data -- Bus to IP data bus for user logic |
-- Bus2IP_BE -- Bus to IP byte enables for user logic |
-- Bus2IP_RdCE -- Bus to IP read chip enable for user logic |
-- Bus2IP_WrCE -- Bus to IP write chip enable for user logic |
-- IP2Bus_Data -- IP to Bus data bus for user logic |
-- IP2Bus_Ack -- IP to Bus acknowledgement |
-- IP2Bus_Retry -- IP to Bus retry response |
-- IP2Bus_Error -- IP to Bus error response |
-- IP2Bus_ToutSup -- IP to Bus timeout suppress |
-- |
-------------------------------------------------------------------------------- |
-- Entity section |
-------------------------------------------------------------------------------- |
|
entity user_logic is |
generic |
( |
-- ADD USER GENERICS BELOW THIS LINE --------------- |
--USER generics added here |
-- ADD USER GENERICS ABOVE THIS LINE --------------- |
|
-- DO NOT EDIT BELOW THIS LINE --------------------- |
-- Bus protocol parameters, do not add to or delete |
C_DWIDTH : integer := 32; |
C_NUM_CE : integer := 1 |
-- DO NOT EDIT ABOVE THIS LINE --------------------- |
); |
port |
( |
-- ADD USER PORTS BELOW THIS LINE ------------------ |
keyb_interrupt : out std_logic; |
keyb_clk_out : out std_logic; |
keyb_cols : in col; |
keyb_rows : out row; |
keyb_up : out std_logic; |
-- ADD USER PORTS ABOVE THIS LINE ------------------ |
|
-- DO NOT EDIT BELOW THIS LINE --------------------- |
-- Bus protocol ports, do not add to or delete |
Bus2IP_Clk : in std_logic; |
Bus2IP_Reset : in std_logic; |
Bus2IP_Data : in std_logic_vector(0 to C_DWIDTH-1); |
Bus2IP_BE : in std_logic_vector(0 to C_DWIDTH/8-1); |
Bus2IP_RdCE : in std_logic_vector(0 to C_NUM_CE-1); |
Bus2IP_WrCE : in std_logic_vector(0 to C_NUM_CE-1); |
IP2Bus_Data : out std_logic_vector(0 to C_DWIDTH-1); |
IP2Bus_Ack : out std_logic; |
IP2Bus_Retry : out std_logic; |
IP2Bus_Error : out std_logic; |
IP2Bus_ToutSup : out std_logic |
-- DO NOT EDIT ABOVE THIS LINE --------------------- |
); |
end entity user_logic; |
|
-------------------------------------------------------------------------------- |
-- Architecture section |
-------------------------------------------------------------------------------- |
|
architecture IMP of user_logic is |
|
--USER signal declarations added here, as needed for user logic |
signal keyb_scan : scancode; |
---------------------------------------- |
-- Signals for user logic slave model s/w accessible register example |
---------------------------------------- |
signal slv_reg_write_select : std_logic_vector(0 to 0); |
signal slv_reg_read_select : std_logic_vector(0 to 0); |
signal slv_ip2bus_data : std_logic_vector(0 to C_DWIDTH-1); |
signal slv_read_ack : std_logic; |
signal slv_write_ack : std_logic; |
signal bus_reset : std_logic; |
|
component Keyboard_controller |
port (reset, clk_in : in std_logic; |
clk_out : out std_logic; |
cols: in col; |
rows: out row; |
scan : out scancode; |
interrupt : out std_logic |
); |
end component; |
|
begin |
|
keyb: Keyboard_controller port map (bus_reset, Bus2IP_Clk, keyb_clk_out, keyb_cols, keyb_rows, keyb_scan, keyb_interrupt); |
|
--USER logic implementation added here |
|
---------------------------------------- |
-- Example code to read/write user logic slave model s/w accessible registers |
-- |
-- Note: |
-- The example code presented here is to show you one way of reading/writing |
-- software accessible registers implemented in the user logic slave model. |
-- Each bit of the Bus2IP_WrCE/Bus2IP_RdCE signals is configured to correspond |
-- to one software accessible register by the top level template. For example, |
-- if you have four 32 bit software accessible registers in the user logic, you |
-- are basically operating on the following memory mapped registers: |
-- |
-- Bus2IP_WrCE or Memory Mapped |
-- Bus2IP_RdCE Register |
-- "1000" C_BASEADDR + 0x0 |
-- "0100" C_BASEADDR + 0x4 |
-- "0010" C_BASEADDR + 0x8 |
-- "0001" C_BASEADDR + 0xC |
-- |
---------------------------------------- |
slv_reg_write_select <= Bus2IP_WrCE(0 to 0); |
slv_reg_read_select <= Bus2IP_RdCE(0 to 0); |
slv_write_ack <= Bus2IP_WrCE(0); |
slv_read_ack <= Bus2IP_RdCE(0); |
|
RESETTER : process is |
variable count : natural range 0 to 50000; --reset 1ms |
begin |
wait until rising_edge(Bus2IP_Clk); |
if (Bus2IP_Reset='1') then |
count := 0; |
else |
if (count < 50000) then |
count := count + 1; |
bus_reset <= '1'; |
else |
bus_reset <= '0'; |
end if; |
end if; |
end process RESETTER; |
|
SLAVE_REG_READ_PROC : process( slv_reg_read_select, keyb_scan) is |
begin |
|
case slv_reg_read_select is |
when "1" => slv_ip2bus_data <= keyb_scan; |
when others => slv_ip2bus_data <= (others => '0'); |
end case; |
|
end process SLAVE_REG_READ_PROC; |
|
---------------------------------------- |
-- Example code to drive IP to Bus signals |
---------------------------------------- |
IP2Bus_Data <= slv_ip2bus_data; |
keyb_up <= keyb_scan(7); |
IP2Bus_Ack <= slv_write_ack or slv_read_ack; |
IP2Bus_Error <= '0'; |
IP2Bus_Retry <= '0'; |
IP2Bus_ToutSup <= '0'; |
|
end IMP; |
/tags/KEYB_CON_0_01/Constants.vhd
0,0 → 1,137
library ieee; |
use ieee.std_logic_1164.all; |
|
library work; |
|
package Constants is |
|
|
constant number_of_rows : natural := 6; |
constant number_of_cols : natural := 12; |
constant scancode_width : natural := 8; |
constant max_keys_pressed : natural := 3; |
|
constant number_of_keys : natural := number_of_rows * number_of_cols; |
|
-- internal clock of 50 Mhz divided by 512 gives about 100 kHz, 1 clock-cycle is about 10 us |
-- 100 ticks is about 1 ms. |
constant debounce_count : natural := 100; |
|
subtype row is std_logic_vector(number_of_cols-1 downto 0); |
subtype col is std_logic_vector(number_of_rows-1 downto 0); |
|
--3 bits |
subtype col_number is natural range 0 to number_of_rows-1; |
--4 bits |
subtype row_number is natural range 0 to number_of_cols-1; |
--number of keys pressed |
subtype key_number is natural range 0 to max_keys_pressed ; |
|
|
subtype states is std_logic_vector(6 downto 0); |
|
--last bit is to differentiate between idle and storing_stage2 |
--output-lines : strobe, sample, analyse, store, produce, release |
constant idle : states := "0000000"; |
constant strobing : states := "1000000"; |
constant sampling : states := "0100000"; |
constant analysing : states := "0110000"; |
constant storing : states := "0001000"; |
constant storing_stage2 : states := "0000001"; |
constant producenormal : states := "0000100"; |
constant producerelease : states := "0000110"; |
|
|
type keymap is array (number_of_rows-1 downto 0) of row; |
|
subtype scancode is std_logic_vector(scancode_width-1 downto 0); |
-- we need 4 bits to encode the columns and 3 bits for the rows, gives an address of 7 bits |
-- that makes 128 possibilities of which 70 are used |
type set1_scancodes_lut_type is array (0 to 93) of std_logic_vector(scancode_width-1 downto 0); |
constant set1_scancodes_lut : set1_scancodes_lut_type := |
(0 => X"01", --esc |
1 => X"10", --q |
2 => X"1e", --a |
3 => X"2a", --lshi |
4 => X"33", --,< |
5 => X"1d", --ctrl |
|
8 => X"3b", --f1 |
9 => X"11", --w |
10 => X"1f", --s |
11 => X"2c", --z |
12 => X"1c", --enter |
13 => X"38", --alt |
|
16 => X"3c", --f2 |
17 => X"12", --e |
18 => X"20", --d |
19 => X"2d", --x |
20 => X"48", --up |
21 => X"39", --space |
|
24 => X"3d", --f3 |
25 => X"13", --r |
26 => X"21", --f |
27 => X"2e", --c |
28 => X"50", --down |
|
32 => X"3e", --f4 |
33 => X"14", --t |
34 => X"22", --g |
35 => X"2f", --v |
36 => X"4b", --left |
|
40 => X"3f", --f5 |
41 => X"15", --y |
42 => X"23", --h |
43 => X"30", --b |
44 => X"4d", --right |
45 => X"39", --space |
|
48 => X"28", --'" |
49 => X"16", --u |
50 => X"24", --j |
51 => X"31", --n |
53 => X"0f", --tab |
|
56 => X"1a", --[{ |
57 => X"17", --i |
58 => X"25", --k |
59 => X"32", --m |
60 => X"34", --.> |
61 => X"3a", --caps |
|
64 => X"1b", --]} |
65 => X"18", --o |
66 => X"26", --l |
67 => X"36", --rshi |
68 => X"0e", --backspace |
69 => X"27", --;: |
|
72 => X"0c", ---_ |
73 => X"19", --p |
74 => X"08", --7& |
75 => X"05", --4$ |
76 => X"52", --ins |
77 => X"02", --1! |
|
80 => X"0d", --=+ |
81 => X"29", --`~ |
82 => X"09", --8* |
83 => X"06", --5% |
84 => X"0b", --0) |
85 => X"03", --2@ |
|
88 => X"2b", --\| |
89 => X"35", --/? |
90 => X"0a", --9( |
91 => X"07", --6^ |
92 => X"53", --del |
93 => X"04", --3# |
|
others => X"00" --error |
); |
|
|
end Constants; |
/tags/KEYB_CON_0_01/Analyser.vhd
0,0 → 1,265
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; |
|