OpenCores
URL https://opencores.org/ocsvn/forth-cpu/forth-cpu/trunk

Subversion Repositories forth-cpu

[/] [forth-cpu/] [trunk/] [timer.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.