URL
https://opencores.org/ocsvn/forth-cpu/forth-cpu/trunk
Subversion Repositories forth-cpu
[/] [forth-cpu/] [trunk/] [timer.vhd] - Rev 3
Go to most recent revision | Compare with Previous | Blame | View Log
------------------------------------------------------------------------------- --| @file timer.vhd --| @brief General Purpose Timer. It is of customizable length, --| the minimum being 4-bits, one for the actual timing, the other --| three for control. (timer.vhd, original file name) --| --| @author Richard James Howe. --| @copyright Copyright 2017 Richard James Howe. --| @license MIT --| @email howe.r.j.89@gmail.com --| --| The control register contains both the value to compare the timer against --| as well as three control bits. Given a "timer_length" value of eight the --| control bits are: --| --| Bit Input Description --| 7 Clock enable --| 6 Timer reset --| 5 Interrupt enable --| 4 - 0 Timer compare value --| ------------------------------------------------------------------------------- library ieee,work,std; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity timer is generic( timer_length: positive := 16); port( clk: in std_ulogic; rst: in std_ulogic; we: in std_ulogic; -- write enable for control register control_i: in std_ulogic_vector(timer_length - 1 downto 0); -- control register counter_o: out std_ulogic_vector(timer_length - 4 downto 0); irq: out std_ulogic); -- generate interrupt end entity; architecture behav of timer is constant highest_bit: positive := timer_length - 1; constant control_enable_bit: positive := highest_bit; constant timer_reset_bit: positive := highest_bit - 1; constant irq_enable_bit: positive := highest_bit - 2; constant timer_highest_bit: positive := highest_bit - 3; signal control_c, control_n: std_ulogic_vector(highest_bit downto 0) := (others => '0'); signal reset_timer: std_ulogic := '0'; signal enabled: std_ulogic := '0'; signal irq_en: std_ulogic := '0'; signal timer_reset: std_ulogic := '0'; signal compare: std_ulogic_vector(timer_highest_bit downto 0) := (others => '0'); signal count: unsigned(timer_highest_bit downto 0) := (others => '0'); begin assert (timer_length >= 4) report "Timer needs to be at least 4 bits wide: 3 bits for control - 1 for counter" severity failure; enabled <= control_c(control_enable_bit); reset_timer <= control_c(timer_reset_bit); irq_en <= control_c(irq_enable_bit); compare <= control_c(timer_highest_bit downto 0); counter_o <= std_ulogic_vector(count); clockRegisters: process(clk, rst) begin if rst = '1' then control_c <= (others => '0'); elsif rising_edge(clk) then control_c <= control_n; end if; end process; counter: process (clk, rst) begin if rst = '1' then count <= (others => '0'); elsif rising_edge(clk) then if reset_timer = '1' or timer_reset = '1' then count <= (others => '0'); elsif enabled = '1' then count <= count + 1; else count <= count; end if; end if; end process; output: process(count, we, control_i, control_c, compare, irq_en, enabled) begin irq <= '0'; control_n <= control_c; timer_reset <= '0'; control_n(timer_reset_bit) <= '0'; -- reset if we = '1' then control_n <= control_i; end if; if count = unsigned(compare) and enabled = '1' then if irq_en = '1' then irq <= '1'; end if; timer_reset <= '1'; end if; end process; end architecture;
Go to most recent revision | Compare with Previous | Blame | View Log