1 |
3 |
howe.r.j.8 |
-------------------------------------------------------------------------------
|
2 |
|
|
--| @file timer.vhd
|
3 |
|
|
--| @brief General Purpose Timer. It is of customizable length,
|
4 |
|
|
--| the minimum being 4-bits, one for the actual timing, the other
|
5 |
|
|
--| three for control. (timer.vhd, original file name)
|
6 |
|
|
--|
|
7 |
|
|
--| @author Richard James Howe.
|
8 |
|
|
--| @copyright Copyright 2017 Richard James Howe.
|
9 |
|
|
--| @license MIT
|
10 |
|
|
--| @email howe.r.j.89@gmail.com
|
11 |
|
|
--|
|
12 |
|
|
--| The control register contains both the value to compare the timer against
|
13 |
|
|
--| as well as three control bits. Given a "timer_length" value of eight the
|
14 |
|
|
--| control bits are:
|
15 |
|
|
--|
|
16 |
|
|
--| Bit Input Description
|
17 |
|
|
--| 7 Clock enable
|
18 |
|
|
--| 6 Timer reset
|
19 |
|
|
--| 5 Interrupt enable
|
20 |
|
|
--| 4 - 0 Timer compare value
|
21 |
|
|
--|
|
22 |
|
|
-------------------------------------------------------------------------------
|
23 |
|
|
|
24 |
|
|
library ieee,work,std;
|
25 |
|
|
use ieee.std_logic_1164.all;
|
26 |
|
|
use ieee.numeric_std.all;
|
27 |
5 |
howe.r.j.8 |
use work.util.common_generics;
|
28 |
3 |
howe.r.j.8 |
|
29 |
|
|
entity timer is
|
30 |
|
|
generic(
|
31 |
5 |
howe.r.j.8 |
g: common_generics;
|
32 |
3 |
howe.r.j.8 |
timer_length: positive := 16);
|
33 |
|
|
port(
|
34 |
|
|
clk: in std_ulogic;
|
35 |
|
|
rst: in std_ulogic;
|
36 |
|
|
|
37 |
|
|
we: in std_ulogic; -- write enable for control register
|
38 |
|
|
control_i: in std_ulogic_vector(timer_length - 1 downto 0); -- control register
|
39 |
|
|
counter_o: out std_ulogic_vector(timer_length - 4 downto 0);
|
40 |
|
|
irq: out std_ulogic); -- generate interrupt
|
41 |
|
|
end entity;
|
42 |
|
|
|
43 |
|
|
architecture behav of timer is
|
44 |
|
|
constant highest_bit: positive := timer_length - 1;
|
45 |
|
|
constant control_enable_bit: positive := highest_bit;
|
46 |
|
|
constant timer_reset_bit: positive := highest_bit - 1;
|
47 |
|
|
constant irq_enable_bit: positive := highest_bit - 2;
|
48 |
|
|
constant timer_highest_bit: positive := highest_bit - 3;
|
49 |
|
|
|
50 |
|
|
signal control_c, control_n: std_ulogic_vector(highest_bit downto 0) := (others => '0');
|
51 |
|
|
|
52 |
|
|
signal reset_timer: std_ulogic := '0';
|
53 |
|
|
signal enabled: std_ulogic := '0';
|
54 |
|
|
signal irq_en: std_ulogic := '0';
|
55 |
|
|
|
56 |
|
|
signal timer_reset: std_ulogic := '0';
|
57 |
|
|
|
58 |
|
|
signal compare: std_ulogic_vector(timer_highest_bit downto 0) := (others => '0');
|
59 |
|
|
signal count: unsigned(timer_highest_bit downto 0) := (others => '0');
|
60 |
|
|
begin
|
61 |
|
|
assert (timer_length >= 4) report "Timer needs to be at least 4 bits wide: 3 bits for control - 1 for counter" severity failure;
|
62 |
|
|
|
63 |
|
|
enabled <= control_c(control_enable_bit);
|
64 |
|
|
reset_timer <= control_c(timer_reset_bit);
|
65 |
|
|
irq_en <= control_c(irq_enable_bit);
|
66 |
|
|
compare <= control_c(timer_highest_bit downto 0);
|
67 |
|
|
|
68 |
|
|
counter_o <= std_ulogic_vector(count);
|
69 |
|
|
|
70 |
|
|
counter: process (clk, rst)
|
71 |
|
|
begin
|
72 |
5 |
howe.r.j.8 |
if rst = '1' and g.asynchronous_reset then
|
73 |
|
|
count <= (others => '0') after g.delay;
|
74 |
|
|
control_c <= (others => '0') after g.delay;
|
75 |
3 |
howe.r.j.8 |
elsif rising_edge(clk) then
|
76 |
5 |
howe.r.j.8 |
if rst = '1' and not g.asynchronous_reset then
|
77 |
|
|
count <= (others => '0') after g.delay;
|
78 |
|
|
control_c <= (others => '0') after g.delay;
|
79 |
3 |
howe.r.j.8 |
else
|
80 |
5 |
howe.r.j.8 |
control_c <= control_n;
|
81 |
|
|
if reset_timer = '1' or timer_reset = '1' then
|
82 |
|
|
count <= (others => '0') after g.delay;
|
83 |
|
|
elsif enabled = '1' then
|
84 |
|
|
count <= count + 1 after g.delay;
|
85 |
|
|
else
|
86 |
|
|
count <= count after g.delay;
|
87 |
|
|
end if;
|
88 |
3 |
howe.r.j.8 |
end if;
|
89 |
|
|
end if;
|
90 |
|
|
end process;
|
91 |
|
|
|
92 |
|
|
output: process(count, we, control_i, control_c, compare, irq_en, enabled)
|
93 |
|
|
begin
|
94 |
|
|
if we = '1' then
|
95 |
5 |
howe.r.j.8 |
control_n <= control_i after g.delay;
|
96 |
|
|
else
|
97 |
|
|
control_n <= control_c after g.delay;
|
98 |
|
|
control_n(timer_reset_bit) <= '0' after g.delay; -- reset
|
99 |
3 |
howe.r.j.8 |
end if;
|
100 |
|
|
|
101 |
|
|
if count = unsigned(compare) and enabled = '1' then
|
102 |
5 |
howe.r.j.8 |
irq <= irq_en after g.delay;
|
103 |
|
|
timer_reset <= '1' after g.delay;
|
104 |
|
|
else
|
105 |
|
|
irq <= '0' after g.delay;
|
106 |
|
|
timer_reset <= '0' after g.delay;
|
107 |
3 |
howe.r.j.8 |
end if;
|
108 |
|
|
end process;
|
109 |
|
|
end architecture;
|
110 |
|
|
|