tsfpga VHDL coverage


Directory: generated/vunit_out/preprocessed/
File: generated/vunit_out/preprocessed/fifo/fifo.vhd
Date: 2021-07-26 04:08:16
Exec Total Coverage
Lines: 53 53 100.0%
Branches: 185 261 70.9%

Line Branch Exec Source
1 168 -- -------------------------------------------------------------------------------------------------
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 -- Synchronous FIFO.
9 -- -------------------------------------------------------------------------------------------------
10
11 library ieee;
12 use ieee.std_logic_1164.all;
13 use ieee.numeric_std.all;
14
15 library common;
16 use common.attribute_pkg.all;
17 use common.types_pkg.all;
18
19 library math;
20 use math.math_pkg.all;
21
22
23
10/12
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 581 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 17 times.
✓ Branch 7 taken 11 times.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 25 times.
✓ Branch 11 taken 553 times.
✓ Branch 12 taken 46 times.
✓ Branch 13 taken 10 times.
2464 entity fifo is
24 generic (
25 width : positive;
26 depth : positive;
27 -- Changing these levels from default value will increase logic footprint
28 almost_full_level : integer range 0 to depth := depth;
29 almost_empty_level : integer range 0 to depth := 0;
30 -- Set to true in order to use read_last and write_last
31 enable_last : boolean := false;
32 -- If enabled, read_valid will not be asserted until a full packet is available in
33 -- FIFO. I.e. when write_last has been received. Must set enable_last as well to use this.
34 enable_packet_mode : boolean := false;
35 -- Set to true in order to use the drop_packet port. Must set enable_packet_mode as
36 -- well to use this.
37 enable_drop_packet : boolean := false;
38 ram_type : ram_style_t := ram_style_auto
39 );
40 port (
41 clk : in std_logic;
42 -- When packet_mode is enabled, this value will still reflect the number of words that are in
43 -- the FIFO RAM. This is not necessarily the same as the number of words that can be read, in
44 -- this mode.
45 level : out integer range 0 to depth := 0;
46
47 read_ready : in std_logic;
48 -- '1' if FIFO is not empty
49 read_valid : out std_logic := '0';
50 read_data : out std_logic_vector(width - 1 downto 0) := (others => '0');
51 -- Must set enable_last generic in order to use this
52 read_last : out std_logic := '0';
53 -- '1' if there are almost_empty_level or fewer words available to read
54 almost_empty : out std_logic := '1';
55
56 -- '1' if FIFO is not full
57 write_ready : out std_logic := '1';
58 write_valid : in std_logic;
59 write_data : in std_logic_vector(width - 1 downto 0);
60 -- Must set enable_last generic in order to use this
61 write_last : in std_logic := '-';
62 -- '1' if there are almost_full_level or more words available in the FIFO
63 almost_full : out std_logic := '0';
64 -- Drop the current packet (all words that have been writen since the previous write_last).
65 -- Must set enable_drop_packet generic in order to use this.
66 drop_packet : in std_logic := '0'
67 );
68 end entity;
69
70 28 architecture a of fifo is
71
72 -- Need one extra bit in the addresses to be able to make the distinction if the FIFO
73 -- is full or empty (where the addresses would otherwise be equal).
74 subtype fifo_addr_t is unsigned(num_bits_needed(2 * depth - 1) - 1 downto 0);
75 712 signal read_addr_next, read_addr : fifo_addr_t := (others => '0');
76 1396 signal write_addr_next, write_addr, write_addr_next_if_not_drop, write_addr_start_of_packet :
77 fifo_addr_t := (others => '0');
78
79 -- The part of the address that actually goes to the BRAM address port
80 subtype bram_addr_range is integer range num_bits_needed(depth - 1) - 1 downto 0;
81
82 28 signal num_lasts_in_fifo : integer range 0 to depth := 0;
83
84 28 signal should_drop_packet : std_logic := '0';
85
86 begin
87
88 84 assert is_power_of_two(depth) report "Depth must be a power of two" severity failure;
89
90
3/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
56 assert enable_last or (not enable_packet_mode)
91 report "Must set enable_last for packet mode" severity failure;
92
3/4
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
56 assert enable_packet_mode or (not enable_drop_packet)
93 report "Must set enable_packet_mode for drop packet support" severity failure;
94
95 -- The flags will update one cycle after the write/read that puts them over/below the line.
96 -- Except for almost_empty when almost_empty_level is zero.
97 -- In that case, when a write puts it over the line there will be a two cycle latency, since
98 -- that write must propagate into the RAM before the data is valid to read.
99 -- For a read that puts it below the line there is always one cycle latency.
100
101 assign_almost_full : if almost_full_level = depth generate
102
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 14 times.
58 almost_full <= not write_ready;
103 else generate
104
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 26875 times.
✓ Branch 3 taken 13 times.
✓ Branch 4 taken 26862 times.
26931 almost_full <= to_sl(level > almost_full_level - 1);
105 end generate;
106
107 assign_almost_empty : if almost_empty_level = 0 generate
108
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 27979 times.
✓ Branch 3 taken 27954 times.
✓ Branch 4 taken 25 times.
28032 almost_empty <= not read_valid;
109 else generate
110
6/8
✓ Branch 0 taken 375180 times.
✓ Branch 1 taken 750278 times.
✓ Branch 2 taken 375152 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 54 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 51 times.
1500670 almost_empty <= to_sl(level < almost_empty_level + 1);
111 end generate;
112
113
114 ------------------------------------------------------------------------------
115 28 status : process
116 541 variable num_lasts_in_fifo_next : integer range 0 to depth := 0;
117 begin
118
3/4
✗ Branch 3 not taken.
✓ Branch 4 taken 750278 times.
✓ Branch 6 taken 375152 times.
✓ Branch 7 taken 375126 times.
1500610 wait until rising_edge(clk);
119
120
2/2
✓ Branch 0 taken 5485 times.
✓ Branch 1 taken 369667 times.
375152 if enable_packet_mode then
121
1/2
✗ Branch 8 not taken.
✓ Branch 9 taken 5485 times.
5485 num_lasts_in_fifo_next := num_lasts_in_fifo
122 + to_int(write_ready and write_valid and write_last and not should_drop_packet)
123 - to_int(read_ready and read_valid and read_last);
124
125 -- We look at num_lasts_in_fifo_next since we need to update read_valid the same cycle when
126 -- the read happens.
127 -- We also look at num_lasts_in_fifo since a write needs an additional clock
128 -- cycle to propagate into the RAM. This is really only needed when the FIFO is empty and
129 -- a packet of length one is written. With this condition, there will be a two cycle latency
130 -- from write_last being written to read_valid being asserted.
131
4/6
✓ Branch 0 taken 5008 times.
✓ Branch 1 taken 477 times.
✓ Branch 3 taken 5485 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 5485 times.
✗ Branch 6 not taken.
5485 read_valid <= to_sl(num_lasts_in_fifo /= 0 and num_lasts_in_fifo_next /= 0);
132
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 5485 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5485 times.
✓ Branch 5 taken 2146 times.
✓ Branch 6 taken 3339 times.
5485 num_lasts_in_fifo <= num_lasts_in_fifo_next;
133 else
134
4/4
✓ Branch 2 taken 54199 times.
✓ Branch 3 taken 315468 times.
✓ Branch 4 taken 64201 times.
✓ Branch 5 taken 305466 times.
369667 read_valid <= to_sl(read_addr_next /= write_addr);
135 end if;
136
137 -- Note that write_ready looks at the write_addr_next that will be used if there is
138 -- no packet drop, even when drop_packet functionality is enabled. This is done to ease the
139 -- timing of write_ready which is often critical.
140 -- There is a functional difference only in the special case when the FIFO
141 -- goes full in the same cycle as drop_packet is sent. In that case, write_ready will be low
142 -- for one cycle and then go high the next.
143 --
144 -- Similarly write_ready looks at read_addr rather than read_addr_next, which eases the timing
145 -- of read_ready. There is a function difference when the FIFO is full and a read performed
146 -- makes the FIFO ready for another write. In this case, write_ready will be low
147 -- for one extra cycle after the read occurs, and then go high the next.
148
16/26
✗ Branch 2 not taken.
✓ Branch 3 taken 375152 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 375152 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 375152 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 375152 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 375152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 375152 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 375152 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 375152 times.
✓ Branch 25 taken 316507 times.
✓ Branch 26 taken 58645 times.
✓ Branch 27 taken 316507 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 316507 times.
✗ Branch 30 not taken.
✓ Branch 32 taken 59684 times.
✓ Branch 33 taken 315468 times.
✓ Branch 34 taken 59684 times.
✓ Branch 35 taken 315468 times.
375152 write_ready <= to_sl(
149 read_addr(bram_addr_range) /= write_addr_next_if_not_drop(bram_addr_range)
150 or read_addr(read_addr'high) = write_addr_next_if_not_drop(write_addr_next'high));
151
152
2/2
✓ Branch 0 taken 1107 times.
✓ Branch 1 taken 374045 times.
375152 if enable_drop_packet then
153
2/2
✓ Branch 5 taken 1103 times.
✓ Branch 6 taken 4 times.
1107 if write_ready and write_valid and write_last and not should_drop_packet then
154
5/6
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 22 times.
375182 write_addr_start_of_packet <= write_addr_next;
155 end if;
156 end if;
157
158 -- These signals however must have the updated values to be valid for the next cycle.
159
5/6
✓ Branch 0 taken 2036459 times.
✓ Branch 1 taken 375152 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2036459 times.
✓ Branch 4 taken 52689 times.
✓ Branch 5 taken 1983770 times.
2411611 write_addr <= write_addr_next;
160
5/6
✓ Branch 0 taken 2036459 times.
✓ Branch 1 taken 375152 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2036459 times.
✓ Branch 4 taken 52018 times.
✓ Branch 5 taken 1984441 times.
2411611 read_addr <= read_addr_next;
161 -- The level count shall always be correct, and hence uses the updated values. Note that this
162 -- can create some wonky situations, e.g. when level read as 1023 for a 1024 deep FIFO
163 -- but write_ready is false.
164 -- Also in packet_mode, the level is incremented for words that might be dropped later.
165
4/6
✗ Branch 3 not taken.
✓ Branch 4 taken 375152 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 375152 times.
✓ Branch 8 taken 36914 times.
✓ Branch 9 taken 338238 times.
750304 level <= to_integer(write_addr_next - read_addr_next) mod (2 * depth);
166 end process;
167
168
3/4
✗ Branch 2 not taken.
✓ Branch 3 taken 33 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 28 times.
61 should_drop_packet <= to_sl(enable_drop_packet) and drop_packet;
169
170
8/12
✗ Branch 3 not taken.
✓ Branch 4 taken 50153 times.
✓ Branch 7 taken 50153 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 50153 times.
✓ Branch 13 taken 355685 times.
✓ Branch 14 taken 50153 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 355685 times.
✓ Branch 17 taken 52691 times.
✓ Branch 18 taken 302994 times.
406208 write_addr_next_if_not_drop <= write_addr + to_int(write_ready and write_valid);
171
10/12
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 25 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 20 times.
✓ Branch 7 taken 192912 times.
✓ Branch 8 taken 26870 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 192912 times.
✓ Branch 11 taken 52684 times.
✓ Branch 12 taken 140228 times.
220352 write_addr_next <=
172
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 26870 times.
26874 write_addr_start_of_packet when should_drop_packet else write_addr_next_if_not_drop;
173
8/17
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 116919 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 116919 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 116919 times.
✓ Branch 13 taken 721378 times.
✓ Branch 14 taken 116919 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 721378 times.
✓ Branch 17 taken 52018 times.
✓ Branch 18 taken 669360 times.
915549 read_addr_next <= read_addr + to_int(read_ready and read_valid);
174
175
176 ------------------------------------------------------------------------------
177 memory_block : block
178 28 constant memory_word_width : integer := width + to_int(enable_last);
179 subtype word_t is std_logic_vector(memory_word_width - 1 downto 0);
180 type mem_t is array (integer range <>) of word_t;
181
182 69244 signal mem : mem_t(0 to depth - 1) := (others => (others => '0'));
183 attribute ram_style of mem : signal is to_attribute(ram_type);
184
185 2276 signal memory_read_data, memory_write_data : word_t := (others => '0');
186 begin
187
188
12/18
✗ Branch 2 not taken.
✓ Branch 3 taken 38385 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 38385 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 38385 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 38385 times.
✓ Branch 12 taken 38385 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 38385 times.
✓ Branch 18 taken 597450 times.
✓ Branch 19 taken 38385 times.
✓ Branch 20 taken 242984 times.
✓ Branch 21 taken 354466 times.
✓ Branch 22 taken 318458 times.
✓ Branch 23 taken 278992 times.
1308706 read_data <= memory_read_data(read_data'range);
189
11/18
✗ Branch 2 not taken.
✓ Branch 3 taken 35902 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 35902 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 35902 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 35902 times.
✓ Branch 12 taken 35902 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 35902 times.
✓ Branch 18 taken 433181 times.
✓ Branch 19 taken 35902 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 433181 times.
✓ Branch 22 taken 245270 times.
✓ Branch 23 taken 187911 times.
470217 memory_write_data(write_data'range) <= write_data;
190
191 assign_data : if enable_last generate
192
3/6
✓ Branch 0 taken 43 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 43 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 43 times.
✗ Branch 5 not taken.
80 read_last <= memory_read_data(memory_read_data'high);
193
7/10
✓ Branch 0 taken 375180 times.
✓ Branch 1 taken 750278 times.
✓ Branch 2 taken 375152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2163 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2163 times.
✓ Branch 8 taken 2154 times.
✓ Branch 9 taken 9 times.
1502782 memory_write_data(memory_write_data'high) <= write_last;
194 end generate;
195
196 35198 memory : process
197 begin
198
3/4
✗ Branch 3 not taken.
✓ Branch 4 taken 750278 times.
✓ Branch 6 taken 375152 times.
✓ Branch 7 taken 375126 times.
1500610 wait until rising_edge(clk);
199
200
6/8
✗ Branch 1 not taken.
✓ Branch 2 taken 375152 times.
✓ Branch 4 taken 12119034 times.
✓ Branch 5 taken 375152 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 12119034 times.
✓ Branch 8 taken 197547 times.
✓ Branch 9 taken 11921487 times.
12494186 memory_read_data <= mem(to_integer(read_addr_next) mod depth);
201
202
2/2
✓ Branch 2 taken 26837 times.
✓ Branch 3 taken 348315 times.
375152 if write_ready and write_valid then
203
6/8
✗ Branch 1 not taken.
✓ Branch 2 taken 26837 times.
✓ Branch 4 taken 370507 times.
✓ Branch 5 taken 26837 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 370507 times.
✓ Branch 8 taken 123877 times.
✓ Branch 9 taken 246630 times.
1120811 mem(to_integer(write_addr) mod depth) <= memory_write_data;
204 end if;
205 end process;
206 end block;
207
208
209 ------------------------------------------------------------------------------
210 psl_block : block
211 28 signal first_cycle : std_logic := '1';
212 199 signal fill_level : unsigned(read_addr'range);
213 begin
214
215
10/14
✓ Branch 0 taken 375180 times.
✓ Branch 1 taken 750278 times.
✓ Branch 2 taken 375152 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 45154 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 45154 times.
✓ Branch 12 taken 321021 times.
✓ Branch 13 taken 45154 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 321021 times.
✓ Branch 16 taken 100204 times.
✓ Branch 17 taken 220817 times.
1867326 fill_level <= write_addr - read_addr;
216
217 28 ctrl : process
218 begin
219
3/4
✗ Branch 3 not taken.
✓ Branch 4 taken 750278 times.
✓ Branch 6 taken 375152 times.
✓ Branch 7 taken 375126 times.
1500610 wait until rising_edge(clk);
220
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 375152 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 375124 times.
750332 first_cycle <= '0';
221 end process;
222
223 -- psl default clock is rising_edge(clk);
224 --
225 -- psl level_port_same_as_fill_level : assert always
226 -- level = fill_level;
227 --
228 -- Constrains start state of read_addr and write_addr to be valid.
229 -- psl level_within_range : assert always
230 -- fill_level <= depth;
231 --
232 -- To constrain start state. Otherwise read_valid can start as one, and a read
233 -- transaction occur, despite FIFO being empty.
234 -- psl not_read_valid_unless_data_in_fifo : assert always
235 -- not (read_valid = '1' and level = 0);
236 --
237 -- psl write_ready_false_if_full : assert always
238 -- level = depth -> not write_ready;
239 --
240 -- Latency since data must propagate through BRAM.
241 -- psl read_valid_goes_high_two_cycles_after_write : assert always
242 -- (write_valid and write_ready) -> next[2] (read_valid);
243 --
244 -- psl read_valid_stays_high_until_read_ready : assert always
245 -- (read_valid) -> (read_valid) until (read_ready);
246 --
247 -- psl read_data_should_be_stable_until_handshake_transaction : assert always
248 -- (not first_cycle) and prev(read_valid and not read_ready) -> stable(read_data);
249 --
250 -- psl read_last_should_be_stable_until_handshake_transaction : assert always
251 -- (not first_cycle) and prev(read_valid and not read_ready) -> stable(read_last);
252 --
253 -- psl read_valid_may_fall_only_after_handshake_transaction : assert always
254 -- first_cycle = '0' and fell(read_valid) -> prev(read_ready);
255 --
256 -- psl level_should_stay_the_same_if_there_is_both_read_and_write : assert always
257 -- {level = 2 and (read_ready and read_valid and write_ready and write_valid) = '1'}
258 -- |=> level = 2;
259 --
260 -- psl level_should_decrease_cycle_after_read_if_there_is_no_write : assert always
261 -- {level = 2 and (read_ready and read_valid and not write_valid) = '1'} |=> level = 1;
262 --
263 -- psl level_should_increase_cycle_after_write_if_there_is_no_read : assert always
264 -- {level = 2 and (write_ready and write_valid and not read_ready) = '1'} |=> level = 3;
265
266 -- The formal verification flow doesn't handle generics very well, so the
267 -- check below is only done if the depth is 4.
268 gen_if_depth_4 : if depth = 4 generate
269 56 begin
270 -- Check that write_ready is deasserted after 4 consecutive writes
271 -- without reads.
272 -- psl assert always
273 -- {(write_valid and not read_ready)}[*4] |=> (not write_ready);
274 end generate;
275 end block;
276
277 end architecture;
278