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

Subversion Repositories astron_counter

[/] [astron_counter/] [trunk/] [common_counter.vhd] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 danv
-------------------------------------------------------------------------------
2
--
3
-- Copyright (C) 2009
4
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6
--
7
-- This program is free software: you can redistribute it and/or modify
8
-- it under the terms of the GNU General Public License as published by
9
-- the Free Software Foundation, either version 3 of the License, or
10
-- (at your option) any later version.
11
--
12
-- This program is distributed in the hope that it will be useful,
13
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
-- GNU General Public License for more details.
16
--
17
-- You should have received a copy of the GNU General Public License
18
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
--
20
-------------------------------------------------------------------------------
21
 
22
-- Purpose : Counter with extra options
23
-- Description:
24
--   - default wrap at 2**g_width or special wrap at fixed g_max or dynamically via cnt_max
25
--   - default increment +1 or other g_step_size
26
--   - external clr
27
--   - external load with g_init or dynamically via load
28
-- Remarks:
29
-- . If g_max = 2**g_width then use g_max=0 for default wrap and avoid truncation warning.
30
--   The check g_max = 2**g_width does not work for g_width >= 31 due to that the INTEGER
31
--   range in VHDL is limited to -2**31 to +2**31-1. Therefore detect that g_max = 2**g_width
32
--   via ceil_log2(g_max+1)>g_width and use this to init the cnt_max input.
33
 
34
LIBRARY IEEE, common_pkg_lib;
35
USE IEEE.std_logic_1164.all;
36
USE common_pkg_lib.common_pkg.ALL;
37
 
38
 
39
ENTITY common_counter IS
40
  GENERIC (
41
    g_latency   : NATURAL := 1;  -- default 1 for registered count output, use 0 for immediate combinatorial count output
42
    g_init      : INTEGER := 0;
43
    g_width     : NATURAL := 32;
44
    g_max       : NATURAL := 0;  -- default 0 to disable the g_max setting. 
45
    g_step_size : INTEGER := 1   -- counting in steps of g_step_size, can be + or -
46
  );
47
  PORT (
48
    rst     : IN  STD_LOGIC := '0';    -- either use asynchronous rst or synchronous cnt_clr
49
    clk     : IN  STD_LOGIC;
50
    clken   : IN  STD_LOGIC := '1';
51
    cnt_clr : IN  STD_LOGIC := '0';    -- synchronous cnt_clr is only interpreted when clken is active
52
    cnt_ld  : IN  STD_LOGIC := '0';    -- cnt_ld loads the output count with the input load value, independent of cnt_en
53
    cnt_en  : IN  STD_LOGIC := '1';
54
    cnt_max : IN  STD_LOGIC_VECTOR(g_width-1 DOWNTO 0) := TO_UVEC(sel_a_b(ceil_log2(g_max+1)>g_width, 0, g_max),  g_width);  -- see remarks
55
    load    : IN  STD_LOGIC_VECTOR(g_width-1 DOWNTO 0) := TO_SVEC(g_init, g_width);
56
    count   : OUT STD_LOGIC_VECTOR(g_width-1 DOWNTO 0)
57
  );
58
END common_counter;
59
 
60
 
61
ARCHITECTURE rtl OF common_counter IS
62
 
63
  CONSTANT zeros    : STD_LOGIC_VECTOR(count'RANGE) := (OTHERS => '0');           -- used to check if cnt_max is zero
64
  SIGNAL reg_count  : STD_LOGIC_VECTOR(count'RANGE) := TO_SVEC(g_init, g_width);  -- in case rst is not used
65
  SIGNAL nxt_count  : STD_LOGIC_VECTOR(count'RANGE) := TO_SVEC(g_init, g_width);  -- to avoid Warning: NUMERIC_STD.">=": metavalue detected, returning FALSE, when using unsigned()
66
  SIGNAL comb_count : STD_LOGIC_VECTOR(count'RANGE) := TO_SVEC(g_init, g_width);  -- to avoid Warning: NUMERIC_STD.">=": metavalue detected, returning FALSE, when using unsigned()
67
 
68
BEGIN
69
 
70
  comb_count <= nxt_count;
71
 
72
  count <= comb_count WHEN g_latency=0 ELSE reg_count;
73
 
74
  ASSERT g_step_size /= 0 REPORT "common_counter: g_step_size must be /= 0" SEVERITY FAILURE;
75
 
76
  p_clk : PROCESS (rst, clk)
77
  BEGIN
78
    IF rst = '1' THEN
79
      reg_count <= TO_SVEC(g_init, g_width);
80
    ELSIF rising_edge(clk) THEN
81
      IF clken='1' THEN
82
        reg_count <= nxt_count;
83
      END IF;
84
    END IF;
85
  END PROCESS;
86
 
87
  p_count : PROCESS(reg_count, cnt_clr, cnt_en, cnt_ld, load, cnt_max)
88
  BEGIN
89
    nxt_count <= reg_count;
90
    IF cnt_clr='1' OR (reg_count=cnt_max AND cnt_max /= zeros) THEN
91
      nxt_count <= (OTHERS => '0');
92
    ELSIF cnt_ld='1' THEN
93
      nxt_count <= load;
94
    ELSIF cnt_en='1' THEN
95
      nxt_count <= INCR_UVEC(reg_count, g_step_size);
96
    END IF;
97
  END PROCESS;
98
 
99
END rtl;

powered by: WebSVN 2.1.0

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