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 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 danv
-------------------------------------------------------------------------------
2
--
3 3 danv
-- Copyright 2020
4 2 danv
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6 3 danv
-- 
7
-- Licensed under the Apache License, Version 2.0 (the "License");
8
-- you may not use this file except in compliance with the License.
9
-- You may obtain a copy of the License at
10
-- 
11
--     http://www.apache.org/licenses/LICENSE-2.0
12
-- 
13
-- Unless required by applicable law or agreed to in writing, software
14
-- distributed under the License is distributed on an "AS IS" BASIS,
15
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
-- See the License for the specific language governing permissions and
17
-- limitations under the License.
18 2 danv
--
19
-------------------------------------------------------------------------------
20
 
21
-- Purpose : Counter with extra options
22
-- Description:
23
--   - default wrap at 2**g_width or special wrap at fixed g_max or dynamically via cnt_max
24
--   - default increment +1 or other g_step_size
25
--   - external clr
26
--   - external load with g_init or dynamically via load
27
-- Remarks:
28
-- . If g_max = 2**g_width then use g_max=0 for default wrap and avoid truncation warning.
29
--   The check g_max = 2**g_width does not work for g_width >= 31 due to that the INTEGER
30
--   range in VHDL is limited to -2**31 to +2**31-1. Therefore detect that g_max = 2**g_width
31
--   via ceil_log2(g_max+1)>g_width and use this to init the cnt_max input.
32
 
33
LIBRARY IEEE, common_pkg_lib;
34
USE IEEE.std_logic_1164.all;
35
USE common_pkg_lib.common_pkg.ALL;
36
 
37
 
38
ENTITY common_counter IS
39
  GENERIC (
40
    g_latency   : NATURAL := 1;  -- default 1 for registered count output, use 0 for immediate combinatorial count output
41
    g_init      : INTEGER := 0;
42
    g_width     : NATURAL := 32;
43
    g_max       : NATURAL := 0;  -- default 0 to disable the g_max setting. 
44
    g_step_size : INTEGER := 1   -- counting in steps of g_step_size, can be + or -
45
  );
46
  PORT (
47
    rst     : IN  STD_LOGIC := '0';    -- either use asynchronous rst or synchronous cnt_clr
48
    clk     : IN  STD_LOGIC;
49
    clken   : IN  STD_LOGIC := '1';
50
    cnt_clr : IN  STD_LOGIC := '0';    -- synchronous cnt_clr is only interpreted when clken is active
51
    cnt_ld  : IN  STD_LOGIC := '0';    -- cnt_ld loads the output count with the input load value, independent of cnt_en
52
    cnt_en  : IN  STD_LOGIC := '1';
53
    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
54
    load    : IN  STD_LOGIC_VECTOR(g_width-1 DOWNTO 0) := TO_SVEC(g_init, g_width);
55
    count   : OUT STD_LOGIC_VECTOR(g_width-1 DOWNTO 0)
56
  );
57
END common_counter;
58
 
59
 
60
ARCHITECTURE rtl OF common_counter IS
61
 
62
  CONSTANT zeros    : STD_LOGIC_VECTOR(count'RANGE) := (OTHERS => '0');           -- used to check if cnt_max is zero
63
  SIGNAL reg_count  : STD_LOGIC_VECTOR(count'RANGE) := TO_SVEC(g_init, g_width);  -- in case rst is not used
64
  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()
65
  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()
66
 
67
BEGIN
68
 
69
  comb_count <= nxt_count;
70
 
71
  count <= comb_count WHEN g_latency=0 ELSE reg_count;
72
 
73
  ASSERT g_step_size /= 0 REPORT "common_counter: g_step_size must be /= 0" SEVERITY FAILURE;
74
 
75
  p_clk : PROCESS (rst, clk)
76
  BEGIN
77
    IF rst = '1' THEN
78
      reg_count <= TO_SVEC(g_init, g_width);
79
    ELSIF rising_edge(clk) THEN
80
      IF clken='1' THEN
81
        reg_count <= nxt_count;
82
      END IF;
83
    END IF;
84
  END PROCESS;
85
 
86
  p_count : PROCESS(reg_count, cnt_clr, cnt_en, cnt_ld, load, cnt_max)
87
  BEGIN
88
    nxt_count <= reg_count;
89
    IF cnt_clr='1' OR (reg_count=cnt_max AND cnt_max /= zeros) THEN
90
      nxt_count <= (OTHERS => '0');
91
    ELSIF cnt_ld='1' THEN
92
      nxt_count <= load;
93
    ELSIF cnt_en='1' THEN
94
      nxt_count <= INCR_UVEC(reg_count, g_step_size);
95
    END IF;
96
  END PROCESS;
97
 
98
END rtl;

powered by: WebSVN 2.1.0

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