GCC Code Coverage Report
Directory: generated/vunit_out/preprocessed/ Exec Total Coverage
File: generated/vunit_out/preprocessed/resync/resync_counter.vhd Lines: 14 14 100.0 %
Date: 2021-06-12 04:12:08 Branches: 44 58 75.9 %

Line Branch Exec Source
1
2448
-- -------------------------------------------------------------------------------------------------
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
-- Synchronize a counter value between two domains
9
--
10
-- This module assumes that the input counter value only increments
11
-- and decrements in steps of one.
12
--
13
-- Note that unlike e.g. resync_level, it is safe to drive the input of this entity with LUTs
14
-- as well as FFs.
15
-- -------------------------------------------------------------------------------------------------
16
17
library ieee;
18
use ieee.std_logic_1164.all;
19
use ieee.numeric_std.all;
20
21
library common;
22
use common.attribute_pkg.all;
23
24
library math;
25
use math.math_pkg.all;
26
27
28


27527095
entity resync_counter is
29
  generic (
30
    width : positive;
31
    -- Initial value for the ouput that will be set for a few cycles before the first input
32
    -- value has propagated.
33
    default_value   : unsigned(width - 1 downto 0) := (others => '0');
34
    -- Optional pipeline step on the output after Gray conversion
35
    pipeline_output : boolean := false
36
  );
37
  port (
38
    clk_in     : in std_logic;
39
    counter_in : in unsigned(default_value'range);
40
41
    clk_out     : in std_logic;
42
    counter_out : out unsigned(default_value'range) := default_value
43
  );
44
end entity;
45
46
architecture a of resync_counter is
47
8022
  signal counter_in_gray, counter_in_gray_p1, counter_out_gray : std_logic_vector(counter_in'range)
48
    := to_gray(default_value);
49
50
  attribute dont_touch of counter_in_gray   : signal is "true";
51
  attribute async_reg of counter_in_gray_p1 : signal is "true";
52
  attribute async_reg of counter_out_gray   : signal is "true";
53
begin
54
55
  ------------------------------------------------------------------------------
56
2946
  clk_in_process : process
57
  begin
58
27513679
    wait until rising_edge(clk_in);
59
60

83530348
    counter_in_gray <= to_gray(counter_in);
61
  end process;
62
63
64
  ------------------------------------------------------------------------------
65
5484
  clk_out_process : process
66
  begin
67

27374272
    wait until rising_edge(clk_out);
68
69

48698120
    counter_out_gray   <= counter_in_gray_p1;
70


55679239
    counter_in_gray_p1 <= counter_in_gray;
71
  end process;
72
73
74
  ------------------------------------------------------------------------------
75
  optional_output_pipe : if pipeline_output generate
76
77
417
    pipe : process
78
    begin
79

137588
      wait until rising_edge(clk_out);
80
81


343970
      counter_out <= from_gray(counter_out_gray);
82
    end process;
83
84
  else generate
85
86


1429306
    counter_out <= from_gray(counter_out_gray);
87
88
  end generate;
89
90
end architecture;