tsfpga VHDL coverage


Directory: generated/vunit_out/preprocessed/
File: generated/vunit_out/preprocessed/axi/axi_read_throttle.vhd
Date: 2021-07-25 04:08:32
Exec Total Coverage
Lines: 46 46 100.0%
Branches: 173 220 78.6%

Line Branch Exec Source
1 36 -- -------------------------------------------------------------------------------------------------
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 -- Performs throttling of an AXI bus by limiting the number of outstanding
9 -- transactions.
10 --
11 -- This entity is to be used in conjuction with a data FIFO on the input.r side.
12 -- Using the level from that FIFO, the throttling will make sure that address
13 -- transactions are not made that would result in the FIFO becoming full. This
14 -- avoids stalling on the throttled_s2m.r channel.
15 --
16 -- To achieve this it keeps track of the number of outstanding beats
17 -- that have been negotiated but not yet sent.
18 -- -------------------------------------------------------------------------------------------------
19
20 library ieee;
21 use ieee.numeric_std.all;
22 use ieee.std_logic_1164.all;
23
24 library axi;
25 use axi.axi_pkg.all;
26
27 library common;
28 use common.types_pkg.all;
29
30 library math;
31 6 use math.math_pkg.all;
32
33
34
34/36
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✓ Branch 3 taken 144 times.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 390 times.
✓ Branch 7 taken 12 times.
✓ Branch 8 taken 252 times.
✓ Branch 9 taken 54 times.
✓ Branch 10 taken 12 times.
✓ Branch 12 taken 18 times.
✓ Branch 13 taken 12 times.
✓ Branch 15 taken 12 times.
✓ Branch 16 taken 6 times.
✓ Branch 21 taken 144 times.
✓ Branch 22 taken 6 times.
✓ Branch 24 taken 768 times.
✓ Branch 25 taken 6 times.
✓ Branch 27 taken 12 times.
✓ Branch 28 taken 6 times.
✓ Branch 32 taken 144 times.
✓ Branch 33 taken 6 times.
✓ Branch 35 taken 384 times.
✓ Branch 36 taken 6 times.
✓ Branch 38 taken 48 times.
✓ Branch 39 taken 6 times.
✓ Branch 41 taken 18 times.
✓ Branch 42 taken 6 times.
✓ Branch 44 taken 12 times.
✓ Branch 45 taken 6 times.
✓ Branch 50 taken 144 times.
✓ Branch 51 taken 6 times.
✓ Branch 53 taken 768 times.
✓ Branch 54 taken 6 times.
✓ Branch 56 taken 12 times.
✓ Branch 57 taken 6 times.
18444 entity axi_read_throttle is
35 generic(
36 6 data_fifo_depth : positive;
37 6 max_burst_length_beats : positive;
38 6 id_width : natural;
39
8/10
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✓ Branch 6 taken 252 times.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 6 times.
✓ Branch 11 taken 252 times.
✓ Branch 12 taken 6 times.
✓ Branch 13 taken 252 times.
✓ Branch 14 taken 6 times.
762 addr_width : positive;
40 -- The AR channel is pipelined one step to improve poor timing, mainly on ARVALID.
41 -- If this generic is set to false, the pipelining will be of a simpler model that has lower
42 -- logic footprint, but only allow a transaction every third clock cycle. If it is set to true,
43 -- the pipeline will support a transaction every clock cycle, at the cost of a greater
44 -- logic footprint.
45 full_ar_throughput : boolean
46 );
47 port(
48 clk : in std_logic;
49 --
50 data_fifo_level : in integer range 0 to data_fifo_depth;
51 --
52 input_m2s : in axi_read_m2s_t := axi_read_m2s_init;
53 input_s2m : out axi_read_s2m_t := axi_read_s2m_init;
54 --
55 throttled_m2s : out axi_read_m2s_t := axi_read_m2s_init;
56 throttled_s2m : in axi_read_s2m_t := axi_read_s2m_init
57 );
58 end entity;
59
60 architecture a of axi_read_throttle is
61
62 612 signal pipelined_m2s_ar : axi_m2s_a_t := axi_m2s_a_init;
63 6 signal pipelined_s2m_ar : axi_s2m_a_t := axi_s2m_a_init;
64
65 6 signal address_transaction, data_transaction : std_logic := '0';
66
67 -- The bits of the ARLEN field that shall be taken into account
68 6 constant len_width : positive := num_bits_needed(max_burst_length_beats - 1);
69 subtype len_range is integer range len_width - 1 downto 0;
70
71 -- +1 in range for sign bit
72 82 signal minus_burst_length_beats : signed(len_width + 1 - 1 downto 0) :=
73 (others => '0');
74
75 -- Number of data beats that have been negotiated via address transactions,
76 -- but have not yet been sent by the master. Aka outstanding beats.
77 subtype data_counter_t is integer range 0 to data_fifo_depth;
78 6 signal num_beats_negotiated_but_not_sent : data_counter_t := 0;
79
80 -- Negation of:
81 -- Number of data beat words empty in the FIFO, that are not claimed by oustanding transactions.
82 6 signal minus_num_empty_words_in_fifo_that_have_not_been_negotiated :
83 integer range -data_fifo_depth to 0 := 0;
84
85 begin
86
87 ------------------------------------------------------------------------------
88 pipeline : block
89 6 constant m2s_length : positive := axi_m2s_a_sz(id_width=>id_width, addr_width=>addr_width);
90 1014 signal input_m2s_ar_slv, pipelined_m2s_ar_slv :
91 std_logic_vector(m2s_length - 1 downto 0) := (others => '0');
92 12 signal pipelined_valid : std_logic := '0';
93 begin
94
95 517638 input_m2s_ar_slv <= to_slv(data=>input_m2s.ar, id_width=>id_width, addr_width=>addr_width);
96
97
98 ------------------------------------------------------------------------------
99 24048 handshake_pipeline_inst : entity common.handshake_pipeline
100 generic map (
101 data_width => input_m2s_ar_slv'length,
102 -- Choosable by user, since it affects footprint.
103 full_throughput => full_ar_throughput,
104 -- The goal of this pipeline is to improve timing of the control bits, so this one must
105 -- be false, even though it will increase footprint.
106 allow_poor_input_ready_timing => false
107 )
108 port map (
109 clk => clk,
110 --
111 input_ready => input_s2m.ar.ready,
112 input_valid => input_m2s.ar.valid,
113 input_data => input_m2s_ar_slv,
114 --
115 output_ready => pipelined_s2m_ar.ready,
116 output_valid => pipelined_valid,
117 output_data => pipelined_m2s_ar_slv
118 );
119
120
121 ------------------------------------------------------------------------------
122 864 assign_ar : process(all)
123 begin
124
28/34
✗ Branch 1 not taken.
✓ Branch 2 taken 12018 times.
✓ Branch 3 taken 3000 times.
✓ Branch 4 taken 9018 times.
✓ Branch 6 taken 288432 times.
✓ Branch 7 taken 12018 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 288432 times.
✓ Branch 10 taken 60 times.
✓ Branch 11 taken 288372 times.
✓ Branch 13 taken 769152 times.
✓ Branch 14 taken 12018 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 769152 times.
✓ Branch 17 taken 17025 times.
✓ Branch 18 taken 752127 times.
✓ Branch 20 taken 96144 times.
✓ Branch 21 taken 12018 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 96144 times.
✓ Branch 24 taken 96 times.
✓ Branch 25 taken 96048 times.
✓ Branch 27 taken 36054 times.
✓ Branch 28 taken 12018 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 36054 times.
✓ Branch 31 taken 225 times.
✓ Branch 32 taken 35829 times.
✓ Branch 34 taken 24036 times.
✓ Branch 35 taken 12018 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 24036 times.
✓ Branch 38 taken 213 times.
✓ Branch 39 taken 23823 times.
2451672 pipelined_m2s_ar <= to_axi_m2s_a(
125 data=>pipelined_m2s_ar_slv,
126 id_width=>id_width,
127 addr_width=>addr_width
128 );
129
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12018 times.
✓ Branch 2 taken 6000 times.
✓ Branch 3 taken 6018 times.
24054 pipelined_m2s_ar.valid <= pipelined_valid;
130 end process;
131
132 end block;
133
134
135 -- Two complement inversion: inv(len) = - len - 1 = - (len + 1) = - burst_length_beats
136
13/22
✗ Branch 3 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 18 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 18 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 18 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 18 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 18 times.
✓ Branch 21 taken 18 times.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✓ Branch 24 taken 18 times.
✓ Branch 27 taken 114 times.
✓ Branch 28 taken 18 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 114 times.
✓ Branch 31 taken 102 times.
✓ Branch 32 taken 12 times.
208 minus_burst_length_beats <= not signed('0' & pipelined_m2s_ar.len(len_range));
137
138
139 ------------------------------------------------------------------------------
140 6 assign : process(all)
141 3104 variable block_address_transactions : boolean;
142 begin
143
28/34
✗ Branch 0 not taken.
✓ Branch 1 taken 98087 times.
✓ Branch 2 taken 6000 times.
✓ Branch 3 taken 92087 times.
✓ Branch 5 taken 2354088 times.
✓ Branch 6 taken 98087 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2354088 times.
✓ Branch 9 taken 60 times.
✓ Branch 10 taken 2354028 times.
✓ Branch 12 taken 6277568 times.
✓ Branch 13 taken 98087 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 6277568 times.
✓ Branch 16 taken 17025 times.
✓ Branch 17 taken 6260543 times.
✓ Branch 19 taken 784696 times.
✓ Branch 20 taken 98087 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 784696 times.
✓ Branch 23 taken 96 times.
✓ Branch 24 taken 784600 times.
✓ Branch 26 taken 294261 times.
✓ Branch 27 taken 98087 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 294261 times.
✓ Branch 30 taken 225 times.
✓ Branch 31 taken 294036 times.
✓ Branch 33 taken 196174 times.
✓ Branch 34 taken 98087 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 196174 times.
✓ Branch 37 taken 213 times.
✓ Branch 38 taken 195961 times.
10004874 throttled_m2s.ar <= pipelined_m2s_ar;
144
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 98087 times.
✓ Branch 2 taken 76910 times.
✓ Branch 3 taken 21177 times.
98087 pipelined_s2m_ar <= throttled_s2m.ar;
145
146
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 98087 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 98081 times.
98087 throttled_m2s.r <= input_m2s.r;
147
21/26
✗ Branch 0 not taken.
✓ Branch 1 taken 98087 times.
✓ Branch 2 taken 6000 times.
✓ Branch 3 taken 92087 times.
✓ Branch 5 taken 2354088 times.
✓ Branch 6 taken 98087 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2354088 times.
✓ Branch 9 taken 60 times.
✓ Branch 10 taken 2354028 times.
✓ Branch 12 taken 12555136 times.
✓ Branch 13 taken 98087 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 12555136 times.
✓ Branch 16 taken 48210 times.
✓ Branch 17 taken 12506926 times.
✓ Branch 19 taken 196174 times.
✓ Branch 20 taken 98087 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 196174 times.
✓ Branch 23 taken 24 times.
✓ Branch 24 taken 196150 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 98087 times.
✓ Branch 28 taken 15 times.
✓ Branch 29 taken 98072 times.
15203485 input_s2m.r <= throttled_s2m.r;
148
149 -- The original condition would have been
150 --
151 -- block_address_transactions =
152 -- burst_length_beats >= num_empty_words_in_fifo_that_have_not_been_negotiated
153 --
154 -- where num_empty_words_in_fifo_that_have_not_been_negotiated =
155 -- num_empty_words_in_fifo - num_beats_negotiated_but_not_sent
156 --
157 -- where num_beats_negotiated_but_not_sent was given by accumulating
158 -- to_int(address_transaction) * burst_length_beats - to_int(data_transaction)
159 --
160 -- However this created a very long critical path from ARLEN to ARVALID. The
161 -- bytes_per_beat = ARLEN + 1 term, used in two places was replaced with -inv(ARLEN).
162 -- The minus sign was moved to the right side of the expression, which changed the subtraction
163 -- order. This makes the signals and their ranges a bit harder to understand, but it improves
164 -- the critical path a lot.
165 98087 block_address_transactions :=
166 minus_burst_length_beats <= minus_num_empty_words_in_fifo_that_have_not_been_negotiated;
167
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 98069 times.
98087 if block_address_transactions then
168
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
18 throttled_m2s.ar.valid <= '0';
169
5/8
✓ Branch 0 taken 186491 times.
✓ Branch 1 taken 372966 times.
✓ Branch 2 taken 186485 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 18 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 18 times.
745960 pipelined_s2m_ar.ready <= '0';
170 end if;
171 end process;
172
173
174 ------------------------------------------------------------------------------
175 6 count : process
176 6 variable num_empty_words_in_fifo, num_beats_negotiated_but_not_sent_int
177 : data_counter_t := 0;
178 44 variable ar_term : signed(minus_burst_length_beats'range) := (others => '0');
179 begin
180
3/4
✗ Branch 3 not taken.
✓ Branch 4 taken 372966 times.
✓ Branch 6 taken 186485 times.
✓ Branch 7 taken 186481 times.
745942 wait until rising_edge(clk);
181
182 -- This muxing results in a shorter critical path than doing
183 -- e.g. minus_burst_length_beats * to_int(address_transaction).
184 -- LUT usage stayed the same.
185
2/2
✓ Branch 1 taken 3000 times.
✓ Branch 2 taken 183485 times.
186485 if address_transaction then
186
1/2
✓ Branch 0 taken 3000 times.
✗ Branch 1 not taken.
3000 ar_term := minus_burst_length_beats;
187 else
188
2/2
✓ Branch 0 taken 1285469 times.
✓ Branch 1 taken 183485 times.
1468954 ar_term := (others => '0');
189 end if;
190
191
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 186485 times.
186485 num_beats_negotiated_but_not_sent_int := num_beats_negotiated_but_not_sent
192 - to_integer(ar_term)
193 - to_int(data_transaction);
194
195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 186485 times.
186485 num_empty_words_in_fifo := data_fifo_depth - data_fifo_level;
196
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 186485 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 186485 times.
✓ Branch 5 taken 12003 times.
✓ Branch 6 taken 174482 times.
186485 minus_num_empty_words_in_fifo_that_have_not_been_negotiated <=
197 num_beats_negotiated_but_not_sent_int - num_empty_words_in_fifo;
198
199
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 186485 times.
✓ Branch 2 taken 6000 times.
✓ Branch 3 taken 180485 times.
372970 num_beats_negotiated_but_not_sent <= num_beats_negotiated_but_not_sent_int;
200 end process;
201
202
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 82910 times.
✓ Branch 3 taken 6000 times.
✓ Branch 4 taken 76910 times.
82916 address_transaction <= throttled_m2s.ar.valid and throttled_s2m.ar.ready;
203
3/4
✗ Branch 2 not taken.
✓ Branch 3 taken 6012 times.
✓ Branch 4 taken 6000 times.
✓ Branch 5 taken 12 times.
6024 data_transaction <= throttled_m2s.r.ready and throttled_s2m.r.valid;
204
205 end architecture;
206