Signal busy as early as possible.
[bos2k9.git] / bos2k9_counter.vhd
1 -----------------------------------------------------------------------
2 -- Copyright (c) 2009 Malte S. Stretz <http://msquadrat.de> 
3 --
4 -- This is a helper entity implementing a counter. It is driven by
5 -- `clk` on the rising edge. `rst` is active high.
6 --
7 -- While `en` is high, it counts the number of ticks given via the
8 -- generic `count`. When reached, `done` is high for exactly one
9 -- `clk` (even if `en` goes low). The counter can be cleared via 
10 -- `clr`.
11 -----------------------------------------------------------------------
12
13 library ieee;
14 use ieee.std_logic_1164.all;
15
16 entity bos2k9_counter is
17   generic(
18     cnt  : positive);
19   port(
20     clk  : in  std_logic;
21     rst  : in  std_logic;
22     en   : in  std_logic;
23     clr  : in  std_logic;
24     done : out std_logic);
25 end bos2k9_counter;
26
27 -----------------------------------------------------------------------
28
29 architecture rtl of bos2k9_counter is
30   -- Use a subtype to please ModelSim's interpretation of attributes.
31   subtype count_t is natural range 0 to cnt - 1;
32   signal count_s : count_t;
33 begin
34   counter : process(clk, rst, en)
35   begin
36     if rst = '1' then
37       count_s <= 0;
38       done    <= '0';
39     elsif rising_edge(clk) then
40       -- `done` must be high for a single `clk` only, even if
41       -- `en` is low.
42       done <= '0';
43       -- This could become an en line for one of the FFs.
44       if (en or clr) = '1' then
45         if clr = '1' then
46           count_s <= count_t'low;
47         elsif count_s = count_t'high then
48           count_s <= count_t'low;
49           done <= '1';
50         else
51           count_s <= count_s + 1;
52         end if;
53       end if;
54     end if;
55   end process;
56 end rtl;