This counter can increment, decrement or skip ahead by an arbitrary amount

 1 -------------------------------------------------------------------------------
 2 -- Filename:        inc_dec_addn_cntr.vhd
 3 --
 4 -- Description:     This counter can increment, decrement or skip ahead
 5 --                  by an arbitrary amount.
 6 --
 7 --                  If Reset is active, the value Cnt synchronously resets
 8 --                  to all ones. (This reset value, different than the
 9 --                  customary reset value of zero, caters to the original
10 --                  application of inc_dec_addn_cntr as the address
11 --                  counter for fifo_rbu)
12 --
13 --                  Otherwise, on each Clk, one is added to Cnt if Incr is
14 --                  asserted and one is subtracted if Decr is asserted. 
15 --                  (If both are asserted, then there is no change to Cnt.)
16 --
17 --                  If Decr is not asserted, then the input value,
18 --                  Nm_to_add, is added. (Simultaneous assertion of Incr
19 --                  would add one more.) If Decr is asserted, then
20 --                  N_to_add, is ignored, i.e., it is possible to decrement
21 --                  by one or add N, but not both, and Decr overrides. 
22 --
23 --                  The value that Cnt will take on at the next clock
24 --                  is available as Cnt_p1.
25 --
26 --
27 -- VHDL-Standard:   VHDL'93
28 -------------------------------------------------------------------------------
29 library IEEE;
30 use IEEE.STD_LOGIC_1164.all;
31 
32 -- Uncomment the following library declaration if using
33 -- arithmetic functions with Signed or Unsigned values
34 use IEEE.NUMERIC_STD.all;
35 
36 -- Uncomment the following library declaration if instantiating
37 -- any Xilinx primitives in this code.
38 --library UNISIM;
39 --use UNISIM.VComponents.all;
40 
41 entity inc_dec_addn_cntr is
42   generic (
43     C_SIZE : natural := 8);
44   port (
45     Clk      : in  std_logic;
46     Reset    : in  std_logic; -- Note: the counter resets to all ones!
47     Incr     : in  std_logic;
48     Decr     : in  std_logic;
49     N_to_add : in  std_logic_vector(C_SIZE-1 downto 0);
50     Cnt      : out std_logic_vector(C_SIZE-1 downto 0);
51     Cnt_p1   : out std_logic_vector(C_SIZE-1 downto 0)
52   );
53 end inc_dec_addn_cntr;
54 
55 architecture Behavioral of inc_dec_addn_cntr is
56   signal cnt_r    : std_logic_vector(Cnt'range);
57   signal cnt_p1_r : std_logic_vector(Cnt'range);
58 
59 begin
60   Cnt    <= cnt_r;
61   Cnt_p1 <= cnt_p1_r;
62   
63   CNT_I_P1_PROC : process( cnt_r, N_to_add, Decr, Incr) is
64   
65     function qual_n_to_add(N_to_add : std_logic_vector; Decr : std_logic) return UNSIGNED is
66       variable r : UNSIGNED(N_to_add'range);
67     begin
68       for i in r'range loop
69         r(i) := N_to_add(i) or Decr; -- "1111...111" when Decr = '1'
70       end loop;
71       return r;
72     end;
73 
74     function to_singleton_unsigned(s : std_logic) return unsigned is
75       variable r : unsigned(0 to 0) := (others => s);
76     begin
77       return r;
78     end;
79     
80   begin
81     cnt_p1_r <= std_logic_vector(   UNSIGNED(cnt_r) + qual_n_to_add(N_to_add, Decr) + to_singleton_unsigned(Incr) );
82   end process;
83 
84   CNT_I_PROC : process(Clk) is
85   begin
86     if Clk'event and Clk = '1' then
87       if Reset = '1' then
88         cnt_r <= (others => '1'); -- "11111...111" --> "00000...000" when Incr='1'
89       else
90         cnt_r <= cnt_p1_r;
91       end if;
92     end if;
93   end process;
94 
95 
96 end Behavioral;
posted @ 2012-05-10 13:55  IAmAProgrammer  阅读(247)  评论(0编辑  收藏  举报