GCC Code Coverage Report
Directory: generated/vunit_out/preprocessed/ Exec Total Coverage
File: generated/vunit_out/preprocessed/common/tb_handshake_pipeline.vhd Lines: 67 67 100.0 %
Date: 2021-06-12 04:12:08 Branches: 187 281 66.5 %

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
9
library ieee;
10
use ieee.numeric_std.all;
11
use ieee.std_logic_1164.all;
12
13
library vunit_lib;
14
use vunit_lib.random_pkg.all;
15
context vunit_lib.vunit_context;
16
context vunit_lib.vc_context;
17
18
library osvvm;
19
use osvvm.RandomPkg.all;
20
21
use work.types_pkg.all;
22
23
24



























60
entity tb_handshake_pipeline is
25
  generic (
26
6
    full_throughput : boolean;
27
6
    allow_poor_input_ready_timing : boolean;
28
6
    data_jitter : boolean := false;
29

102
    runner_cfg : string
30
6
  );
31

36
end entity;
32
30
33




300
architecture tb of tb_handshake_pipeline is
34
114
35



42
  signal clk : std_logic := '0';
36

36
  constant clk_period : time := 10 ns;
37
12
38

18
  constant data_width : integer := 16;
39
306
40
6
  signal input_ready, input_valid, input_last : std_logic := '0';
41
6
  signal output_ready, output_valid, output_last : std_logic := '0';
42
390
  signal input_data, output_data : std_logic_vector(data_width - 1 downto 0) := (others => '0');
43
44
6
  constant num_words : integer := 1024;
45
46
6
  constant stall_config : stall_config_t := (
47
    stall_probability => 0.5 * real(to_int(data_jitter)),
48
    min_stall_cycles => 1,
49
    max_stall_cycles => 2
50
  );
51
52
6
  constant input_master : axi_stream_master_t := new_axi_stream_master(
53
    data_length => input_data'length,
54
    protocol_checker => new_axi_stream_protocol_checker(
55
      logger => get_logger("input_master"),
56
      data_length => input_data'length
57
    ),
58
    stall_config => stall_config
59
  );
60
61
6
  constant output_slave : axi_stream_slave_t := new_axi_stream_slave(
62
    data_length => input_data'length,
63
    protocol_checker => new_axi_stream_protocol_checker(
64
      logger => get_logger("output_slave"),
65
      data_length => output_data'length
66
    ),
67
    stall_config => stall_config
68
  );
69
70
12
  signal start, stimuli_done, data_check_done : boolean := false;
71
72
begin
73
74
86056
  test_runner_watchdog(runner, 2 ms);
75
86020
  clk <= not clk after clk_period / 2;
76
77
78
  ------------------------------------------------------------------------------
79
6
  main : process
80
6
    variable rnd : RandomPType;
81
82






368736
    procedure run_test is
83
18
      variable data : integer_array_t := null_integer_array;
84
85

594
      variable reference_data, got_data : std_logic_vector(input_data'range) := (others => '0');
86
18
      variable got_last : std_logic := '0';
87
88
18
      variable axi_stream_pop_reference : axi_stream_reference_t;
89
18
      variable axi_stream_pop_reference_queue : queue_t := new_queue;
90
    begin
91
18
      report "Starting test";
92
18
      data := random_integer_array(width=>num_words, bits_per_word=>data_width, is_signed=>false);
93
94
18
      for word_idx in 0 to length(data) - 1 loop
95

18432
        reference_data := std_logic_vector(to_unsigned(get(data, word_idx), reference_data'length));
96

73734
        push_axi_stream(
97
          net,
98
          input_master,
99
          tdata=>reference_data,
100
          tlast=>to_sl(word_idx=length(data) - 1)
101
        );
102
      end loop;
103
104
      -- Queue up reads in order to get full throughput. We need to keep track of
105
      -- the pop_reference when we read the reply later. Hence it is pushed to a queue.
106
18
      for word_idx in 0 to length(data) - 1 loop
107
36864
        pop_axi_stream(net, output_slave, axi_stream_pop_reference);
108

73728
        push(axi_stream_pop_reference_queue, axi_stream_pop_reference);
109
      end loop;
110
111
18
      for word_idx in 0 to length(data) - 1 loop
112
18432
        axi_stream_pop_reference := pop(axi_stream_pop_reference_queue);
113
73728
        await_pop_axi_stream_reply(
114
          net,
115
          axi_stream_pop_reference,
116
          tdata=>got_data,
117
          tlast=>got_last
118
        );
119
120

18432
        reference_data := std_logic_vector(to_unsigned(get(data, word_idx), reference_data'length));
121

36864
        check_equal(got_data, reference_data, "word_idx=" & to_string(word_idx), line_num => 121, file_name => "tb_handshake_pipeline.vhd");
122







368872
        check_equal(got_last, word_idx = num_words - 1, line_num => 122, file_name => "tb_handshake_pipeline.vhd");
123
      end loop;
124
    end procedure;
125
126
30
    variable start_time, time_diff : time;
127
128
  begin
129
18
    test_runner_setup(runner, runner_cfg);
130
12
    rnd.InitSeed(rnd'instance_name);
131
132
    -- Decrease noise
133
12
    disable(get_logger("input_master:rule 4"), warning);
134
12
    disable(get_logger("output_slave:rule 4"), warning);
135
136
6
    if run("test_random_data") then
137
8204
      run_test;
138
8200
      run_test;
139
8200
      run_test;
140
8204
      run_test;
141
142
10
    elsif run("test_full_throughput") then
143
2
      start_time := now;
144
4102
      run_test;
145
2
      time_diff := now - start_time;
146
147

6
      check_relation(time_diff < (num_words + 3) * clk_period, line_num => 147, file_name => "tb_handshake_pipeline.vhd", context_msg => "Expected time_diff < (num_words + 3) * clk_period. Left is " & to_string(time_diff) & ". Right is " & to_string((num_words + 3) * clk_period) & ".");
148
    end if;
149
150
130
    test_runner_cleanup(runner);
151
  end process;
152
153
154
  ------------------------------------------------------------------------------
155
6
  axi_stream_master_inst : entity vunit_lib.axi_stream_master
156
    generic map(
157
      master => input_master
158
    )
159
    port map(
160
      aclk => clk,
161
      tvalid => input_valid,
162
      tready => input_ready,
163
      tdata => input_data,
164
      tlast => input_last
165
    );
166
167
168
  ------------------------------------------------------------------------------
169
6
  axi_stream_slave_inst : entity vunit_lib.axi_stream_slave
170
    generic map(
171
      slave => output_slave
172
    )
173
    port map(
174
      aclk => clk,
175
      tvalid => output_valid,
176
      tready => output_ready,
177
      tdata => output_data,
178
      tlast => output_last
179
    );
180
181
182
  ------------------------------------------------------------------------------
183
6
  dut : entity work.handshake_pipeline
184
    generic map (
185
      data_width => data_width,
186
      full_throughput => full_throughput,
187
      allow_poor_input_ready_timing => allow_poor_input_ready_timing
188
    )
189
    port map (
190
      clk => clk,
191
      --
192
      input_ready => input_ready,
193
      input_valid => input_valid,
194
      input_last => input_last,
195
      input_data => input_data,
196
      --
197
      output_ready => output_ready,
198
      output_valid => output_valid,
199
      output_last => output_last,
200
      output_data => output_data
201
    );
202
203
end architecture;