OpenCores
URL https://opencores.org/ocsvn/potato/potato/trunk

Subversion Repositories potato

[/] [potato/] [trunk/] [soc/] [pp_soc_timer.vhd] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 skordal
-- The Potato Processor - A simple processor for FPGAs
2
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net>
3
-- Report bugs and issues on <https://github.com/skordal/potato/issues>
4
 
5
library ieee;
6
use ieee.std_logic_1164.all;
7
use ieee.numeric_std.all;
8
 
9
--! @brief Simple timer module for generating periodic interrupts.
10
--! The following registers are defined:
11
--! * 0: Control register. The bits are:
12
--!      - 0: Run - set to '1' to enable the counter
13
--!      - 1: Clear - set to '1' to clear the counter after a comparison match or just to reset it
14
--! * 1: Compare register, set this to the value where an interrupt should be generated.
15
--! * 2: Counter register, should only be read, but can be written if you want to.
16
entity pp_soc_timer is
17
        port(
18
                clk   : in std_logic;
19
                reset : in std_logic;
20
 
21
                -- Timer interrupt:
22
                irq : out std_logic;
23
 
24
                -- Wishbone interface:
25
                wb_adr_in  : in  std_logic_vector( 1 downto 0);
26
                wb_dat_in  : in  std_logic_vector(31 downto 0);
27
                wb_dat_out : out std_logic_vector(31 downto 0);
28
                wb_cyc_in  : in  std_logic;
29
                wb_stb_in  : in  std_logic;
30
                wb_we_in   : in  std_logic;
31
                wb_ack_out : out std_logic
32
        );
33
end entity;
34
 
35
architecture behaviour of pp_soc_timer is
36
        signal ctrl_run : std_logic;
37
 
38
        signal counter : std_logic_vector(31 downto 0);
39
        signal compare : std_logic_vector(31 downto 0);
40
 
41
        -- Wishbone acknowledge signal:
42
        signal ack : std_logic;
43
begin
44
 
45
        wb_ack_out <= ack and wb_cyc_in and wb_stb_in;
46
        irq <= '1' when counter = compare else '0';
47
 
48
        timer: process(clk)
49
        begin
50
                if rising_edge(clk) then
51
                        if reset = '1' then
52
                                wb_dat_out <= (others => '0');
53
                                ack <= '0';
54
 
55
                                ctrl_run <= '0';
56
                                counter <= (others => '0');
57
                                compare <= (others => '1');
58
                        else
59
                                if ctrl_run = '1' and counter /= compare then
60
                                        counter <= std_logic_vector(unsigned(counter) + 1);
61
                                end if;
62
 
63
                                if wb_cyc_in = '1' and wb_stb_in = '1' and ack = '0' then
64
                                        if wb_we_in = '1' then
65
                                                case wb_adr_in is
66
                                                        when b"00" => -- Write control register
67
                                                                ctrl_run <= wb_dat_in(0);
68
                                                                if wb_dat_in(1) = '1' then
69
                                                                        counter <= (others => '0');
70
                                                                end if;
71
                                                        when b"01" => -- Write compare register
72
                                                                compare <= wb_dat_in;
73
                                                        when b"10" => -- Write count register
74
                                                                counter <= wb_dat_in;
75
                                                        when b"11" => -- Unused register
76
                                                        when others =>
77
                                                end case;
78
                                                ack <= '1';
79
                                        else
80
                                                case wb_adr_in is
81
                                                        when b"00" => -- Read control register
82
                                                                wb_dat_out <= (0 => ctrl_run, others => '0');
83
                                                        when b"01" => -- Read compare register
84
                                                                wb_dat_out <= compare;
85
                                                        when b"10" => -- Read count register
86
                                                                wb_dat_out <= counter;
87
                                                        when b"11" => -- Unused register
88
                                                        when others =>
89
                                                end case;
90
                                                ack <= '1';
91
                                        end if;
92
                                elsif wb_stb_in = '0' then
93
                                        ack <= '0';
94
                                end if;
95
                        end if;
96
                end if;
97
        end process timer;
98
 
99
end architecture behaviour;

powered by: WebSVN 2.1.0

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