GCC Code Coverage Report
Directory: generated/vunit_out/preprocessed/ Exec Total Coverage
File: generated/vunit_out/preprocessed/axi/tb_axi_simple_crossbar.vhd Lines: 81 81 100.0 %
Date: 2021-06-12 04:12:08 Branches: 449 551 81.5 %

Line Branch Exec Source
1
24
-- -------------------------------------------------------------------------------------------------
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
9
library ieee;
10
use ieee.std_logic_1164.all;
11
use ieee.numeric_std.all;
12
13
library vunit_lib;
14
context vunit_lib.vunit_context;
15
context vunit_lib.vc_context;
16
17
library osvvm;
18
use osvvm.RandomPkg.all;
19
20
library axi;
21
use axi.axi_pkg.all;
22
use axi.axi_lite_pkg.all;
23
24
library bfm;
25
26
27





























323330
entity tb_axi_simple_crossbar is
28
  generic(
29








1140
    runner_cfg : string;
30
    test_axi_lite : boolean
31










4832
  );
32










3140
end entity;
33
162
34








8624
architecture tb of tb_axi_simple_crossbar is
35
562
36
  constant num_inputs : integer := 4;
37
6
  constant clk_period : time := 5 ns;
38
478
39








1458
  signal clk : std_logic := '0';
40
2490
41









2714
  constant axi_port_data_width : integer := 32;
42











954
  type bus_master_vec_t is array (integer range <>) of bus_master_t;
43

330
  constant input_masters : bus_master_vec_t(0 to 4 - 1) := (
44








1078
    0 => new_bus(data_length => axi_port_data_width, address_length => axi_a_addr_sz),
45

58
    1 => new_bus(data_length => axi_port_data_width, address_length => axi_a_addr_sz),
46
    2 => new_bus(data_length => axi_port_data_width, address_length => axi_a_addr_sz),
47
    3 => new_bus(data_length => axi_port_data_width, address_length => axi_a_addr_sz)
48
  );
49
50
4
  constant memory : memory_t := new_memory;
51
4
  constant axi_read_slave, axi_write_slave : axi_slave_t := new_axi_slave(
52
    memory => memory,
53
    address_fifo_depth => 8,
54
    write_response_fifo_depth => 8,
55
    address_stall_probability => 0.3,
56
    data_stall_probability => 0.3,
57
    write_response_stall_probability => 0.3,
58
    min_response_latency => 12 * clk_period,
59
    max_response_latency => 20 * clk_period,
60
    logger => get_logger("axi_rd_slave")
61
  );
62
63
begin
64
65

321674
  clk <= not clk after clk_period / 2;
66











48086
  test_runner_watchdog(runner, 1 ms);
67
68
69
  ------------------------------------------------------------------------------
70
4
  main : process
71
4
    constant num_words : integer := 1000;
72
4
    constant bytes_per_word : integer := axi_port_data_width / 8;
73
260
    variable got, expected : std_logic_vector(axi_port_data_width - 1 downto 0);
74
4
    variable address : integer;
75
4
    variable buf : buffer_t;
76
4
    variable rnd : RandomPType;
77
78
4
    variable input_select : integer;
79
4
    variable bus_reference : bus_reference_t;
80
81
36
    variable bus_reference_queue : queue_t := new_queue;
82
  begin
83
12
    test_runner_setup(runner, runner_cfg);
