1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity main is
port(
CLK100: in std_logic; -- system clock
PS2_CLK: in std_logic; -- async ps/2 clock input
PS2_DAT: in std_logic; -- async ps/2 data input
DD: out std_logic_vector(7 downto 0); -- display segment data
DS: out std_logic_vector(3 downto 0)); -- display select
end main;
architecture Behavioral of main is
component ps2sync
port(
CLK: in std_logic; -- system clock
PS2_CLK: in std_logic; -- async ps/2 clock input
PS2_DAT: in std_logic; -- async ps/2 data input
DAT: out std_logic_vector(7 downto 0); -- scancode data
NEW_DAT: out std_logic); -- if scancode was just completed (1 for once clock cycle)
end component;
component scancodefilter
port(
CLK: in std_logic; -- system clock
DAT: in std_logic_vector(7 downto 0); -- scancode input
NEW_DAT: in std_logic; -- new scancode input
BCD: out std_logic_vector(3 downto 0); -- bcd digit 0-9 or dash (0xB) for keypress
SHIFT: out std_logic); -- shift display (1 for one clock cycle per key down press)
end component;
component dispshift
port(
CLK: in std_logic; -- system clock
S: in std_logic; -- shift
D: in std_logic_vector(3 downto 0); -- shift input (data)
N0, N1, N2, N3: out std_logic_vector(3 downto 0)); -- shift outputs
end component;
component bcd2disp
port (
CLK: in std_logic; -- system clock
N0, N1, N2, N3: in std_logic_vector(3 downto 0); -- shift inputs
DD: out std_logic_vector(7 downto 0); -- display data
DS: out std_logic_vector(3 downto 0)); -- display select
end component;
signal SYNC_DAT: std_logic_vector(7 downto 0); -- ps2sync <-> scancodefilter
signal SYNC_DAT_NEW: std_logic; -- ps2sync <-> scancodefilter
signal BCD_NEW: std_logic_vector(3 downto 0); -- scancodefilter <-> dispshift
signal BCD_SHIFT: std_logic; -- scancodefilter <-> dispshift
signal N0, N1, N2, N3: std_logic_vector(3 downto 0); -- inputs for display
signal DISP_CLK: std_logic_vector(16 downto 0); -- clock counter for display clock
-- clock period = (2 << 16) / 100_000_000 = 1.31 ms per display / 5.24 ms full refresh
begin
-- convert async ps2 signals into synchronous lines
ps2: component ps2sync
port map (
CLK => CLK100,
PS2_CLK => PS2_CLK,
PS2_DAT => PS2_DAT,
DAT => SYNC_DAT,
NEW_DAT => SYNC_DAT_NEW);
-- filter key up scancodes, and convert non-numeric keys into "-" (0xB)
filter: component scancodefilter
port map(
CLK => CLK100,
DAT => SYNC_DAT,
NEW_DAT => SYNC_DAT_NEW,
BCD => BCD_NEW,
SHIFT => BCD_SHIFT);
-- display 'shift register'
shift_register: component dispshift
port map(
CLK => CLK100,
S => BCD_SHIFT,
D => BCD_NEW,
N0 => N0,
N1 => N1,
N2 => N2,
N3 => N3);
-- display driver clock divider
process(CLK100)
begin
if rising_edge(CLK100) then
DISP_CLK <= (DISP_CLK + 1);
end if;
end process;
-- numbers N0-N3 to displays 0-3
disp: component bcd2disp
port map (
CLK => DISP_CLK(16),
N0 => N3,
N1 => N2,
N2 => N1,
N3 => N0,
DD => DD,
DS => DS);
end Behavioral;
|