tsfpga VHDL coverage


Directory: generated/vunit_out/preprocessed/
File: generated/vunit_out/preprocessed/resync/resync_slv_level_coherent.vhd
Date: 2021-07-25 04:08:32
Exec Total Coverage
Lines: 23 23 100.0%
Branches: 46 60 76.7%

Line Branch Exec Source
1 48 -- -------------------------------------------------------------------------------------------------
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 -- Resynchronize a data vector from one clock domain to another. Unlike e.g. resync_slv_level, this
9 -- entity contains a mechanism that guarantees bit coherency. An asynchronous FIFO can also be used
10 -- to achieve this task, but this entity results in a smaller logic footprint.
11 --
12 -- Note that unlike e.g. resync_level, it is safe to drive the input of this entity with LUTs
13 -- as well as FFs.
14 --
15 -- A level signal is rotated around between input and output side, with three registers in each
16 -- direction. The level toggles for each roundtrip, and data is sampled on each side upon a level
17 -- transition.
18 -- This ensures that data is sample on the output side only when we know that the sampled
19 -- input data is stable. Conversely input data is only sampled when we know that data has been
20 -- sampled on the output in a stable fashion.
21 --
22 -- The latency is less than or equal to
23 -- 3 * period(clk_in) + 3 * period(clk_out)
24 --
25 -- This is also the sampling period of the signal. As such this resync is not suitable for signals
26 -- that change quickly. It is instead typically used for e.g. monotonic counters, slow moving status
27 -- words, and other data where the different bits are correlated.
28 --
29 -- The LUT utilization is always 3. The FF utilization increases linearly at a rate of 2 * width.
30 --
31 -- Compared to resync_counter this entity has lower LUT and FF usage in all scenarios. It does
32 -- however have higher latency.
33 --
34 -- Compared to asynchronous_fifo this entity has lower LUT usage. FF usage is lower up to around
35 -- width 32 where this entity will consume more FF. Latency is about the same for both.
36 -- -------------------------------------------------------------------------------------------------
37
38 library ieee;
39 use ieee.std_logic_1164.all;
40
41
42
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 8 times.
✓ Branch 5 taken 44 times.
✓ Branch 6 taken 8 times.
240 entity resync_slv_level_coherent is
43 generic (
44 width : positive;
45 -- Initial value for the ouput that will be set for a few cycles before the first input
46 -- value has propagated.
47 default_value : std_logic_vector(width - 1 downto 0) := (others => '0')
48 );
49 port (
50 clk_in : in std_logic := '0';
51 data_in : in std_logic_vector(default_value'range);
52
53 clk_out : in std_logic;
54 data_out : out std_logic_vector(default_value'range) := default_value
55 );
56 end entity;
57
58 architecture a of resync_slv_level_coherent is
59
60 96 signal data_in_sampled, data_out_int : std_logic_vector(data_in'range) := default_value;
61
62 8 constant level_default_value : std_logic := '0';
63 16 signal input_level, input_level_m1, input_level_m1_not_inverted, output_level, output_level_m1
64 16 : std_logic := level_default_value;
65 16
66 begin
67 16
68 16 ------------------------------------------------------------------------------
69 8 resync_level_to_output_inst : entity work.resync_level
70 generic map (
71 -- Value is driven by a FF so this is not needed
72 enable_input_register => false,
73 default_value => level_default_value
74 )
75 port map (
76 clk_in => clk_in,
77 data_in => input_level,
78 --
79 clk_out => clk_out,
80 data_out => output_level_m1
81 );
82
83
84 ------------------------------------------------------------------------------
85 134 resync_level_to_input_inst : entity work.resync_level
86 generic map (
87 -- Value is driven by a FF so this is not needed
88 enable_input_register => false,
89 default_value => level_default_value
90 )
91 port map (
92 clk_in => clk_out,
93 data_in => output_level,
94 --
95 clk_out => clk_in,
96 data_out => input_level_m1_not_inverted
97 );
98
99 -- Invert here, before the last input level register, so that the output level async_reg is
100 -- driven by an FF and not a LUT.
101
4/5
✓ Branch 0 taken 380 times.
✓ Branch 1 taken 742 times.
✓ Branch 2 taken 431 times.
✓ Branch 3 taken 59 times.
✗ Branch 4 not taken.
1620 input_level_m1 <= not input_level_m1_not_inverted;
102
103
104 ------------------------------------------------------------------------------
105 52 handle_input : process
106 begin
107
3/4
✗ Branch 3 not taken.
✓ Branch 4 taken 742 times.
✓ Branch 6 taken 372 times.
✓ Branch 7 taken 370 times.
1494 wait until rising_edge(clk_in);
108
109
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 322 times.
372 if input_level /= input_level_m1 then
110
7/10
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 50 times.
✓ Branch 6 taken 408 times.
✓ Branch 7 taken 50 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 408 times.
✓ Branch 10 taken 32 times.
✓ Branch 11 taken 376 times.
780 data_in_sampled <= data_in;
111 end if;
112
113
6/8
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 536 times.
✓ Branch 2 taken 270 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 372 times.
✓ Branch 6 taken 50 times.
✓ Branch 7 taken 322 times.
1828 input_level <= input_level_m1;
114 end process;
115
116
117 ------------------------------------------------------------------------------
118 52 handle_output : process
119 begin
120
3/4
✗ Branch 3 not taken.
✓ Branch 4 taken 536 times.
✓ Branch 6 taken 270 times.
✓ Branch 7 taken 266 times.
1084 wait until rising_edge(clk_out);
121
122
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 222 times.
270 if output_level /= output_level_m1 then
123
5/6
✓ Branch 0 taken 390 times.
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 390 times.
✓ Branch 4 taken 32 times.
✓ Branch 5 taken 358 times.
660 data_out_int <= data_in_sampled;
124 end if;
125
126
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 270 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 222 times.
540 output_level <= output_level_m1;
127 end process;
128
129
7/10
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 18 times.
✓ Branch 7 taken 92 times.
✓ Branch 8 taken 18 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 92 times.
✓ Branch 11 taken 32 times.
✓ Branch 12 taken 60 times.
214 data_out <= data_out_int;
130
131 end architecture;
132