84
8
    rnd.InitSeed(rnd'instance_name);
85
86
4
    buf := allocate(memory, num_words * bytes_per_word);
87
88
4
    if run("read_random_data_from_random_input_master") then
89
      -- Set random data in read memory
90
2
      for idx in 0 to num_words - 1 loop
91
2000
        address := idx * bytes_per_word;
92
2000
        expected := rnd.RandSlv(expected'length);
93

8000
        write_word(memory, address, expected);
94
      end loop;
95
96
      -- Queue up reads from random input master
97
2
      for idx in 0 to num_words - 1 loop
98
2000
        input_select := rnd.RandInt(0, input_masters'high);
99

4002
        read_bus(net, input_masters(input_select), address, bus_reference);
100

8000
        push(bus_reference_queue, bus_reference);
101
      end loop;
102
103
      -- Verify read data
104
2
      for idx in 0 to num_words - 1 loop
105

2000
        expected := read_word(memory, address, bytes_per_word);
106
2000
        bus_reference := pop(bus_reference_queue);
107
8000
        await_read_bus_reply(net, bus_reference, got);
108


8000
        check_equal(got, expected, "idx=" & to_string(idx), line_num => 108, file_name => "tb_axi_simple_crossbar.vhd");
109
      end loop;
110
111
2
      assert is_empty(bus_reference_queue);
112
113

6
    elsif run("write_random_data_from_random_input_master") then
114
      -- Set expected random data and queue up write
115
2
      for idx in 0 to num_words - 1 loop
116
2000
        address := idx * bytes_per_word;
117
2000
        expected := rnd.RandSlv(expected'length);
118

4000
        set_expected_word(memory, address, expected);
119
120
2000
        input_select := rnd.RandInt(0, input_masters'high);
121


8002
        write_bus(net, input_masters(input_select), address, expected);
122
      end loop;
123
124
      -- Wait until all writes are completed
125
2
      wait for 300 us;
126
6
      check_expected_was_written(memory);
127
    end if;
128
129
44048
    test_runner_cleanup(runner);
130
  end process;
131
132
133
  ------------------------------------------------------------------------------
134
  bfm_generate : if test_axi_lite generate
135
530
    signal inputs_read_m2s : axi_lite_read_m2s_vec_t(0 to num_inputs - 1) := (others => axi_lite_read_m2s_init);
136
546
    signal inputs_read_s2m : axi_lite_read_s2m_vec_t(inputs_read_m2s'range) := (others => axi_lite_read_s2m_init);
137
138
1106
    signal inputs_write_m2s : axi_lite_write_m2s_vec_t(0 to num_inputs - 1) := (others => axi_lite_write_m2s_init);
139
34
    signal inputs_write_s2m : axi_lite_write_s2m_vec_t(inputs_read_m2s'range) := (others => axi_lite_write_s2m_init);
140
141
402
    signal output_m2s : axi_lite_m2s_t := axi_lite_m2s_init;
142
146
    signal output_s2m : axi_lite_s2m_t := axi_lite_s2m_init;
143
  begin
144
145
    ------------------------------------------------------------------------------
146
    input_masters_gen : for idx in inputs_read_m2s'range generate
147
12
    begin
148
8
      axi_lite_master_inst : entity bfm.axi_lite_master
149
        generic map (
150
          bus_handle => input_masters(idx)
151
        )
152
        port map (
153
          clk => clk,
154
          --
155
          axi_lite_m2s.read => inputs_read_m2s(idx),
156
          axi_lite_m2s.write => inputs_write_m2s(idx),
157
          axi_lite_s2m.read => inputs_read_s2m(idx),
158
          axi_lite_s2m.write => inputs_write_s2m(idx)
159
        );
160
    end generate;
161
162
163
    ------------------------------------------------------------------------------
164
2
    axi_slave_inst : entity bfm.axi_lite_slave
165
      generic map (
166
        axi_read_slave => axi_read_slave,
167
        axi_write_slave => axi_write_slave,
168
        data_width => axi_port_data_width
169
      )
170
      port map (
171
        clk => clk,
172
        --
173
        axi_lite_write_m2s => output_m2s.write,
174
        axi_lite_write_s2m => output_s2m.write,
175
        --
176
        axi_lite_read_m2s => output_m2s.read,
177
        axi_lite_read_s2m => output_s2m.read
178
      );
179
180
181
    ------------------------------------------------------------------------------
182
2
    dut_read : entity work.axi_lite_simple_read_crossbar
183
      generic map(
184
        num_inputs => num_inputs
185
      )
186
      port map(
187
        clk => clk,
188
        --
189
        input_ports_m2s => inputs_read_m2s,
190
        input_ports_s2m => inputs_read_s2m,
191
        --
192
        output_m2s => output_m2s.read,
193
        output_s2m => output_s2m.read
194
      );
195
196
    ------------------------------------------------------------------------------
197
2
    dut_write : entity work.axi_lite_simple_write_crossbar
198
      generic map(
199
        num_inputs => num_inputs
200
      )
201
      port map(
202
        clk => clk,
203
        --
204
        input_ports_m2s => inputs_write_m2s,
205
        input_ports_s2m => inputs_write_s2m,
206
        --
207
        output_m2s => output_m2s.write,
208
        output_s2m => output_s2m.write
209
      );
210
211
  else generate
212
826
    signal inputs_read_m2s : axi_read_m2s_vec_t(0 to num_inputs - 1) := (others => axi_read_m2s_init);
213
1250
    signal inputs_read_s2m : axi_read_s2m_vec_t(inputs_read_m2s'range) := (others => axi_read_s2m_init);
214
215
2170
    signal inputs_write_m2s : axi_write_m2s_vec_t(0 to num_inputs - 1) := (others => axi_write_m2s_init);
216
226
    signal inputs_write_s2m : axi_write_s2m_vec_t(inputs_read_m2s'range) := (others => axi_write_s2m_init);
217
218
742
    signal output_m2s : axi_m2s_t := axi_m2s_init;
219
370
    signal output_s2m : axi_s2m_t := axi_s2m_init;
220
  begin
221
222
    ------------------------------------------------------------------------------
223
    input_masters_gen : for idx in inputs_read_m2s'range generate
224
14
    begin
225
8
      axi_master_inst : entity bfm.axi_master
226
        generic map (
227
          bus_handle => input_masters(idx)
228
        )
229
        port map (
230
          clk => clk,
231
          --
232
          axi_read_m2s => inputs_read_m2s(idx),
233
          axi_read_s2m => inputs_read_s2m(idx),
234
          --
235
          axi_write_m2s => inputs_write_m2s(idx),
236
          axi_write_s2m => inputs_write_s2m(idx)
237
        );
238
    end generate;
239
240
    ------------------------------------------------------------------------------
241
2
    axi_slave_inst : entity bfm.axi_slave
242
      generic map (
243
        axi_read_slave => axi_read_slave,
244
        axi_write_slave => axi_write_slave,
245
        data_width => axi_port_data_width
246
      )
247
      port map (
248
        clk => clk,
249
        --
250
        axi_read_m2s => output_m2s.read,
251
        axi_read_s2m => output_s2m.read,
252
        --
253
        axi_write_m2s => output_m2s.write,
254
        axi_write_s2m => output_s2m.write
255
      );
256
257
258
    ------------------------------------------------------------------------------
259
2
    dut_read : entity work.axi_simple_read_crossbar
260
      generic map(
261
        num_inputs => num_inputs
262
      )
263
      port map(
264
        clk => clk,
265
        --
266
        input_ports_m2s => inputs_read_m2s,
267
        input_ports_s2m => inputs_read_s2m,
268
        --
269
        output_m2s => output_m2s.read,
270
        output_s2m => output_s2m.read
271
      );
272
273
274
    ------------------------------------------------------------------------------
275
2
    dut_write : entity work.axi_simple_write_crossbar
276
      generic map(
277
        num_inputs => num_inputs
278
      )
279
      port map(
280
        clk => clk,
281
        --
282
        input_ports_m2s => inputs_write_m2s,
283
        input_ports_s2m => inputs_write_s2m,
284
        --
285
        output_m2s => output_m2s.write,
286
        output_s2m => output_s2m.write
287
      );
288
289
  end generate;
290
291
end architecture;