tsfpga VHDL coverage


Directory: generated/vunit_out/preprocessed/
File: generated/vunit_out/preprocessed/resync/resync_level.vhd
Date: 2021-07-26 04:08:16
Exec Total Coverage
Lines: 13 13 100.0%
Branches: 29 40 72.5%

Line Branch Exec Source
1 894 -- -------------------------------------------------------------------------------------------------
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 -- Resync a single bit from one clock domain to another.
9 --
10 -- The two registers will be placed in the same slice, in order to minimize
11 -- MTBF. This guarantees proper resynchronization of semi static "level" type
12 -- signals without meta stability on rising/falling edges. It can not handle
13 -- "pulse" type signals. Pulses can be missed and single-cycle pulse behaviour
14 -- will not work.
15 --
16 -- The clk_in port does not necessarily have to be set. But if you want to have
17 -- a deterministic latency through the resync block (via a set_max_delay
18 -- constraint) it has to be set. If not, a simple set_false_path constraint will
19 -- be used and the latency can be arbitrary, depending on the placer/router.
20 --
21 -- There is an option to include a register on the input side before the async_reg flip-flop chain.
22 -- This option is to prevent sampling of data when the input is in a transient "glitch" state, which
23 -- can occur if it is driven by a LUT as opposed to a flip-flop. If the input is already driven by
24 -- a flip-flop, you can safely set the generic to 'false' in order to save resources.
25 -- Note that this is a separate issue from meta-stability.
26 -- When this option is enabled, the 'clk_in' port must be driven with the correct clock.
27 --
28 -- Some motivation why this is needed:
29 -- While LUTs are designed to be glitch-free in order to save switching power, this can only be
30 -- achieved as long as only one LUT input value changes state. (See e.g. this thread:
31 -- https://forums.xilinx.com/t5/Other-FPGA-Architecture/Interior-switching-of-LUT5-SRAM/td-p/835012)
32 -- When more than one input changes state per clock cycle, glitches will almost ceratinly appear on
33 -- the LUT output before reaching its steady state.
34 -- This is partly due to difference in propagation delay between the inputs, and partly due to
35 -- the electrical structure of a LUT. In a regular synchronous design, the Vivado timing engine
36 -- guarantees that all these glitches have been resolved and LUT output has reached its
37 -- steady state before the value is sampled by a FF. When the value is fed to our async_reg FF
38 -- chain however there is no control over this, and we may very well sample an erroneous
39 -- glitch value.
40 -- So given this knowledge the rule of thumb is to always drive resync_level input by a FF.
41 -- However since LUTs are glitch-free in some scenarios, exceptions can be made if we are sure
42 -- of what we are doing. For example if the value is inverted in a LUT before being fed to
43 -- resync_level, then that is a scenario where we do not actually need the extra FF.
44 -- -------------------------------------------------------------------------------------------------
45
46 library ieee;
47 use ieee.std_logic_1164.all;
48
49 library common;
50 use common.attribute_pkg.all;
51
52
53
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 149 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 134 times.
76014 entity resync_level is
54 generic (
55 -- Enable or disable a register on the input side before the async_reg flip-flip chain.
56 -- Must be used if the input can contain glitches. See header for more details.
57 -- The 'clk_in' port must be assigned if this generic is set to 'true'.
58 enable_input_register : boolean;
59 -- Initial value for the ouput that will be set for a few cycles before the first input
60 -- value has propagated.
61 default_value : std_logic := '0'
62 );
63 port (
64 clk_in : in std_logic := '-';
65 data_in : in std_logic;
66
67 clk_out : in std_logic;
68 data_out : out std_logic
69 );
70 end entity;
71
72 architecture a of resync_level is
73 149 signal data_in_int, data_in_p1, data_out_int : std_logic := default_value;
74
75 attribute async_reg of data_in_p1 : signal is "true";
76 attribute async_reg of data_out_int : signal is "true";
77 begin
78
79 -- This check will trigger in simulation, but will probably not work in synthesis
80 76494 assert clk_in /= '-' or not enable_input_register
81 report "Must assign clock when using input register"
82 severity failure;
83
84
5/8
✓ Branch 0 taken 2493 times.
✓ Branch 1 taken 4854 times.
✓ Branch 2 taken 2443 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1523 times.
✓ Branch 6 taken 1523 times.
✗ Branch 7 not taken.
11462 data_out <= data_out_int;
85
86
87 ------------------------------------------------------------------------------
88 assign_input : if enable_input_register generate
89
90 ------------------------------------------------------------------------------
91 199 input_register : process
92 begin
93
3/4
✗ Branch 3 not taken.
✓ Branch 4 taken 4854 times.
✓ Branch 6 taken 2443 times.
✓ Branch 7 taken 2411 times.
9790 wait until rising_edge(clk_in);
94
95
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2443 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 2401 times.
4886 data_in_int <= data_in;
96 end process;
97
98 else generate
99
100
6/8
✓ Branch 0 taken 43069 times.
✓ Branch 1 taken 85738 times.
✓ Branch 2 taken 42920 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1509 times.
✓ Branch 6 taken 1422 times.
✓ Branch 7 taken 87 times.
173583 data_in_int <= data_in;
101
102 end generate;
103
104
105 ------------------------------------------------------------------------------
106 149 main : process
107 begin
108
3/4
✗ Branch 3 not taken.
✓ Branch 4 taken 85738 times.
✓ Branch 6 taken 42920 times.
✓ Branch 7 taken 42818 times.
171727 wait until rising_edge(clk_out);
109
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 42920 times.
✓ Branch 2 taken 1375 times.
✓ Branch 3 taken 41545 times.
42920 data_out_int <= data_in_p1;
110
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 42920 times.
✓ Branch 3 taken 1377 times.
✓ Branch 4 taken 41543 times.
85989 data_in_p1 <= data_in_int;
111 end process;
112
113 end architecture;
114