GCC Code Coverage Report
Directory: generated/vunit_out/preprocessed/ Exec Total Coverage
File: generated/vunit_out/preprocessed/common/clock_counter.vhd Lines: 18 18 100.0 %
Date: 2021-06-12 04:12:08 Branches: 39 53 73.6 %

Line Branch Exec Source
1
12
-- -------------------------------------------------------------------------------------------------
2
-- Copyright (c) Lukas Vik. All rights reserved.
3
--
4
-- This file is part of the tsfpga project.
5
-- https://tsfpga.com
6
-- https://gitlab.com/tsfpga/tsfpga
7
-- -------------------------------------------------------------------------------------------------
8
-- Measure the switching rate of an unknown clock by using a freerunning reference clock of
9
-- known frequency.
10
--
11
-- The frequency of target_clock is given by
12
--   target_tick_count * reference_clock_frequency / 2 ** resolution_bits
13
--
14
-- The target_tick_count value is updated every 2 ** resolution_bits cycles. It is invalid for
15
-- 2 * 2 ** resolution_bits cycles in the beginning as reference_clock starts switching,
16
-- but after that it is always valid.
17
--
18
-- For the calculation to work, target_clock must be no more than 2 ** (max_relation_bits - 1) times
19
-- faster than reference_clock.
20
-- -------------------------------------------------------------------------------------------------
21
22
library ieee;
23
use ieee.numeric_std.all;
24
use ieee.std_logic_1164.all;
25
26
library math;
27
use math.math_pkg.all;
28
29
library resync;
30
31
32

149196
entity clock_counter is
33
  generic (
34
    resolution_bits : positive;
35
    max_relation_bits : positive;
36
    -- The shift register length is device specific.
37
    -- For Xilinx ultrascale and 7 series devices, it should be set to 32
38
2
    shift_register_length : integer := 32
39

38
  );
40
  port (
41
2
    target_clock : in std_logic;
42


74
    --
43
    reference_clock : in std_logic;
44
    target_tick_count : out unsigned(resolution_bits + max_relation_bits - 1 downto 0) :=
45
      (others => '0')
46
  );
47
end entity;
48
49
architecture a of clock_counter is
50
51
218
  signal tick_count, tick_count_resync, tick_count_resync_previous :
52
    unsigned(target_tick_count'range) := (others => '0');
53
54
4
  signal reference_tick : std_logic := '0';
55
56
begin
57
58
  ------------------------------------------------------------------------------
59
40
  increment : process
60
  begin
61
149110
    wait until rising_edge(target_clock);
62

860250
    tick_count <= tick_count + 1;
63
  end process;
64
65
66
  ------------------------------------------------------------------------------
67

38
  resync_counter_inst : entity resync.resync_counter
68
    generic map (
69
      width => tick_count'length
70
    )
71
    port map (
72
      clk_in => target_clock,
73
      counter_in => tick_count,
74
      --
75
      clk_out => reference_clock,
76
      counter_out => tick_count_resync
77
    );
78
79
80
  ------------------------------------------------------------------------------
81
2
  periodic_pulse_inst : entity work.periodic_pulser
82
    generic map (
83
      period => 2 ** resolution_bits,
84
      shift_register_length => shift_register_length
85
    )
86
    port map (
87
      clk => reference_clock,
88
      count_enable => '1',
89
      pulse => reference_tick
90
    );
91
92
93
  ------------------------------------------------------------------------------
94
74
  assign_result : process
95
  begin
96

114704
    wait until rising_edge(reference_clock);
97
98
28676
    if reference_tick then
99


532
      target_tick_count <= tick_count_resync - tick_count_resync_previous;
100

57858
      tick_count_resync_previous <= tick_count_resync;
101
    end if;
102
  end process;
103
104
end architecture;