GCC Code Coverage Report
Directory: generated/vunit_out/preprocessed/ Exec Total Coverage
File: generated/vunit_out/preprocessed/resync/resync_pulse.vhd Lines: 20 20 100.0 %
Date: 2021-06-12 04:12:08 Branches: 15 20 75.0 %

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
-- A robust way of resyncing a pulse signal from one clock domain to another.
9
--
10
-- This modules features a feedback input gating which makes it robust in all configurations.
11
-- Without input gating, if multiple pulses arrive close to each other, pulse overload will occur and
12
-- some or even all of them can be missed and not arrive on the output.
13
-- With input gating, if multiple pulses arrive one and only one will arrive on the output.
14
--
15
-- Note that unlike e.g. resync_level, it is safe to drive the input of this entity with LUTs
16
-- as well as FFs.
17
-- -------------------------------------------------------------------------------------------------
18
19
library ieee;
20
use ieee.std_logic_1164.all;
21
22
library common;
23
use common.types_pkg.all;
24
25
26

55844
entity resync_pulse is
27
  generic (
28
    assert_false_on_pulse_overload : boolean := true
29
  );
30
  port (
31
    clk_in : in std_logic;
32
    pulse_in : in std_logic;
33
34
    clk_out : in std_logic;
35
    pulse_out : out std_logic := '0'
36
  );
37
end entity;
38
39
architecture a of resync_pulse is
40
26
  signal level_in, level_out, level_out_p1, level_out_feedback : std_logic := '0';
41
begin
42
43
  ------------------------------------------------------------------------------
44
13
  input : process
45
  begin
46
55740
    wait until rising_edge(clk_in);
47
48
13934
    if pulse_in = '1' then
49
901
      if level_in = level_out_feedback then
50
601
        level_in <= not level_in;
51
300
      elsif assert_false_on_pulse_overload then
52
27881
        assert false report "Pulse overload";
53
      end if;
54
    end if;
55
  end process;
56
57
58
  ------------------------------------------------------------------------------
59
13
  level_in_resync_inst : entity work.resync_level
60
    generic map (
61
      -- Value is drive by a FF so this is not needed
62
      enable_input_register => false
63
    )
64
26
    port map (
65
26
      clk_in => clk_in,
66
      data_in => level_in,
67
26
68

147885
      clk_out => clk_out,
69
      data_out => level_out
70
    );
71
72
73
  ------------------------------------------------------------------------------
74
13
  level_out_resync_inst : entity work.resync_level
75
    generic map (
76
      -- Value is drive by a FF so this is not needed
77
      enable_input_register => false
78
    )
79
    port map (
80
      clk_in => clk_out,
81
      data_in => level_out,
82
83
      clk_out => clk_in,
84
      data_out => level_out_feedback
85
    );
86
87
88
  ------------------------------------------------------------------------------
89
13
  output : process
90
  begin
91

147846
    wait until rising_edge(clk_out);
92

36958
    pulse_out <= to_sl(level_out /= level_out_p1);
93

73929
    level_out_p1 <= level_out;
94
  end process;
95
96
end architecture;