tsfpga VHDL coverage


Directory: generated/vunit_out/preprocessed/
File: generated/vunit_out/preprocessed/reg_file/axi_lite_reg_file.vhd
Date: 2021-07-26 04:08:16
Exec Total Coverage
Lines: 64 64 100.0%
Branches: 211 295 71.5%

Line Branch Exec Source
1 258 -- -------------------------------------------------------------------------------------------------
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 -- General register file controlled over AXI-Lite.
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.addr_pkg.all;
17
18 library axi;
19 use axi.axi_pkg.all;
20 use axi.axi_lite_pkg.all;
21
22 use work.reg_file_pkg.all;
23
24
25
31/34
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 2752 times.
✓ Branch 3 taken 43 times.
✓ Branch 4 taken 43 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2795 times.
✓ Branch 8 taken 43 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 43 times.
✓ Branch 11 taken 2752 times.
✓ Branch 12 taken 43 times.
✓ Branch 13 taken 43 times.
✓ Branch 14 taken 344 times.
✓ Branch 15 taken 43 times.
✓ Branch 16 taken 43 times.
✓ Branch 20 taken 2752 times.
✓ Branch 21 taken 43 times.
✓ Branch 23 taken 86 times.
✓ Branch 24 taken 43 times.
✓ Branch 29 taken 86 times.
✓ Branch 30 taken 43 times.
✓ Branch 32 taken 413 times.
✓ Branch 33 taken 43 times.
✓ Branch 34 taken 13216 times.
✓ Branch 35 taken 413 times.
✓ Branch 37 taken 413 times.
✓ Branch 38 taken 43 times.
✓ Branch 39 taken 13216 times.
✓ Branch 40 taken 413 times.
✓ Branch 42 taken 413 times.
✓ Branch 43 taken 43 times.
✓ Branch 45 taken 413 times.
✓ Branch 46 taken 43 times.
79675 entity axi_lite_reg_file is
26 generic (
27 regs : reg_definition_vec_t;
28 default_values : reg_vec_t(regs'range) := (others => (others => '0'))
29 );
30 port (
31 clk : in std_logic;
32 -- Register control bus
33 axi_lite_m2s : in axi_lite_m2s_t;
34 axi_lite_s2m : out axi_lite_s2m_t := (
35 read => (
36 ar => (ready => '1'),
37 r => axi_lite_s2m_r_init),
38 write => (
39 aw => (ready => '1'),
40 w => axi_lite_s2m_w_init,
41 b => axi_lite_s2m_b_init)
42 );
43 -- Register values
44 regs_up : in reg_vec_t(regs'range) := default_values;
45 regs_down : out reg_vec_t(regs'range) := default_values;
46 -- Each bit is pulsed for one cycle when the corresponding register is read/written
47 reg_was_read : out std_logic_vector(regs'range) := (others => '0');
48 reg_was_written : out std_logic_vector(regs'range) := (others => '0')
49 );
50 end entity;
51
52 architecture a of axi_lite_reg_file is
53
54 43 constant addr_and_mask_vec : addr_and_mask_vec_t := to_addr_and_mask_vec(regs);
55
56 13672 signal reg_values : reg_vec_t(regs'range) := default_values;
57
58 43 constant invalid_addr : integer := regs'length;
59 subtype decoded_idx_t is integer range 0 to invalid_addr;
60
61 begin
62
63 59304 regs_down <= reg_values;
64
65
66 ------------------------------------------------------------------------------
67 read_block : block
68 type read_state_t is (ar, r);
69 43 signal read_state : read_state_t := ar;
70 43 signal read_idx : decoded_idx_t := invalid_addr;
71 43 signal valid_read_address : boolean := false;
72 begin
73
74 -- An address transaction has occured and the address points to a valid read register
75
10/14
✓ Branch 0 taken 22679 times.
✓ Branch 1 taken 45246 times.
✓ Branch 2 taken 22636 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 33 times.
✓ Branch 5 taken 43 times.
✓ Branch 6 taken 33 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 33 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 76 times.
✓ Branch 14 taken 21 times.
✓ Branch 15 taken 55 times.
90680 valid_read_address <= read_idx /= invalid_addr and is_read_type(regs(read_idx).reg_type);
76
77 6132 read_process : process
78 begin
79
3/4
✗ Branch 3 not taken.
✓ Branch 4 taken 45246 times.
✓ Branch 6 taken 22636 times.
✓ Branch 7 taken 22610 times.
90561 wait until rising_edge(clk);
80
81
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 22636 times.
✓ Branch 2 taken 190 times.
✓ Branch 3 taken 22446 times.
22636 axi_lite_s2m.read.r.valid <= '0';
82
83
7/8
✓ Branch 1 taken 54501 times.
✓ Branch 2 taken 22636 times.
✓ Branch 3 taken 54501 times.
✓ Branch 4 taken 22636 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 54501 times.
✓ Branch 7 taken 373 times.
✓ Branch 8 taken 54128 times.
131638 reg_was_read <= (others => '0');
84
85
2/2
✓ Branch 0 taken 21198 times.
✓ Branch 1 taken 1438 times.
22636 if valid_read_address then
86
5/6
✓ Branch 0 taken 42396 times.
✓ Branch 1 taken 21198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 42396 times.
✓ Branch 4 taken 21 times.
✓ Branch 5 taken 42375 times.
63594 axi_lite_s2m.read.r.resp <= axi_resp_okay;
87
88
4/6
✓ Branch 0 taken 21198 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 21198 times.
✓ Branch 6 taken 222 times.
✓ Branch 7 taken 20976 times.
21198 if is_fabric_gives_value_type(regs(read_idx).reg_type) then
89
7/10
✓ Branch 0 taken 222 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 222 times.
✓ Branch 5 taken 7104 times.
✓ Branch 6 taken 222 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7104 times.
✓ Branch 9 taken 288 times.
✓ Branch 10 taken 6816 times.
7326 axi_lite_s2m.read.r.data(reg_values(0)'range) <= regs_up(read_idx);
90 else
91
7/10
✓ Branch 0 taken 20976 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20976 times.
✓ Branch 5 taken 671232 times.
✓ Branch 6 taken 20976 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 671232 times.
✓ Branch 9 taken 708 times.
✓ Branch 10 taken 670524 times.
692208 axi_lite_s2m.read.r.data(reg_values(0)'range) <= reg_values(read_idx);
92 end if;
93 else
94
5/6
✓ Branch 0 taken 2876 times.
✓ Branch 1 taken 1438 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2876 times.
✓ Branch 4 taken 31 times.
✓ Branch 5 taken 2845 times.
4314 axi_lite_s2m.read.r.resp <= axi_resp_slverr;
95
7/8
✓ Branch 0 taken 92032 times.
✓ Branch 1 taken 1438 times.
✓ Branch 2 taken 92032 times.
✓ Branch 3 taken 1438 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 92032 times.
✓ Branch 6 taken 1984 times.
✓ Branch 7 taken 90048 times.
185502 axi_lite_s2m.read.r.data <= (others => '-');
96 end if;
97
98
2/3
✓ Branch 0 taken 22256 times.
✓ Branch 1 taken 380 times.
✗ Branch 2 not taken.
22636 case read_state is
99 when ar =>
100
2/2
✓ Branch 2 taken 190 times.
✓ Branch 3 taken 22066 times.
22256 if axi_lite_m2s.read.ar.valid and axi_lite_s2m.read.ar.ready then
101
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 190 times.
✓ Branch 2 taken 190 times.
✗ Branch 3 not taken.
190 axi_lite_s2m.read.ar.ready <= '0';
102
4/6
✗ Branch 1 not taken.
✓ Branch 2 taken 190 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 190 times.
✓ Branch 6 taken 33 times.
✓ Branch 7 taken 157 times.
190 read_idx <= decode(axi_lite_m2s.read.ar.addr, addr_and_mask_vec);
103
104
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 190 times.
✓ Branch 2 taken 190 times.
✗ Branch 3 not taken.
22256 read_state <= r;
105 end if;
106
107 when r =>
108
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 380 times.
✓ Branch 2 taken 190 times.
✓ Branch 3 taken 190 times.
380 axi_lite_s2m.read.r.valid <= '1';
109
2/2
✓ Branch 2 taken 190 times.
✓ Branch 3 taken 190 times.
380 if axi_lite_m2s.read.r.ready and axi_lite_s2m.read.r.valid then
110
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 190 times.
✓ Branch 2 taken 190 times.
✗ Branch 3 not taken.
190 axi_lite_s2m.read.r.valid <= '0';
111
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 190 times.
✓ Branch 2 taken 190 times.
✗ Branch 3 not taken.
190 axi_lite_s2m.read.ar.ready <= '1';
112
113
2/2
✓ Branch 0 taken 188 times.
✓ Branch 1 taken 2 times.
190 if valid_read_address then
114
4/8
✓ Branch 0 taken 188 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 188 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 188 times.
✓ Branch 7 taken 188 times.
✗ Branch 8 not taken.
188 reg_was_read(read_idx) <= '1';
115 end if;
116
117
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 190 times.
✓ Branch 2 taken 190 times.
✗ Branch 3 not taken.
45272 read_state <= ar;
118 end if;
119 end case;
120 end process;
121 end block;
122
123
124 ------------------------------------------------------------------------------
125 write_block : block
126 type write_state_t is (aw, w, b);
127 43 signal write_state : write_state_t := aw;
128 43 signal write_idx : decoded_idx_t := invalid_addr;
129 43 signal valid_write_address : boolean := false;
130 begin
131
132 -- Constrain initial state value to be valid enum. It seems the formal check will allow enums
133 -- to assume invalid (initial) values.
134 -- psl write_state_enum_should_be_valid : assert always
135 -- (write_state = aw or write_state = w or write_state = b) @ rising_edge(clk);
136
137 -- An address transaction has occured and the address points to a valid write register
138
10/14
✓ Branch 0 taken 22679 times.
✓ Branch 1 taken 45246 times.
✓ Branch 2 taken 22636 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 44 times.
✓ Branch 5 taken 43 times.
✓ Branch 6 taken 44 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 44 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 87 times.
✓ Branch 14 taken 19 times.
✓ Branch 15 taken 68 times.
90691 valid_write_address <= write_idx /= invalid_addr and is_write_type(regs(write_idx).reg_type);
139
140 14257 write_process : process
141 begin
142
3/4
✗ Branch 3 not taken.
✓ Branch 4 taken 45246 times.
✓ Branch 6 taken 22636 times.
✓ Branch 7 taken 22610 times.
90561 wait until rising_edge(clk);
143
144
7/8
✓ Branch 1 taken 54501 times.
✓ Branch 2 taken 22636 times.
✓ Branch 3 taken 54501 times.
✓ Branch 4 taken 22636 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 54501 times.
✓ Branch 7 taken 306 times.
✓ Branch 8 taken 54195 times.
131638 reg_was_written <= (others => '0');
145
146
2/2
✓ Branch 0 taken 21473 times.
✓ Branch 1 taken 1163 times.
22636 if valid_write_address then
147
5/6
✓ Branch 0 taken 42946 times.
✓ Branch 1 taken 21473 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 42946 times.
✓ Branch 4 taken 19 times.
✓ Branch 5 taken 42927 times.
64419 axi_lite_s2m.write.b.resp <= axi_resp_okay;
148 else
149
5/6
✓ Branch 0 taken 2326 times.
✓ Branch 1 taken 1163 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2326 times.
✓ Branch 4 taken 31 times.
✓ Branch 5 taken 2295 times.
3489 axi_lite_s2m.write.b.resp <= axi_resp_slverr;
150 end if;
151
152
1/2
✓ Branch 0 taken 22636 times.
✗ Branch 1 not taken.
22636 for list_idx in regs'range loop
153
4/6
✓ Branch 0 taken 54501 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 54501 times.
✓ Branch 6 taken 2344 times.
✓ Branch 7 taken 52157 times.
54501 if is_write_pulse_type(regs(list_idx).reg_type) then
154 -- Set default value zero. If a write occurs to this register, the value
155 -- will be asserted for one cycle below.
156
12/16
✓ Branch 0 taken 2344 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2344 times.
✓ Branch 5 taken 75008 times.
✓ Branch 6 taken 2344 times.
✓ Branch 7 taken 75008 times.
✓ Branch 8 taken 2344 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 75008 times.
✓ Branch 11 taken 166 times.
✓ Branch 12 taken 74842 times.
✓ Branch 14 taken 31865 times.
✓ Branch 15 taken 22636 times.
✓ Branch 16 taken 31865 times.
✗ Branch 17 not taken.
206861 reg_values(list_idx) <= (others => '0');
157 end if;
158 end loop;
159
160
3/4
✓ Branch 0 taken 22402 times.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
22636 case write_state is
161 when aw =>
162
2/2
✓ Branch 2 taken 117 times.
✓ Branch 3 taken 22285 times.
22402 if axi_lite_m2s.write.aw.valid and axi_lite_s2m.write.aw.ready then
163
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
117 axi_lite_s2m.write.aw.ready <= '0';
164
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
117 axi_lite_s2m.write.w.ready <= '1';
165
166
4/6
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 117 times.
✓ Branch 6 taken 44 times.
✓ Branch 7 taken 73 times.
117 write_idx <= decode(axi_lite_m2s.write.aw.addr, addr_and_mask_vec);
167
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
22402 write_state <= w;
168 end if;
169
170 when w =>
171
1/2
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
117 if axi_lite_m2s.write.w.valid and axi_lite_s2m.write.w.ready then
172
2/2
✓ Branch 0 taken 115 times.
✓ Branch 1 taken 2 times.
117 if valid_write_address then
173
7/10
✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 115 times.
✓ Branch 5 taken 3680 times.
✓ Branch 6 taken 115 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3680 times.
✓ Branch 9 taken 810 times.
✓ Branch 10 taken 2870 times.
3795 reg_values(write_idx) <= axi_lite_m2s.write.w.data(reg_values(0)'range);
174
4/8
✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 115 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 115 times.
✓ Branch 7 taken 115 times.
✗ Branch 8 not taken.
115 reg_was_written(write_idx) <= '1';
175 end if;
176
177
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
117 axi_lite_s2m.write.w.ready <= '0';
178
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
117 axi_lite_s2m.write.b.valid <= '1';
179
180
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
117 write_state <= b;
181 end if;
182
183 when b =>
184
1/2
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
117 if axi_lite_m2s.write.b.ready and axi_lite_s2m.write.b.valid then
185
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
117 axi_lite_s2m.write.aw.ready <= '1';
186
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
117 axi_lite_s2m.write.b.valid <= '0';
187
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
45315 write_state <= aw;
188 end if;
189 end case;
190 end process;
191 end block;
192
193
194 ------------------------------------------------------------------------------
195 psl_block : block
196 499 constant reg_was_accessed_zero : std_logic_vector(reg_was_read'range) := (others => '0');
197 begin
198 -- psl default clock is rising_edge(clk);
199 --
200 -- psl reg_was_written_should_pulse_only_one_clock_cycle : assert always
201 -- {reg_was_written /= reg_was_accessed_zero} |=> (reg_was_written = reg_was_accessed_zero);
202 --
203 -- psl reg_was_read_should_pulse_only_one_clock_cycle : assert always
204 -- {reg_was_read /= reg_was_accessed_zero} |=> (reg_was_read = reg_was_accessed_zero);
205 --
206 -- Asserting reg_was_read typically prompts something in the PL that changes the register value.
207 -- Hence it is important that reg_was_read is asserted after the actual read (R) transaction
208 -- has occured, and not e.g. after the AR transaction.
209 -- psl reg_was_read_should_pulse_when_read_transaction_occurs : assert always
210 -- (reg_was_read /= reg_was_accessed_zero) -> prev(axi_lite_m2s.read.r.ready and axi_lite_s2m.read.r.valid);
211 end block;
212
213 end architecture;
214