GCC Code Coverage Report
Directory: generated/vunit_out/preprocessed/ Exec Total Coverage
File: generated/vunit_out/preprocessed/resync/resync_cycles.vhd Lines: 24 24 100.0 %
Date: 2021-06-12 04:12:08 Branches: 48 66 72.7 %

Line Branch Exec Source
1
78
-- -------------------------------------------------------------------------------------------------
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
-- Resynchronizes a bit, so that the output bit is asserted as many
9
-- clock cycles as the input bit.
10
--
11
-- This module counts each clk_in cycle the input bit is asserted.
12
-- The counter is resynchronized to clk_out, and used as a reference to know
13
-- how many clk_out cycles the output bit should be asserted.
14
-- The module may fail when clk_out is slower than clk_in and the input is
15
-- asserted many cycles in a row. An assertion is made to check for this case.
16
--
17
-- Note that unlike e.g. resync_level, it is safe to drive the input of this entity with LUTs
18
-- as well as FFs.
19
-- -------------------------------------------------------------------------------------------------
20
21
library ieee;
22
use ieee.std_logic_1164.all;
23
use ieee.numeric_std.all;
24
25
library common;
26
use common.types_pkg.all;
27
28
library math;
29
use math.math_pkg.all;
30
31
32


40231
entity resync_cycles is
33
  generic (
34
    counter_width : positive;
35
    active_level : std_logic := '1'
36
  );
37
  port (
38
13
    clk_in : in std_logic;
39

87
    data_in : in std_logic;
40
41
13
    clk_out : in std_logic;
42



62354
    data_out : out std_logic := (not active_level)
43
  );
44
end entity;
45
46
architecture a of resync_cycles is
47
470
  signal counter_in, counter_in_resync, counter_out : unsigned(counter_width - 1 downto 0) := (others => '0');
48
begin
49
50
  ------------------------------------------------------------------------------
51
87
  input : process
52
  begin
53
40127
    wait until rising_edge(clk_in);
54
55
10029
    if data_in = active_level then
56
37351
      counter_in <= (counter_in + 1);
57
    end if;
58
  end process;
59
60
61
  ------------------------------------------------------------------------------
62

87
  counter_in_resync_inst : entity work.resync_counter
63
    generic map (
64
      width => counter_width
65
    )
66
    port map (
67
      clk_in => clk_in,
68
      counter_in => counter_in,
69
70
      clk_out => clk_out,
71
      counter_out => counter_in_resync
72
    );
73
74
75
  ------------------------------------------------------------------------------
76
87
  output : process
77
  begin
78

62193
    wait until rising_edge(clk_out);
79
80
15547
    if counter_out /= counter_in_resync then
81

4320
      data_out <= active_level;
82


17280
      counter_out <= (counter_out + 1);
83
    else
84


93287
      data_out <= not active_level;
85
    end if;
86
  end process;
87
88
89
  ------------------------------------------------------------------------------
90
13
  check_counter_wrapping : process
91
87
    variable counter_in_p1 : unsigned(counter_in'range) := (others => '0');
92
  begin
93

62193
    wait until rising_edge(clk_out);
94
95
15547
    if counter_in = counter_out then
96
7987
      assert counter_in_p1 = counter_in
97
        report "Too many input cycles, outputs will be lost!";
98
    end if;
99
100
31107
    counter_in_p1 := counter_in;
101
  end process;
102
103
end architecture;