-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTIMER.vhd
96 lines (89 loc) · 2.45 KB
/
TIMER.vhd
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
library IEEE;
use IEEE.numeric_std.all;
use IEEE.std_logic_1164.all;
entity TIMER is
--generic(size: integer := 8);
port(
clk, rst: in std_logic;
irq: out std_logic := '0';
-- Data Bus
data_i: in unsigned(7 downto 0);
adr_i: in unsigned(5 downto 0);
we_i: in std_logic;
data_o: out unsigned(7 downto 0)
);
end TIMER;
architecture Malibu of TIMER is
component BUS_SLAVE
generic(
ADR_START : integer;
ADR_STOP : integer
);
port(
clk: in std_logic;
-- Inputs
we_i: in std_logic;
adr_i: in unsigned(5 downto 0);
data_i, data_read_i: in unsigned(7 downto 0);
-- Outputs
data_o: out unsigned(7 downto 0)
);
end component;
-- Timer
signal tcon: unsigned(7 downto 0) := (others => '0');-- Timer Control: 7 -> Timer Enabled, 6 -> Interrupt Enable, 5 -> COMPA Enable, 4 ->, 3 ->, 2:0 -> PreScaler
signal cmpa, cmpb: unsigned(7 downto 0) := (others => '0');-- Compare A, Compare B
signal T, preScaler: unsigned(7 downto 0) := (others => '0');-- Timer Counter, PreScaler Counter
signal clk_ms: unsigned(7 downto 0) := (others => '0');-- Test ms counter
-- Bus
signal reg_data: unsigned(7 downto 0);
begin
-- Bus
BUS_S: BUS_SLAVE generic map(ADR_START => 16, ADR_STOP => 20)
port map(clk => clk, we_i => we_i, adr_i => adr_i, data_i => data_i, data_read_i => reg_data, data_o => data_o);
-- Read Register
reg_data <= T when adr_i = 16 else
tcon when adr_i = 17 else
cmpa when adr_i = 18 else
(others => '0');
-- Main
main:process(clk)
begin
edg:if(rising_edge(clk)) then
irq <= '0';
wrt:if(we_i = '0') then
-- rs:if(rst = '0') then
-- T <= (others => '0');
rs:if(tcon(7) = '1') then
prs:if(preScaler = ((x"01" sll to_integer(tcon(2 downto 0))) - 1)) then
cmp:if(tcon(5) = '1' and (T = (cmpa - 1))) then
T <= (others => '0');
tirq:if(tcon(6) = '1') then
irq <= '1';
end if tirq;
clk_ms <= clk_ms + 1;
else
T <= T + 1;
end if cmp;
preScaler <= (others => '0');
else
preScaler <= preScaler + 1;
end if prs;
end if rs;
else
-- Write Register
case adr_i is
when "010000" => -- 16
T <= data_i;
when "010001" => -- 17
tcon <= data_i;
when "010010" => -- 18
cmpa <= data_i;
when "010011" => -- 19
null;
when others =>
null;
end case;
end if wrt;
end if edg;
end process main;
end Malibu;