OpenCores
URL https://opencores.org/ocsvn/dp_pkg/dp_pkg/trunk

Subversion Repositories dp_pkg

[/] [dp_pkg/] [trunk/] [tb_dp_pkg.vhd] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 danv
-------------------------------------------------------------------------------
2
--
3 7 danv
-- Copyright 2020
4 2 danv
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6 7 danv
-- 
7
-- Licensed under the Apache License, Version 2.0 (the "License");
8
-- you may not use this file except in compliance with the License.
9
-- You may obtain a copy of the License at
10
-- 
11
--     http://www.apache.org/licenses/LICENSE-2.0
12
-- 
13
-- Unless required by applicable law or agreed to in writing, software
14
-- distributed under the License is distributed on an "AS IS" BASIS,
15
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
-- See the License for the specific language governing permissions and
17
-- limitations under the License.
18 2 danv
--
19
-------------------------------------------------------------------------------
20
 
21
LIBRARY IEEE, common_pkg_lib;
22
USE IEEE.std_logic_1164.ALL;
23
USE IEEE.numeric_std.ALL;
24
USE common_pkg_lib.common_pkg.ALL;
25
USE common_pkg_lib.common_lfsr_sequences_pkg.ALL;
26
USE common_pkg_lib.tb_common_pkg.ALL;
27
USE work.dp_stream_pkg.ALL;
28
 
29
 
30
PACKAGE tb_dp_pkg IS
31
 
32
  ------------------------------------------------------------------------------
33
  -- Purpose:
34
  --
35
  -- Test bench package for applying stimuli to a streaming data path. The
36
  -- input is counter data, the output is verified and an error is reported
37
  -- if a counter value is missing or duplicate.
38
  --
39
  -- Description:
40
  --
41
  -- The test is divided into intervals marked by sync to start a new subtest
42
  -- named by state. New subtests can be added by adding an extra sync interval
43
  -- and state name to this package. In each subtest the streaming interface
44
  -- DUT can be verified for different situations by manipulating:
45
  -- . cnt_en    : cnt_en not always active when in_ready is asserted
46
  -- . out_ready : out_ready not always active
47
  --
48
  -- Remarks:
49
  -- . See e.g. tb_dp_pipeline.vhd for how to use the procedures.
50
  -- . To run all stimuli in Modelsim do:
51
  --   > as 10
52
  --   > run 400 us
53
  ------------------------------------------------------------------------------
54
 
55
  CONSTANT clk_period         : TIME := 10 ns;  -- 100 MHz
56
  CONSTANT c_dp_sync_interval : NATURAL := 3000;
57
  CONSTANT c_dp_test_interval : NATURAL := 100;
58
  CONSTANT c_dp_nof_toggle    : NATURAL := 40;
59
  CONSTANT c_dp_nof_both      : NATURAL := 50;
60
 
61
  -- The test bench uses other field widths than the standard t_dp_sosi record field widths, the assumptions are:
62
  -- . c_dp_data_w < c_dp_stream_data_w
63
  -- . c_dp_data_w > c_dp_stream_empty_w
64
  -- . c_dp_data_w > c_dp_stream_channel_w
65
  -- . c_dp_data_w > c_dp_stream_error_w
66
  CONSTANT c_dp_data_w            : NATURAL := c_word_w;  -- =32, choose wide enough to avoid out_data wrap around issue for p_verify
67
  CONSTANT c_dp_bsn_w             : NATURAL := c_dp_data_w;  -- c_dp_stream_bsn_w;
68
  CONSTANT c_dp_empty_w           : NATURAL := c_dp_stream_empty_w;
69
  CONSTANT c_dp_channel_w         : NATURAL := c_dp_stream_channel_w;
70
  CONSTANT c_dp_channel_user_w    : NATURAL := c_dp_stream_channel_w/2;     -- support some bits for mux input user streams channel widths
71
  CONSTANT c_dp_channel_mux_w     : NATURAL :=(c_dp_stream_channel_w+1)/2;  -- support rest bits for the nof input ports of a mux
72
  CONSTANT c_dp_error_w           : NATURAL := c_dp_stream_error_w;
73
 
74
  TYPE t_dp_data_arr IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0);
75
 
76
  -- The state name tells what kind of test is done in the sync interval
77
  TYPE t_dp_state_enum IS (
78
    s_idle,
79
    s_both_active,
80
    s_pull_down_out_ready,
81
    s_pull_down_cnt_en,
82
    s_toggle_out_ready,
83
    s_toggle_cnt_en,
84
    s_toggle_both,
85
    s_pulse_cnt_en,
86
    s_chirp_out_ready,
87
    s_random,
88
    s_done
89
  );
90
 
91
  TYPE t_dp_value_enum IS (
92
    e_equal,
93
    e_at_least
94
  );
95
 
96
  -- always active, random or pulse flow control
97
  TYPE t_dp_flow_control_enum IS (
98
    e_active,
99
    e_random,
100
    e_pulse
101
  );
102
 
103
  TYPE t_dp_flow_control_enum_arr IS ARRAY (NATURAL RANGE <>) OF t_dp_flow_control_enum;
104
 
105
  CONSTANT c_dp_flow_control_enum_arr : t_dp_flow_control_enum_arr := (e_active, e_random, e_pulse);  -- array all possible values that can be iterated over
106
 
107
  ------------------------------------------------------------------------------
108
  -- Stream source functions
109
  ------------------------------------------------------------------------------
110
 
111
  -- Block data generator with feedforward throttle control
112
  -- !!! old style: sync before sop
113
  -- !!! used by tb_dp_packetizing, do not use for new DP components
114
  PROCEDURE proc_dp_gen_block_data(CONSTANT c_nof_block_per_sync : IN    NATURAL;
115
                                   CONSTANT c_block_size         : IN    NATURAL;
116
                                   CONSTANT c_gap_size           : IN    NATURAL;
117
                                   CONSTANT c_throttle_num       : IN    NATURAL;
118
                                   CONSTANT c_throttle_den       : IN    NATURAL;
119
                                   SIGNAL   rst                  : IN    STD_LOGIC;
120
                                   SIGNAL   clk                  : IN    STD_LOGIC;
121
                                   SIGNAL   sync_nr              : INOUT NATURAL;
122
                                   SIGNAL   block_nr             : INOUT NATURAL;
123
                                   SIGNAL   cnt_sync             : OUT   STD_LOGIC;
124
                                   SIGNAL   cnt_val              : OUT   STD_LOGIC;
125
                                   SIGNAL   cnt_dat              : INOUT STD_LOGIC_VECTOR);
126
 
127
  -- Block data generator with ready flow control and symbols counter
128
  PROCEDURE proc_dp_gen_block_data(CONSTANT c_ready_latency  : IN  NATURAL;    -- 0, 1 are supported by proc_dp_stream_ready_latency()
129
                                   CONSTANT c_use_data       : IN  BOOLEAN;    -- when TRUE use data field, else use re, im fields, and keep unused fields at 'X'
130
                                   CONSTANT c_data_w         : IN  NATURAL;    -- data width for the data, re and im fields
131
                                   CONSTANT c_symbol_w       : IN  NATURAL;    -- c_data_w/c_symbol_w must be an integer
132
                                   CONSTANT c_symbol_init    : IN  NATURAL;    -- init counter for symbols in data field
133
                                   CONSTANT c_symbol_re_init : IN  NATURAL;    -- init counter for symbols in re field
134
                                   CONSTANT c_symbol_im_init : IN  NATURAL;    -- init counter for symbols in im field
135
                                   CONSTANT c_nof_symbols    : IN  NATURAL;    -- nof symbols per frame for the data, re and im fields
136
                                   CONSTANT c_channel        : IN  NATURAL;    -- channel field
137
                                   CONSTANT c_error          : IN  NATURAL;    -- error field
138
                                   CONSTANT c_sync           : IN  STD_LOGIC;  -- when '1' issue sync pulse during this block
139
                                   CONSTANT c_bsn            : IN  STD_LOGIC_VECTOR;  -- bsn field
140
                                   SIGNAL   clk              : IN  STD_LOGIC;
141
                                   SIGNAL   in_en            : IN  STD_LOGIC;  -- when '0' then no valid output even when src_in is ready
142
                                   SIGNAL   src_in           : IN  t_dp_siso;
143
                                   SIGNAL   src_out          : OUT t_dp_sosi);
144
 
145
  PROCEDURE proc_dp_gen_block_data(CONSTANT c_data_w         : IN  NATURAL;    -- data width for the data field
146
                                   CONSTANT c_symbol_init    : IN  NATURAL;    -- init counter for the data in the data field
147
                                   CONSTANT c_nof_symbols    : IN  NATURAL;    -- nof symbols per frame for the data fields
148
                                   CONSTANT c_channel        : IN  NATURAL;    -- channel field
149
                                   CONSTANT c_error          : IN  NATURAL;    -- error field
150
                                   CONSTANT c_sync           : IN  STD_LOGIC;  -- when '1' issue sync pulse during this block
151
                                   CONSTANT c_bsn            : IN  STD_LOGIC_VECTOR;  -- bsn field
152
                                   SIGNAL   clk              : IN  STD_LOGIC;
153
                                   SIGNAL   in_en            : IN  STD_LOGIC;  -- when '0' then no valid output even when src_in is ready
154
                                   SIGNAL   src_in           : IN  t_dp_siso;
155
                                   SIGNAL   src_out          : OUT t_dp_sosi);
156
 
157
  -- Handle stream ready signal, only support RL=0 or 1.
158
  PROCEDURE proc_dp_stream_ready_latency(CONSTANT c_latency : IN  NATURAL;
159
                                         SIGNAL   clk       : IN  STD_LOGIC;
160
                                         SIGNAL   ready     : IN  STD_LOGIC;
161
                                         SIGNAL   in_en     : IN  STD_LOGIC;  -- when '1' then active output when ready
162
                                         CONSTANT c_sync    : IN  STD_LOGIC;
163
                                         CONSTANT c_valid   : IN  STD_LOGIC;
164
                                         CONSTANT c_sop     : IN  STD_LOGIC;
165
                                         CONSTANT c_eop     : IN  STD_LOGIC;
166
                                         SIGNAL   out_sync  : OUT STD_LOGIC;
167
                                         SIGNAL   out_valid : OUT STD_LOGIC;
168
                                         SIGNAL   out_sop   : OUT STD_LOGIC;
169
                                         SIGNAL   out_eop   : OUT STD_LOGIC);
170
 
171
  -- Initialize the data per symbol
172
  FUNCTION func_dp_data_init(c_data_w, c_symbol_w, init : NATURAL) RETURN STD_LOGIC_VECTOR;
173
 
174
  -- Increment the data per symbol
175
  FUNCTION func_dp_data_incr(c_data_w, c_symbol_w : NATURAL; data : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
176
 
177
  -- Generate a counter data with valid
178
  PROCEDURE proc_dp_gen_data(CONSTANT c_ready_latency : IN  NATURAL;    -- 0, 1 are supported by proc_dp_stream_ready_latency()
179
                             CONSTANT c_data_w        : IN  NATURAL;
180
                             CONSTANT c_data_init     : IN  NATURAL;
181
                             SIGNAL   rst             : IN  STD_LOGIC;
182
                             SIGNAL   clk             : IN  STD_LOGIC;
183
                             SIGNAL   in_en           : IN  STD_LOGIC;  -- when '0' then no valid output even when src_in is ready
184
                             SIGNAL   src_in          : IN  t_dp_siso;
185
                             SIGNAL   src_out         : OUT t_dp_sosi);
186
 
187
  -- As above but with counter max
188
  PROCEDURE proc_dp_gen_data(CONSTANT c_ready_latency   : IN  NATURAL;
189
                             CONSTANT c_data_w          : IN  NATURAL;
190
                             CONSTANT c_data_init       : IN  NATURAL;
191
                             CONSTANT c_data_max        : IN  NATURAL;
192
                             SIGNAL   rst             : IN  STD_LOGIC;
193
                             SIGNAL   clk             : IN  STD_LOGIC;
194
                             SIGNAL   in_en           : IN  STD_LOGIC;
195
                             SIGNAL   src_in          : IN  t_dp_siso;
196
                             SIGNAL   src_out         : OUT t_dp_sosi);
197
 
198
  -- Generate a frame with symbols counter
199
  PROCEDURE proc_dp_gen_frame(CONSTANT c_ready_latency : IN  NATURAL;    -- 0, 1 are supported by proc_dp_stream_ready_latency()
200
                              CONSTANT c_data_w        : IN  NATURAL;
201
                              CONSTANT c_symbol_w      : IN  NATURAL;    -- c_data_w/c_symbol_w must be an integer
202
                              CONSTANT c_symbol_init   : IN  NATURAL;
203
                              CONSTANT c_nof_symbols   : IN  NATURAL;
204
                              CONSTANT c_bsn           : IN  NATURAL;
205
                              CONSTANT c_sync          : IN  STD_LOGIC;
206
                              SIGNAL   clk             : IN  STD_LOGIC;
207
                              SIGNAL   in_en           : IN  STD_LOGIC;  -- when '0' then no valid output even when src_in is ready
208
                              SIGNAL   src_in          : IN  t_dp_siso;
209
                              SIGNAL   src_out         : OUT t_dp_sosi);
210
 
211
  -- Input data counter
212
  PROCEDURE proc_dp_cnt_dat(SIGNAL rst     : IN    STD_LOGIC;
213
                            SIGNAL clk     : IN    STD_LOGIC;
214
                            SIGNAL in_en   : IN    STD_LOGIC;
215
                            SIGNAL cnt_dat : INOUT STD_LOGIC_VECTOR);
216
 
217
  PROCEDURE proc_dp_cnt_dat(SIGNAL rst     : IN    STD_LOGIC;
218
                            SIGNAL clk     : IN    STD_LOGIC;
219
                            SIGNAL in_en   : IN    STD_LOGIC;
220
                            SIGNAL cnt_val : INOUT STD_LOGIC;
221
                            SIGNAL cnt_dat : INOUT STD_LOGIC_VECTOR);
222
 
223
  -- Transmit data
224
  PROCEDURE proc_dp_tx_data(CONSTANT c_ready_latency : IN    NATURAL;
225
                            SIGNAL   rst             : IN    STD_LOGIC;
226
                            SIGNAL   clk             : IN    STD_LOGIC;
227
                            SIGNAL   cnt_val         : IN    STD_LOGIC;
228
                            SIGNAL   cnt_dat         : IN    STD_LOGIC_VECTOR;
229
                            SIGNAL   tx_data         : INOUT t_dp_data_arr;
230
                            SIGNAL   tx_val          : INOUT STD_LOGIC_VECTOR;
231
                            SIGNAL   out_data        : OUT   STD_LOGIC_VECTOR;
232
                            SIGNAL   out_val         : OUT   STD_LOGIC);
233
 
234
  -- Transmit data control (use for sop, eop)
235
  PROCEDURE proc_dp_tx_ctrl(CONSTANT c_offset : IN  NATURAL;
236
                            CONSTANT c_period : IN  NATURAL;
237
                            SIGNAL   data     : IN  STD_LOGIC_VECTOR;
238
                            SIGNAL   valid    : IN  STD_LOGIC;
239
                            SIGNAL   ctrl     : OUT STD_LOGIC);
240
 
241
  -- Define sync interval
242
  PROCEDURE proc_dp_sync_interval(SIGNAL clk  : IN  STD_LOGIC;
243
                                  SIGNAL sync : OUT STD_LOGIC);
244
 
245
  -- Stimuli for cnt_en
246
  PROCEDURE proc_dp_count_en(SIGNAL rst    : IN    STD_LOGIC;
247
                             SIGNAL clk    : IN    STD_LOGIC;
248
                             SIGNAL sync   : IN    STD_LOGIC;
249
                             SIGNAL lfsr   : INOUT STD_LOGIC_VECTOR;
250
                             SIGNAL state  : OUT   t_dp_state_enum;
251
                             SIGNAL done   : OUT   STD_LOGIC;
252
                             SIGNAL tb_end : OUT   STD_LOGIC;
253
                             SIGNAL cnt_en : OUT   STD_LOGIC);
254
 
255
  ------------------------------------------------------------------------------
256
  -- Stream sink functions
257
  ------------------------------------------------------------------------------
258
 
259
  -- Stimuli for out_ready
260
  PROCEDURE proc_dp_out_ready(SIGNAL rst       : IN    STD_LOGIC;
261
                              SIGNAL clk       : IN    STD_LOGIC;
262
                              SIGNAL sync      : IN    STD_LOGIC;
263
                              SIGNAL lfsr      : INOUT STD_LOGIC_VECTOR;
264
                              SIGNAL out_ready : OUT   STD_LOGIC);
265
 
266
  -- DUT output verify enable
267
  PROCEDURE proc_dp_verify_en(CONSTANT c_delay   : IN  NATURAL;
268
                              SIGNAL   rst       : IN  STD_LOGIC;
269
                              SIGNAL   clk       : IN  STD_LOGIC;
270
                              SIGNAL   sync      : IN  STD_LOGIC;
271
                              SIGNAL   verify_en : OUT STD_LOGIC);
272
 
273
  PROCEDURE proc_dp_verify_en(CONSTANT c_continuous : IN  BOOLEAN;
274
                              SIGNAL   clk          : IN  STD_LOGIC;
275
                              SIGNAL   valid        : IN  STD_LOGIC;
276
                              SIGNAL   sop          : IN  STD_LOGIC;
277
                              SIGNAL   eop          : IN  STD_LOGIC;
278
                              SIGNAL   verify_en    : OUT STD_LOGIC);
279
 
280
  -- Run and verify for some cycles
281
  PROCEDURE proc_dp_verify_run_some_cycles(CONSTANT nof_pre_clk    : IN   NATURAL;
282
                                           CONSTANT nof_verify_clk : IN   NATURAL;
283
                                           CONSTANT nof_post_clk   : IN   NATURAL;
284
                                           SIGNAL   clk            : IN   STD_LOGIC;
285
                                           SIGNAL   verify_en      : OUT  STD_LOGIC);
286
 
287
  -- Verify the expected value
288
  PROCEDURE proc_dp_verify_value(CONSTANT c_str : IN STRING;
289
                                 CONSTANT mode  : IN t_dp_value_enum;
290
                                 SIGNAL   clk   : IN STD_LOGIC;
291
                                 SIGNAL   en    : IN STD_LOGIC;
292
                                 SIGNAL   exp   : IN STD_LOGIC_VECTOR;
293
                                 SIGNAL   res   : IN STD_LOGIC_VECTOR);
294
 
295
  PROCEDURE proc_dp_verify_value(CONSTANT mode : IN t_dp_value_enum;
296
                                 SIGNAL   clk  : IN STD_LOGIC;
297
                                 SIGNAL   en   : IN STD_LOGIC;
298
                                 SIGNAL   exp  : IN STD_LOGIC_VECTOR;
299
                                 SIGNAL   res  : IN STD_LOGIC_VECTOR);
300
 
301
  PROCEDURE proc_dp_verify_value(CONSTANT c_str : IN STRING;
302
                                 SIGNAL   clk   : IN STD_LOGIC;
303
                                 SIGNAL   en    : IN STD_LOGIC;
304
                                 SIGNAL   exp   : IN STD_LOGIC;
305
                                 SIGNAL   res   : IN STD_LOGIC);
306
 
307
  -- Verify output global and local BSN
308
  -- . incrementing or replicated global BSN
309
  -- . incrementing local BSN that starts at 1
310
  PROCEDURE proc_dp_verify_bsn(CONSTANT c_use_local_bsn             : IN    BOOLEAN;    -- use local BSN or only use global BSN
311
                               CONSTANT c_global_bsn_increment      : IN    POSITIVE;   -- increment per global BSN
312
                               CONSTANT c_nof_replicated_global_bsn : IN    POSITIVE;   -- number of replicated global BSN
313
                               CONSTANT c_block_per_sync            : IN    POSITIVE;   -- of sop/eop blocks per sync interval
314
                               SIGNAL   clk                         : IN    STD_LOGIC;
315
                               SIGNAL   out_sync                    : IN    STD_LOGIC;
316
                               SIGNAL   out_sop                     : IN    STD_LOGIC;
317
                               SIGNAL   out_bsn                     : IN    STD_LOGIC_VECTOR;
318
                               SIGNAL   verify_en                   : INOUT STD_LOGIC;  -- initialize '0', becomes '1' when bsn verification starts
319
                               SIGNAL   cnt_replicated_global_bsn   : INOUT NATURAL;
320
                               SIGNAL   prev_out_bsn_global         : INOUT STD_LOGIC_VECTOR;
321
                               SIGNAL   prev_out_bsn_local          : INOUT STD_LOGIC_VECTOR);
322
 
323
  -- Verify incrementing data
324
  -- . wrap at c_out_data_max when >0, else no wrap when c_out_data_max=0
325
  -- . default increment by +1, but also allow an increment by +c_out_data_gap
326
  PROCEDURE proc_dp_verify_data(CONSTANT c_str           : IN    STRING;
327
                                CONSTANT c_ready_latency : IN    NATURAL;
328
                                CONSTANT c_out_data_max  : IN    UNSIGNED;
329
                                CONSTANT c_out_data_gap  : IN    UNSIGNED;
330
                                SIGNAL   clk             : IN    STD_LOGIC;
331
                                SIGNAL   verify_en       : IN    STD_LOGIC;
332
                                SIGNAL   out_ready       : IN    STD_LOGIC;
333
                                SIGNAL   out_val         : IN    STD_LOGIC;
334
                                SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
335
                                SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR);
336
 
337
  -- Verify the DUT incrementing output data that wraps in range 0 ... c_out_data_max
338
  PROCEDURE proc_dp_verify_data(CONSTANT c_str           : IN    STRING;
339
                                CONSTANT c_ready_latency : IN    NATURAL;
340
                                CONSTANT c_out_data_max  : IN    UNSIGNED;
341
                                SIGNAL   clk             : IN    STD_LOGIC;
342
                                SIGNAL   verify_en       : IN    STD_LOGIC;
343
                                SIGNAL   out_ready       : IN    STD_LOGIC;
344
                                SIGNAL   out_val         : IN    STD_LOGIC;
345
                                SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
346
                                SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR);
347
 
348
  -- Verify the DUT incrementing output data, fixed increment +1
349
  PROCEDURE proc_dp_verify_data(CONSTANT c_str           : IN    STRING;
350
                                CONSTANT c_ready_latency : IN    NATURAL;
351
                                SIGNAL   clk             : IN    STD_LOGIC;
352
                                SIGNAL   verify_en       : IN    STD_LOGIC;
353
                                SIGNAL   out_ready       : IN    STD_LOGIC;
354
                                SIGNAL   out_val         : IN    STD_LOGIC;  -- by using sop or eop proc_dp_verify_data() can also be used to verify other SOSI fields like bsn, error, channel, empty
355
                                SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
356
                                SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR);
357
 
358
  -- Verify incrementing data with RL > 0 or no flow control, support wrap at maximum and increment gap
359
  PROCEDURE proc_dp_verify_data(CONSTANT c_str           : IN    STRING;
360
                                CONSTANT c_out_data_max  : IN    UNSIGNED;
361
                                CONSTANT c_out_data_gap  : IN    UNSIGNED;
362
                                SIGNAL   clk             : IN    STD_LOGIC;
363
                                SIGNAL   verify_en       : IN    STD_LOGIC;
364
                                SIGNAL   out_val         : IN    STD_LOGIC;
365
                                SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
366
                                SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR);
367
 
368
  PROCEDURE proc_dp_verify_data(CONSTANT c_str           : IN    STRING;
369
                                CONSTANT c_out_data_max  : IN    NATURAL;
370
                                CONSTANT c_out_data_gap  : IN    NATURAL;
371
                                SIGNAL   clk             : IN    STD_LOGIC;
372
                                SIGNAL   verify_en       : IN    STD_LOGIC;
373
                                SIGNAL   out_val         : IN    STD_LOGIC;
374
                                SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
375
                                SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR);
376
 
377
  PROCEDURE proc_dp_verify_data(CONSTANT c_str           : IN    STRING;
378
                                CONSTANT c_out_data_max  : IN    NATURAL;
379
                                SIGNAL   clk             : IN    STD_LOGIC;
380
                                SIGNAL   verify_en       : IN    STD_LOGIC;
381
                                SIGNAL   out_val         : IN    STD_LOGIC;
382
                                SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
383
                                SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR);
384
 
385
  -- Verify incrementing data with RL > 0 or no flow control, fixed increment +1
386
  PROCEDURE proc_dp_verify_data(CONSTANT c_str           : IN    STRING;
387
                                SIGNAL   clk             : IN    STD_LOGIC;
388
                                SIGNAL   verify_en       : IN    STD_LOGIC;
389
                                SIGNAL   out_val         : IN    STD_LOGIC;
390
                                SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
391
                                SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR);
392
 
393
  -- Verify the DUT output symbols
394
  PROCEDURE proc_dp_verify_symbols(CONSTANT c_ready_latency : IN    NATURAL;
395
                                   CONSTANT c_data_w        : IN    NATURAL;
396
                                   CONSTANT c_symbol_w      : IN    NATURAL;
397
                                   SIGNAL   clk             : IN    STD_LOGIC;
398
                                   SIGNAL   verify_en       : IN    STD_LOGIC;
399
                                   SIGNAL   out_ready       : IN    STD_LOGIC;
400
                                   SIGNAL   out_val         : IN    STD_LOGIC;
401
                                   SIGNAL   out_eop         : IN    STD_LOGIC;
402
                                   SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
403
                                   SIGNAL   out_empty       : IN    STD_LOGIC_VECTOR;
404
                                   SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR);
405
 
406
  -- Verify the DUT output data with empty
407
  PROCEDURE proc_dp_verify_data_empty(CONSTANT c_ready_latency : IN    NATURAL;
408
                                      CONSTANT c_last_word     : IN    NATURAL;
409
                                      SIGNAL   clk             : IN    STD_LOGIC;
410
                                      SIGNAL   verify_en       : IN    STD_LOGIC;
411
                                      SIGNAL   out_ready       : IN    STD_LOGIC;
412
                                      SIGNAL   out_val         : IN    STD_LOGIC;
413
                                      SIGNAL   out_eop         : IN    STD_LOGIC;
414
                                      SIGNAL   out_eop_1       : INOUT STD_LOGIC;
415
                                      SIGNAL   out_eop_2       : INOUT STD_LOGIC;
416
                                      SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
417
                                      SIGNAL   out_data_1      : INOUT STD_LOGIC_VECTOR;
418
                                      SIGNAL   out_data_2      : INOUT STD_LOGIC_VECTOR;
419
                                      SIGNAL   out_data_3      : INOUT STD_LOGIC_VECTOR;
420
                                      SIGNAL   out_empty       : IN    STD_LOGIC_VECTOR;
421
                                      SIGNAL   out_empty_1     : INOUT STD_LOGIC_VECTOR);
422
 
423
  PROCEDURE proc_dp_verify_other_sosi(CONSTANT c_str       : IN STRING;
424
                                      CONSTANT c_exp_data  : IN STD_LOGIC_VECTOR;
425
                                      SIGNAL   clk         : IN STD_LOGIC;
426
                                      SIGNAL   verify_en   : IN STD_LOGIC;
427
                                      SIGNAL   res_data    : IN STD_LOGIC_VECTOR);
428
 
429
  PROCEDURE proc_dp_verify_valid(CONSTANT c_ready_latency : IN    NATURAL;
430
                                 SIGNAL   clk             : IN    STD_LOGIC;
431
                                 SIGNAL   verify_en       : IN    STD_LOGIC;
432
                                 SIGNAL   out_ready       : IN    STD_LOGIC;
433
                                 SIGNAL   prev_out_ready  : INOUT STD_LOGIC_VECTOR;
434
                                 SIGNAL   out_val         : IN    STD_LOGIC);
435
 
436
  PROCEDURE proc_dp_verify_valid(SIGNAL   clk             : IN    STD_LOGIC;
437
                                 SIGNAL   verify_en       : IN    STD_LOGIC;
438
                                 SIGNAL   out_ready       : IN    STD_LOGIC;
439
                                 SIGNAL   prev_out_ready  : INOUT STD_LOGIC;
440
                                 SIGNAL   out_val         : IN    STD_LOGIC);
441
 
442
  -- Verify the DUT output sync
443
  PROCEDURE proc_dp_verify_sync(CONSTANT c_sync_period : IN    NATURAL;
444
                                CONSTANT c_sync_offset : IN    NATURAL;
445
                                SIGNAL   clk           : IN    STD_LOGIC;
446
                                SIGNAL   verify_en     : IN    STD_LOGIC;
447
                                SIGNAL   sync          : IN    STD_LOGIC;
448
                                SIGNAL   sop           : IN    STD_LOGIC;
449
                                SIGNAL   bsn           : IN    STD_LOGIC_VECTOR);
450
 
451
  -- Verify the DUT output sop and eop
452
  PROCEDURE proc_dp_verify_sop_and_eop(CONSTANT c_ready_latency : IN    NATURAL;
453
                                       CONSTANT c_verify_valid  : IN    BOOLEAN;
454
                                       SIGNAL   clk             : IN    STD_LOGIC;
455
                                       SIGNAL   out_ready       : IN    STD_LOGIC;
456
                                       SIGNAL   out_val         : IN    STD_LOGIC;
457
                                       SIGNAL   out_sop         : IN    STD_LOGIC;
458
                                       SIGNAL   out_eop         : IN    STD_LOGIC;
459
                                       SIGNAL   hold_sop        : INOUT STD_LOGIC);
460
 
461
  PROCEDURE proc_dp_verify_sop_and_eop(CONSTANT c_ready_latency : IN    NATURAL;
462
                                       SIGNAL   clk             : IN    STD_LOGIC;
463
                                       SIGNAL   out_ready       : IN    STD_LOGIC;
464
                                       SIGNAL   out_val         : IN    STD_LOGIC;
465
                                       SIGNAL   out_sop         : IN    STD_LOGIC;
466
                                       SIGNAL   out_eop         : IN    STD_LOGIC;
467
                                       SIGNAL   hold_sop        : INOUT STD_LOGIC);
468
 
469
  PROCEDURE proc_dp_verify_sop_and_eop(SIGNAL clk      : IN    STD_LOGIC;
470
                                       SIGNAL out_val  : IN    STD_LOGIC;
471
                                       SIGNAL out_sop  : IN    STD_LOGIC;
472
                                       SIGNAL out_eop  : IN    STD_LOGIC;
473
                                       SIGNAL hold_sop : INOUT STD_LOGIC);
474
 
475
  PROCEDURE proc_dp_verify_block_size(CONSTANT c_ready_latency : IN    NATURAL;
476
                                      SIGNAL   alt_size        : IN    NATURAL;     -- alternative size (eg. use exp_size'last_value)
477
                                      SIGNAL   exp_size        : IN    NATURAL;     -- expected size
478
                                      SIGNAL   clk             : IN    STD_LOGIC;
479
                                      SIGNAL   out_ready       : IN    STD_LOGIC;
480
                                      SIGNAL   out_val         : IN    STD_LOGIC;
481
                                      SIGNAL   out_sop         : IN    STD_LOGIC;
482
                                      SIGNAL   out_eop         : IN    STD_LOGIC;
483
                                      SIGNAL   cnt_size        : INOUT NATURAL);
484
 
485
  PROCEDURE proc_dp_verify_block_size(CONSTANT c_ready_latency : IN    NATURAL;
486
                                      SIGNAL   exp_size        : IN    NATURAL;     -- expected size
487
                                      SIGNAL   clk             : IN    STD_LOGIC;
488
                                      SIGNAL   out_ready       : IN    STD_LOGIC;
489
                                      SIGNAL   out_val         : IN    STD_LOGIC;
490
                                      SIGNAL   out_sop         : IN    STD_LOGIC;
491
                                      SIGNAL   out_eop         : IN    STD_LOGIC;
492
                                      SIGNAL   cnt_size        : INOUT NATURAL);
493
 
494
  PROCEDURE proc_dp_verify_block_size(SIGNAL alt_size : IN    NATURAL;     -- alternative size (eg. use exp_size'last_value)
495
                                      SIGNAL exp_size : IN    NATURAL;     -- expected size
496
                                      SIGNAL clk      : IN    STD_LOGIC;
497
                                      SIGNAL out_val  : IN    STD_LOGIC;
498
                                      SIGNAL out_sop  : IN    STD_LOGIC;
499
                                      SIGNAL out_eop  : IN    STD_LOGIC;
500
                                      SIGNAL cnt_size : INOUT NATURAL);
501
 
502
  PROCEDURE proc_dp_verify_block_size(SIGNAL exp_size : IN    NATURAL;     -- expected size
503
                                      SIGNAL clk      : IN    STD_LOGIC;
504
                                      SIGNAL out_val  : IN    STD_LOGIC;
505
                                      SIGNAL out_sop  : IN    STD_LOGIC;
506
                                      SIGNAL out_eop  : IN    STD_LOGIC;
507
                                      SIGNAL cnt_size : INOUT NATURAL);
508
 
509
  -- Verify the DUT output invalid between frames
510
  PROCEDURE proc_dp_verify_gap_invalid(SIGNAL clk     : IN    STD_LOGIC;
511
                                       SIGNAL in_val  : IN    STD_LOGIC;
512
                                       SIGNAL in_sop  : IN    STD_LOGIC;
513
                                       SIGNAL in_eop  : IN    STD_LOGIC;
514
                                       SIGNAL out_gap : INOUT STD_LOGIC);  -- declare initial gap signal = '1'
515
 
516
  -- Verify the DUT output control (use for sop, eop)
517
  PROCEDURE proc_dp_verify_ctrl(CONSTANT c_offset  : IN NATURAL;
518
                                CONSTANT c_period  : IN NATURAL;
519
                                CONSTANT c_str     : IN STRING;
520
                                SIGNAL   clk       : IN STD_LOGIC;
521
                                SIGNAL   verify_en : IN STD_LOGIC;
522
                                SIGNAL   data      : IN STD_LOGIC_VECTOR;
523
                                SIGNAL   valid     : IN STD_LOGIC;
524
                                SIGNAL   ctrl      : IN STD_LOGIC);
525
 
526
  -- Wait for stream valid
527
  PROCEDURE proc_dp_stream_valid(SIGNAL clk      : IN  STD_LOGIC;
528
                                 SIGNAL in_valid : IN  STD_LOGIC);
529
 
530
  -- Wait for stream valid AND sop
531
  PROCEDURE proc_dp_stream_valid_sop(SIGNAL clk      : IN  STD_LOGIC;
532
                                     SIGNAL in_valid : IN  STD_LOGIC;
533
                                     SIGNAL in_sop   : IN  STD_LOGIC);
534
 
535
  -- Wait for stream valid AND eop
536
  PROCEDURE proc_dp_stream_valid_eop(SIGNAL clk      : IN  STD_LOGIC;
537
                                     SIGNAL in_valid : IN  STD_LOGIC;
538
                                     SIGNAL in_eop   : IN  STD_LOGIC);
539
 
540
END tb_dp_pkg;
541
 
542
 
543
PACKAGE BODY tb_dp_pkg IS
544
 
545
  ------------------------------------------------------------------------------
546
  -- PROCEDURE: Block data generator with feedforward throttle control
547
  ------------------------------------------------------------------------------
548
  PROCEDURE proc_dp_gen_block_data(CONSTANT c_nof_block_per_sync : IN    NATURAL;
549
                                   CONSTANT c_block_size         : IN    NATURAL;
550
                                   CONSTANT c_gap_size           : IN    NATURAL;
551
                                   CONSTANT c_throttle_num       : IN    NATURAL;
552
                                   CONSTANT c_throttle_den       : IN    NATURAL;
553
                                   SIGNAL   rst                  : IN    STD_LOGIC;
554
                                   SIGNAL   clk                  : IN    STD_LOGIC;
555
                                   SIGNAL   sync_nr              : INOUT NATURAL;
556
                                   SIGNAL   block_nr             : INOUT NATURAL;
557
                                   SIGNAL   cnt_sync             : OUT   STD_LOGIC;
558
                                   SIGNAL   cnt_val              : OUT   STD_LOGIC;
559
                                   SIGNAL   cnt_dat              : INOUT STD_LOGIC_VECTOR) IS
560
    CONSTANT c_start_delay : NATURAL := 10;
561
    VARIABLE v_throttle    : NATURAL;
562
  BEGIN
563
    sync_nr  <= 0;
564
    block_nr <= 0;
565
 
566
    cnt_sync <= '0';
567
    cnt_val  <= '0';
568
    cnt_dat  <= (cnt_dat'RANGE=>'1');  -- -1, so first valid cnt_dat starts at 0
569
 
570
    -- allow some clock cycles before start after rst release
571
    WAIT UNTIL rst='0';
572
    FOR I IN 0 TO c_start_delay-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
573
 
574
    -- output first sync
575
    cnt_sync <= '1';
576
    WAIT UNTIL rising_edge(clk);
577
    cnt_sync <= '0';
578
    FOR I IN 1 TO c_gap_size-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
579
 
580
    WHILE TRUE LOOP
581
      -- output block
582
      IF c_throttle_num >= c_throttle_den THEN
583
        -- no need to throttle, so cnt_val active during whole data block
584
        FOR I IN 0 TO c_block_size-1 LOOP
585
          cnt_val <= '1';
586
          cnt_dat <= INCR_UVEC(cnt_dat, 1);
587
          WAIT UNTIL rising_edge(clk);
588
        END LOOP;
589
      ELSE
590
        -- throttle cnt_val, so c_throttle_num active cnt_val cycles per c_throttle_den cycles
591
        FOR I IN 0 TO c_block_size/c_throttle_num-1 LOOP
592
          FOR J IN 0 TO c_throttle_num-1 LOOP
593
            cnt_val <= '1';
594
            cnt_dat <= INCR_UVEC(cnt_dat, 1);
595
            WAIT UNTIL rising_edge(clk);
596
          END LOOP;
597
          FOR J IN 0 TO c_throttle_den-c_throttle_num-1 LOOP
598
            cnt_val <= '0';
599
            WAIT UNTIL rising_edge(clk);
600
          END LOOP;
601
        END LOOP;
602
      END IF;
603
      cnt_val <= '0';
604
      -- output sync for next block at first sample of gap
605
      IF block_nr>0 AND ((block_nr + 1) MOD c_nof_block_per_sync)=0 THEN
606
        cnt_sync <= '1';
607
        sync_nr  <= sync_nr+1;
608
      END IF;
609
      WAIT UNTIL rising_edge(clk);
610
      -- output rest of the gap
611
      cnt_sync <= '0';
612
      FOR I IN 1 TO c_gap_size-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
613
      -- next block
614
      block_nr <= block_nr+1;
615
    END LOOP;
616
  END proc_dp_gen_block_data;
617
 
618
 
619
  ------------------------------------------------------------------------------
620
  -- PROCEDURE: Block data generator with ready flow control and symbols counter
621
  -- . dependent on in_en and src_in.ready
622
  -- . optional sync pulse at end of frame 
623
  ------------------------------------------------------------------------------
624
  PROCEDURE proc_dp_gen_block_data(CONSTANT c_ready_latency  : IN  NATURAL;    -- 0, 1 are supported by proc_dp_stream_ready_latency()
625
                                   CONSTANT c_use_data       : IN  BOOLEAN;    -- when TRUE use data field, else use re, im fields, and keep unused fields at 'X'
626
                                   CONSTANT c_data_w         : IN  NATURAL;    -- data width for the data, re and im fields
627
                                   CONSTANT c_symbol_w       : IN  NATURAL;    -- c_data_w/c_symbol_w must be an integer
628
                                   CONSTANT c_symbol_init    : IN  NATURAL;    -- init counter for symbols in data field
629
                                   CONSTANT c_symbol_re_init : IN  NATURAL;    -- init counter for symbols in re field
630
                                   CONSTANT c_symbol_im_init : IN  NATURAL;    -- init counter for symbols in im field
631
                                   CONSTANT c_nof_symbols    : IN  NATURAL;    -- nof symbols per frame for the data, re and im fields
632
                                   CONSTANT c_channel        : IN  NATURAL;    -- channel field
633
                                   CONSTANT c_error          : IN  NATURAL;    -- error field
634
                                   CONSTANT c_sync           : IN  STD_LOGIC;  -- when '1' issue sync pulse during this block
635
                                   CONSTANT c_bsn            : IN  STD_LOGIC_VECTOR;  -- bsn field
636
                                   SIGNAL   clk              : IN  STD_LOGIC;
637
                                   SIGNAL   in_en            : IN  STD_LOGIC;  -- when '0' then no valid output even when src_in is ready
638
                                   SIGNAL   src_in           : IN  t_dp_siso;
639
                                   SIGNAL   src_out          : OUT t_dp_sosi) IS
640
    CONSTANT c_nof_symbols_per_data : NATURAL := c_data_w/c_symbol_w;
641
    CONSTANT c_div                  : NATURAL := c_nof_symbols   / c_nof_symbols_per_data;
642
    CONSTANT c_mod                  : NATURAL := c_nof_symbols MOD c_nof_symbols_per_data;
643
    CONSTANT c_empty                : NATURAL := sel_a_b(c_mod, c_nof_symbols_per_data - c_mod, 0);
644
    CONSTANT c_nof_data             : NATURAL := sel_a_b(c_mod, 1, 0) + c_div;
645
    VARIABLE v_data                 : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0):= func_dp_data_init(c_data_w, c_symbol_w, c_symbol_init);
646
    VARIABLE v_re                   : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0):= func_dp_data_init(c_data_w, c_symbol_w, c_symbol_re_init);
647
    VARIABLE v_im                   : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0):= func_dp_data_init(c_data_w, c_symbol_w, c_symbol_im_init);
648
  BEGIN
649
    src_out <= c_dp_sosi_rst;
650
    IF src_in.xon='1' THEN
651
      -- Generate this block
652
      src_out.bsn     <= RESIZE_DP_BSN(c_bsn);
653
      src_out.empty   <= TO_DP_EMPTY(c_empty);
654
      src_out.channel <= TO_DP_CHANNEL(c_channel);
655
      src_out.err     <= TO_DP_ERROR(c_error);
656
      IF c_use_data=TRUE  THEN src_out.data  <= RESIZE_DP_DATA(v_data);   END IF;
657
      IF c_use_data=FALSE THEN src_out.re    <= RESIZE_DP_DSP_DATA(v_re); END IF;
658
      IF c_use_data=FALSE THEN src_out.im    <= RESIZE_DP_DSP_DATA(v_im); END IF;
659
      IF c_nof_data>1 THEN
660
        -- . sop
661
        proc_dp_stream_ready_latency(c_ready_latency, clk, src_in.ready, in_en, c_sync, '1', '1', '0', src_out.sync, src_out.valid, src_out.sop, src_out.eop);
662
        -- . valid
663
        FOR I IN 1 TO c_nof_data-2 LOOP
664
          v_data := func_dp_data_incr(c_data_w, c_symbol_w, v_data);
665
          v_re   := func_dp_data_incr(c_data_w, c_symbol_w, v_re);
666
          v_im   := func_dp_data_incr(c_data_w, c_symbol_w, v_im);
667
          IF c_use_data=TRUE  THEN src_out.data <= RESIZE_DP_DATA(v_data);   END IF;
668
          IF c_use_data=FALSE THEN src_out.re   <= RESIZE_DP_DSP_DATA(v_re); END IF;
669
          IF c_use_data=FALSE THEN src_out.im   <= RESIZE_DP_DSP_DATA(v_im); END IF;
670
          proc_dp_stream_ready_latency(c_ready_latency, clk, src_in.ready, in_en, '0', '1', '0', '0', src_out.sync, src_out.valid, src_out.sop, src_out.eop);
671
        END LOOP;
672
 
673
        -- . eop
674
        v_data := func_dp_data_incr(c_data_w, c_symbol_w, v_data);
675
        v_re   := func_dp_data_incr(c_data_w, c_symbol_w, v_re);
676
        v_im   := func_dp_data_incr(c_data_w, c_symbol_w, v_im);
677
        IF c_use_data=TRUE  THEN src_out.data <= RESIZE_DP_DATA(v_data);   END IF;
678
        IF c_use_data=FALSE THEN src_out.re   <= RESIZE_DP_DSP_DATA(v_re); END IF;
679
        IF c_use_data=FALSE THEN src_out.im   <= RESIZE_DP_DSP_DATA(v_im); END IF;
680
        proc_dp_stream_ready_latency(c_ready_latency, clk, src_in.ready, in_en, '0', '1', '0', '1', src_out.sync, src_out.valid, src_out.sop, src_out.eop);
681
      ELSE
682
        -- . sop and eop, frame has only one word
683
        proc_dp_stream_ready_latency(c_ready_latency, clk, src_in.ready, in_en, c_sync, '1', '1', '1', src_out.sync, src_out.valid, src_out.sop, src_out.eop);
684
      END IF;
685
    ELSE
686
      -- Skip this block
687
      proc_common_wait_some_cycles(clk, c_nof_data);
688
    END IF;
689
  END proc_dp_gen_block_data;
690
 
691
 
692
  PROCEDURE proc_dp_gen_block_data(CONSTANT c_data_w         : IN  NATURAL;    -- data width for the data field
693
                                   CONSTANT c_symbol_init    : IN  NATURAL;    -- init counter for the data in the data field
694
                                   CONSTANT c_nof_symbols    : IN  NATURAL;    -- nof symbols per frame for the data fields
695
                                   CONSTANT c_channel        : IN  NATURAL;    -- channel field
696
                                   CONSTANT c_error          : IN  NATURAL;    -- error field
697
                                   CONSTANT c_sync           : IN  STD_LOGIC;  -- when '1' issue sync pulse during this block
698
                                   CONSTANT c_bsn            : IN  STD_LOGIC_VECTOR;  -- bsn field
699
                                   SIGNAL   clk              : IN  STD_LOGIC;
700
                                   SIGNAL   in_en            : IN  STD_LOGIC;  -- when '0' then no valid output even when src_in is ready
701
                                   SIGNAL   src_in           : IN  t_dp_siso;
702
                                   SIGNAL   src_out          : OUT t_dp_sosi) IS
703
  BEGIN
704
    proc_dp_gen_block_data(1, TRUE, c_data_w, c_data_w, c_symbol_init, 0, 0, c_nof_symbols, c_channel, c_error, c_sync, c_bsn, clk, in_en, src_in, src_out);
705
  END proc_dp_gen_block_data;
706
 
707
 
708
  ------------------------------------------------------------------------------
709
  -- PROCEDURE: Handle stream ready signal
710
  -- . output active when src_in is ready and in_en='1'
711
  -- . only support RL=0 or 1, support for RL>1 requires keeping previous ready information in a STD_LOGIC_VECTOR(RL-1 DOWNTO 0).
712
  ------------------------------------------------------------------------------
713
  PROCEDURE proc_dp_stream_ready_latency(CONSTANT c_latency : IN  NATURAL;
714
                                         SIGNAL   clk       : IN  STD_LOGIC;
715
                                         SIGNAL   ready     : IN  STD_LOGIC;
716
                                         SIGNAL   in_en     : IN  STD_LOGIC;
717
                                         CONSTANT c_sync    : IN  STD_LOGIC;
718
                                         CONSTANT c_valid   : IN  STD_LOGIC;
719
                                         CONSTANT c_sop     : IN  STD_LOGIC;
720
                                         CONSTANT c_eop     : IN  STD_LOGIC;
721
                                         SIGNAL   out_sync  : OUT STD_LOGIC;
722
                                         SIGNAL   out_valid : OUT STD_LOGIC;
723
                                         SIGNAL   out_sop   : OUT STD_LOGIC;
724
                                         SIGNAL   out_eop   : OUT STD_LOGIC) IS
725
  BEGIN
726
    -- Default no output
727
    out_sync  <= '0';
728
    out_valid <= '0';
729
    out_sop   <= '0';
730
    out_eop   <= '0';
731
 
732
    -- Skip cycles until in_en='1'
733
    WHILE in_en='0' LOOP
734
      WAIT UNTIL rising_edge(clk);
735
    END LOOP;
736
 
737
    -- Active output when ready
738
    -- . RL = 0
739
    IF c_latency=0 THEN
740
      -- show the available output until acknowledge
741
      out_sync  <= c_sync;
742
      out_valid <= c_valid;
743
      out_sop   <= c_sop;
744
      out_eop   <= c_eop;
745
      WAIT UNTIL rising_edge(clk);
746
      WHILE ready /= '1' LOOP
747
        WAIT UNTIL rising_edge(clk);
748
      END LOOP;
749
      -- ready has acknowledged the valid output
750
    END IF;
751
 
752
    -- . RL = 1
753
    IF c_latency=1 THEN
754
      -- no valid output until request
755
      WHILE ready /= '1' LOOP
756
        WAIT UNTIL rising_edge(clk);
757
      END LOOP;
758
      -- ready has requested this valid output
759
      out_sync  <= c_sync;
760
      out_valid <= c_valid;
761
      out_sop   <= c_sop;
762
      out_eop   <= c_eop;
763
      WAIT UNTIL rising_edge(clk);
764
    END IF;
765
 
766
    -- Return with no active output
767
    out_sync  <= '0';
768
    out_valid <= '0';
769
    out_sop   <= '0';
770
    out_eop   <= '0';
771
  END proc_dp_stream_ready_latency;
772
 
773
 
774
  ------------------------------------------------------------------------------
775
  -- FUNCTION: Initialize the data per symbol
776
  -- . use big endian
777
  -- . if c_data_w=32, c_symbol_w=8, init=3 then return 0x03040506
778
  ------------------------------------------------------------------------------
779
  FUNCTION func_dp_data_init(c_data_w, c_symbol_w, init : NATURAL) RETURN STD_LOGIC_VECTOR IS
780
    CONSTANT c_nof_symbols_per_data : NATURAL := c_data_w/c_symbol_w;
781
    VARIABLE v_data                 : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0);
782
    VARIABLE v_sym                  : STD_LOGIC_VECTOR(c_symbol_w-1 DOWNTO 0);
783
  BEGIN
784
    v_data := (OTHERS=>'0');
785
    v_sym  := TO_UVEC(init, c_symbol_w);
786
    FOR I IN c_nof_symbols_per_data-1 DOWNTO 0 LOOP
787
      v_data((I+1)*c_symbol_w-1 DOWNTO I*c_symbol_w) := v_sym;
788
      v_sym := INCR_UVEC(v_sym, 1);
789
    END LOOP;
790
    RETURN v_data;
791
  END func_dp_data_init;
792
 
793
 
794
  ------------------------------------------------------------------------------
795
  -- FUNCTION: Increment the data per symbol
796
  -- . use big endian
797
  -- . if c_data_w=32, c_symbol_w=8 then 0x00010203 returns 0x04050607
798
  -- . the actual data'LENGTH must be >= c_data_w, unused bits become 0
799
  -- . c_data_w/c_symbol_w must be an integer
800
  ------------------------------------------------------------------------------
801
  FUNCTION func_dp_data_incr(c_data_w, c_symbol_w : NATURAL; data : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
802
    CONSTANT c_nof_symbols_per_data : NATURAL := c_data_w/c_symbol_w;
803
    VARIABLE v_data                 : STD_LOGIC_VECTOR(data'LENGTH-1 DOWNTO 0);
804
    VARIABLE v_sym                  : STD_LOGIC_VECTOR(c_symbol_w-1 DOWNTO 0);
805
  BEGIN
806
    v_data := (OTHERS=>'0');
807
    v_sym  := data(c_symbol_w-1 DOWNTO 0);
808
    FOR I IN c_nof_symbols_per_data-1 DOWNTO 0 LOOP
809
      v_sym := INCR_UVEC(v_sym, 1);
810
      v_data((I+1)*c_symbol_w-1 DOWNTO I*c_symbol_w) := v_sym;
811
    END LOOP;
812
    RETURN v_data;
813
  END func_dp_data_incr;
814
 
815
 
816
  ------------------------------------------------------------------------------
817
  -- PROCEDURE: Generate counter data with valid
818
  -- . Output counter data dependent on in_en and src_in.ready
819
  ------------------------------------------------------------------------------
820
  PROCEDURE proc_dp_gen_data(CONSTANT c_ready_latency : IN  NATURAL;    -- 0, 1 are supported by proc_dp_stream_ready_latency()
821
                             CONSTANT c_data_w        : IN  NATURAL;
822
                             CONSTANT c_data_init     : IN  NATURAL;
823
                             SIGNAL   rst             : IN  STD_LOGIC;
824
                             SIGNAL   clk             : IN  STD_LOGIC;
825
                             SIGNAL   in_en           : IN  STD_LOGIC;  -- when '0' then no valid output even when src_in is ready
826
                             SIGNAL   src_in          : IN  t_dp_siso;
827
                             SIGNAL   src_out         : OUT t_dp_sosi) IS
828
    VARIABLE v_data : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0):= TO_UVEC(c_data_init, c_data_w);
829
  BEGIN
830
    src_out      <= c_dp_sosi_rst;
831
    src_out.data <= RESIZE_DP_DATA(v_data);
832
    IF rst='0' THEN
833
      WAIT UNTIL rising_edge(clk);
834
      WHILE TRUE LOOP
835
        src_out.data <= RESIZE_DP_DATA(v_data);
836
        proc_dp_stream_ready_latency(c_ready_latency, clk, src_in.ready, in_en, '0', '1', '0', '0', src_out.sync, src_out.valid, src_out.sop, src_out.eop);
837
        v_data := INCR_UVEC(v_data, 1);
838
      END LOOP;
839
    END IF;
840
  END proc_dp_gen_data;
841
 
842
 
843
  ------------------------------------------------------------------------------
844
  -- PROCEDURE: Generate counter data with valid
845
  -- . Output counter data dependent on in_en and src_in.ready
846
  -- . with maximum count value
847
  ------------------------------------------------------------------------------
848
  PROCEDURE proc_dp_gen_data(CONSTANT c_ready_latency   : IN  NATURAL;
849
                             CONSTANT c_data_w          : IN  NATURAL;
850
                             CONSTANT c_data_init       : IN  NATURAL;
851
                             CONSTANT c_data_max        : IN  NATURAL;
852
                             SIGNAL   rst               : IN  STD_LOGIC;
853
                             SIGNAL   clk               : IN  STD_LOGIC;
854
                             SIGNAL   in_en             : IN  STD_LOGIC;  -- when '0' then no valid output even when src_in is ready
855
                             SIGNAL   src_in            : IN  t_dp_siso;
856
                             SIGNAL   src_out           : OUT t_dp_sosi) IS
857
    VARIABLE v_cnt     : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0):= TO_UVEC(c_data_init, c_data_w);
858
  BEGIN
859
    src_out         <= c_dp_sosi_rst;
860
    src_out.data    <= RESIZE_DP_DATA(v_cnt);
861
    IF rst='0' THEN
862
      WAIT UNTIL rising_edge(clk);
863
      WHILE TRUE LOOP
864
        src_out.data    <= RESIZE_DP_DATA(v_cnt);
865
        proc_dp_stream_ready_latency(c_ready_latency, clk, src_in.ready, in_en, '0', '1', '0', '0', src_out.sync, src_out.valid, src_out.sop, src_out.eop);
866
        IF TO_UINT(v_cnt)=c_data_max THEN
867
          v_cnt := TO_UVEC(c_data_init, c_data_w);
868
        ELSE
869
          v_cnt := INCR_UVEC(v_cnt, 1);
870
        END IF;
871
      END LOOP;
872
    END IF;
873
  END proc_dp_gen_data;
874
 
875
 
876
  ------------------------------------------------------------------------------
877
  -- PROCEDURE: Generate a frame with symbols counter
878
  -- . dependent on in_en and src_in.ready
879
  ------------------------------------------------------------------------------
880
  PROCEDURE proc_dp_gen_frame(CONSTANT c_ready_latency : IN  NATURAL;    -- 0, 1 are supported by proc_dp_stream_ready_latency()
881
                              CONSTANT c_data_w        : IN  NATURAL;
882
                              CONSTANT c_symbol_w      : IN  NATURAL;    -- c_data_w/c_symbol_w must be an integer
883
                              CONSTANT c_symbol_init   : IN  NATURAL;
884
                              CONSTANT c_nof_symbols   : IN  NATURAL;
885
                              CONSTANT c_bsn           : IN  NATURAL;
886
                              CONSTANT c_sync          : IN  STD_LOGIC;
887
                              SIGNAL   clk             : IN  STD_LOGIC;
888
                              SIGNAL   in_en           : IN  STD_LOGIC;  -- when '0' then no valid output even when src_in is ready
889
                              SIGNAL   src_in          : IN  t_dp_siso;
890
                              SIGNAL   src_out         : OUT t_dp_sosi) IS
891
    CONSTANT c_nof_symbols_per_data : NATURAL := c_data_w/c_symbol_w;
892
    CONSTANT c_div                  : NATURAL := c_nof_symbols   / c_nof_symbols_per_data;
893
    CONSTANT c_mod                  : NATURAL := c_nof_symbols MOD c_nof_symbols_per_data;
894
    CONSTANT c_empty                : NATURAL := sel_a_b(c_mod, c_nof_symbols_per_data - c_mod, 0);
895
    CONSTANT c_nof_data             : NATURAL := sel_a_b(c_mod, 1, 0) + c_div;
896
    VARIABLE v_data                 : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0):= func_dp_data_init(c_data_w, c_symbol_w, c_symbol_init);
897
  BEGIN
898
    src_out       <= c_dp_sosi_rst;
899
    src_out.bsn   <= TO_DP_BSN(c_bsn);
900
    src_out.empty <= TO_DP_EMPTY(c_empty);
901
    src_out.data  <= RESIZE_DP_DATA(v_data);
902
    IF c_nof_data>1 THEN
903
      -- . sop
904
      proc_dp_stream_ready_latency(c_ready_latency, clk, src_in.ready, in_en, c_sync, '1', '1', '0', src_out.sync, src_out.valid, src_out.sop, src_out.eop);
905
      -- . valid
906
      FOR I IN 1 TO c_nof_data-2 LOOP
907
        v_data := func_dp_data_incr(c_data_w, c_symbol_w, v_data);
908
        src_out.data <= RESIZE_DP_DATA(v_data);
909
        proc_dp_stream_ready_latency(c_ready_latency, clk, src_in.ready, in_en, '0', '1', '0', '0', src_out.sync, src_out.valid, src_out.sop, src_out.eop);
910
      END LOOP;
911
      -- . eop
912
      v_data := func_dp_data_incr(c_data_w, c_symbol_w, v_data);
913
      src_out.data <= RESIZE_DP_DATA(v_data);
914
      proc_dp_stream_ready_latency(c_ready_latency, clk, src_in.ready, in_en, '0', '1', '0', '1', src_out.sync, src_out.valid, src_out.sop, src_out.eop);
915
    ELSE
916
      -- . sop and eop, frame has only one word
917
      proc_dp_stream_ready_latency(c_ready_latency, clk, src_in.ready, in_en, c_sync, '1', '1', '1', src_out.sync, src_out.valid, src_out.sop, src_out.eop);
918
    END IF;
919
    src_out.sync  <= '0';
920
    src_out.valid <= '0';
921
    src_out.sop   <= '0';
922
    src_out.eop   <= '0';
923
  END proc_dp_gen_frame;
924
 
925
 
926
  ------------------------------------------------------------------------------
927
  -- PROCEDURE: Input data counter
928
  ------------------------------------------------------------------------------
929
  PROCEDURE proc_dp_cnt_dat(SIGNAL rst     : IN    STD_LOGIC;
930
                            SIGNAL clk     : IN    STD_LOGIC;
931
                            SIGNAL in_en   : IN    STD_LOGIC;
932
                            SIGNAL cnt_dat : INOUT STD_LOGIC_VECTOR) IS
933
  BEGIN
934
    IF rst='1' THEN
935
      cnt_dat <= (cnt_dat'RANGE=>'0');
936
    ELSIF rising_edge(clk) THEN
937
      IF in_en='1' THEN
938
        cnt_dat <= STD_LOGIC_VECTOR(UNSIGNED(cnt_dat)+1);
939
      END IF;
940
    END IF;
941
  END proc_dp_cnt_dat;
942
 
943
  PROCEDURE proc_dp_cnt_dat(SIGNAL rst     : IN    STD_LOGIC;
944
                            SIGNAL clk     : IN    STD_LOGIC;
945
                            SIGNAL in_en   : IN    STD_LOGIC;
946
                            SIGNAL cnt_val : INOUT STD_LOGIC;
947
                            SIGNAL cnt_dat : INOUT STD_LOGIC_VECTOR) IS
948
  BEGIN
949
    IF rst='1' THEN
950
      cnt_val <= '0';
951
      cnt_dat <= (cnt_dat'RANGE=>'0');
952
    ELSIF rising_edge(clk) THEN
953
      cnt_val <= '0';
954
      IF in_en='1' THEN
955
        cnt_val <= '1';
956
        cnt_dat <= STD_LOGIC_VECTOR(UNSIGNED(cnt_dat)+1);
957
      END IF;
958
    END IF;
959
  END proc_dp_cnt_dat;
960
 
961
  ------------------------------------------------------------------------------
962
  -- PROCEDURE: Transmit data
963
  ------------------------------------------------------------------------------
964
  PROCEDURE proc_dp_tx_data(CONSTANT c_ready_latency : IN    NATURAL;
965
                            SIGNAL   rst             : IN    STD_LOGIC;
966
                            SIGNAL   clk             : IN    STD_LOGIC;
967
                            SIGNAL   cnt_val         : IN    STD_LOGIC;
968
                            SIGNAL   cnt_dat         : IN    STD_LOGIC_VECTOR;
969
                            SIGNAL   tx_data         : INOUT t_dp_data_arr;
970
                            SIGNAL   tx_val          : INOUT STD_LOGIC_VECTOR;
971
                            SIGNAL   out_data        : OUT   STD_LOGIC_VECTOR;
972
                            SIGNAL   out_val         : OUT   STD_LOGIC) IS
973
    CONSTANT c_void : NATURAL := sel_a_b(c_ready_latency, 1, 0);  -- used to avoid empty range VHDL warnings when c_ready_latency=0
974
  BEGIN
975
    -- TX data array for output ready latency [c_ready_latency], index [0] for zero latency combinatorial
976
    tx_data(0) <= cnt_dat;
977
    tx_val( 0) <= cnt_val;
978
 
979
    IF rst='1' THEN
980
      tx_data(1 TO c_ready_latency+c_void) <= (1 TO c_ready_latency+c_void=>(OTHERS=>'0'));
981
      tx_val( 1 TO c_ready_latency+c_void) <= (1 TO c_ready_latency+c_void=>'0');
982
    ELSIF rising_edge(clk) THEN
983
      tx_data(1 TO c_ready_latency+c_void) <= tx_data(0 TO c_ready_latency+c_void-1);
984
      tx_val( 1 TO c_ready_latency+c_void) <= tx_val( 0 TO c_ready_latency+c_void-1);
985
    END IF;
986
 
987
    out_data <= tx_data(c_ready_latency);
988
    out_val  <= tx_val(c_ready_latency);
989
  END proc_dp_tx_data;
990
 
991
 
992
  ------------------------------------------------------------------------------
993
  -- PROCEDURE: Transmit data control (use for sop, eop)
994
  ------------------------------------------------------------------------------
995
  PROCEDURE proc_dp_tx_ctrl(CONSTANT c_offset : IN  NATURAL;
996
                            CONSTANT c_period : IN  NATURAL;
997
                            SIGNAL   data     : IN  STD_LOGIC_VECTOR;
998
                            SIGNAL   valid    : IN  STD_LOGIC;
999
                            SIGNAL   ctrl     : OUT STD_LOGIC) IS
1000
    VARIABLE v_data : INTEGER;
1001
  BEGIN
1002
    v_data := TO_UINT(data);
1003
    ctrl <= '0';
1004
    IF valid='1' AND ((v_data-c_offset) MOD c_period)=0 THEN
1005
      ctrl <= '1';
1006
    END IF;
1007
  END proc_dp_tx_ctrl;
1008
 
1009
 
1010
  ------------------------------------------------------------------------------
1011
  -- PROCEDURE: Define test sync interval
1012
  ------------------------------------------------------------------------------
1013
  PROCEDURE proc_dp_sync_interval(SIGNAL clk  : IN  STD_LOGIC;
1014
                                  SIGNAL sync : OUT STD_LOGIC) IS
1015
  BEGIN
1016
    sync <= '0';
1017
    FOR I IN 1 TO c_dp_sync_interval-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1018
    sync <= '1';
1019
    WAIT UNTIL rising_edge(clk);
1020
  END proc_dp_sync_interval;
1021
 
1022
 
1023
  ------------------------------------------------------------------------------
1024
  -- PROCEDURE: Stimuli for cnt_en
1025
  ------------------------------------------------------------------------------
1026
  PROCEDURE proc_dp_count_en(SIGNAL rst    : IN    STD_LOGIC;
1027
                             SIGNAL clk    : IN    STD_LOGIC;
1028
                             SIGNAL sync   : IN    STD_LOGIC;
1029
                             SIGNAL lfsr   : INOUT STD_LOGIC_VECTOR;
1030
                             SIGNAL state  : OUT   t_dp_state_enum;
1031
                             SIGNAL done   : OUT   STD_LOGIC;
1032
                             SIGNAL tb_end : OUT   STD_LOGIC;
1033
                             SIGNAL cnt_en : OUT   STD_LOGIC) IS
1034
  BEGIN
1035
    -- The counter operates at zero latency
1036
    state <= s_idle;
1037
    done <= '0';
1038
    tb_end <= '0';
1039
    cnt_en <= '0';
1040
    WAIT UNTIL rst='0';
1041
    WAIT UNTIL rising_edge(clk);
1042
    -- The cnt_val may be asserted for every active in_ready, but als support
1043
    -- cnt_val not asserted for every asserted in_ready.
1044
 
1045
    ----------------------------------------------------------------------------
1046
    -- Interval 1
1047
    ----------------------------------------------------------------------------
1048
    WAIT UNTIL sync='1';
1049
    state <= s_both_active;
1050
    cnt_en <= '1';
1051
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1052
 
1053
    ----------------------------------------------------------------------------
1054
    -- Interval 2
1055
    ----------------------------------------------------------------------------
1056
    WAIT UNTIL sync='1';
1057
    state <= s_pull_down_out_ready;
1058
    cnt_en <= '1';
1059
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1060
 
1061
    ----------------------------------------------------------------------------
1062
    -- Interval 3
1063
    ----------------------------------------------------------------------------
1064
    WAIT UNTIL sync='1';
1065
    state <= s_pull_down_cnt_en;
1066
    cnt_en <= '1';
1067
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1068
 
1069
    -- . 1 cycle
1070
    cnt_en <= '0';
1071
    WAIT UNTIL rising_edge(clk);
1072
    cnt_en <= '1';
1073
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1074
 
1075
    -- . 2 cycle
1076
    cnt_en <= '0';
1077
    WAIT UNTIL rising_edge(clk);
1078
    WAIT UNTIL rising_edge(clk);
1079
    cnt_en <= '1';
1080
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1081
 
1082
    -- . 3 cycle
1083
    cnt_en <= '0';
1084
    WAIT UNTIL rising_edge(clk);
1085
    WAIT UNTIL rising_edge(clk);
1086
    WAIT UNTIL rising_edge(clk);
1087
    cnt_en <= '1';
1088
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1089
 
1090
    -- . 4 cycle
1091
    cnt_en <= '0';
1092
    WAIT UNTIL rising_edge(clk);
1093
    WAIT UNTIL rising_edge(clk);
1094
    WAIT UNTIL rising_edge(clk);
1095
    WAIT UNTIL rising_edge(clk);
1096
    cnt_en <= '1';
1097
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1098
 
1099
    -- . 5 cycle
1100
    cnt_en <= '0';
1101
    WAIT UNTIL rising_edge(clk);
1102
    WAIT UNTIL rising_edge(clk);
1103
    WAIT UNTIL rising_edge(clk);
1104
    WAIT UNTIL rising_edge(clk);
1105
    WAIT UNTIL rising_edge(clk);
1106
    cnt_en <= '1';
1107
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1108
 
1109
    -- . 6 cycle
1110
    cnt_en <= '0';
1111
    WAIT UNTIL rising_edge(clk);
1112
    WAIT UNTIL rising_edge(clk);
1113
    WAIT UNTIL rising_edge(clk);
1114
    WAIT UNTIL rising_edge(clk);
1115
    WAIT UNTIL rising_edge(clk);
1116
    WAIT UNTIL rising_edge(clk);
1117
    cnt_en <= '1';
1118
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1119
 
1120
    -- . 7 cycle
1121
    cnt_en <= '0';
1122
    WAIT UNTIL rising_edge(clk);
1123
    WAIT UNTIL rising_edge(clk);
1124
    WAIT UNTIL rising_edge(clk);
1125
    WAIT UNTIL rising_edge(clk);
1126
    WAIT UNTIL rising_edge(clk);
1127
    WAIT UNTIL rising_edge(clk);
1128
    WAIT UNTIL rising_edge(clk);
1129
    cnt_en <= '1';
1130
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1131
 
1132
    ----------------------------------------------------------------------------
1133
    -- Interval 4
1134
    ----------------------------------------------------------------------------
1135
    WAIT UNTIL sync='1';
1136
    state <= s_toggle_out_ready;
1137
    cnt_en <= '1';
1138
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1139
 
1140
    ----------------------------------------------------------------------------
1141
    -- Interval 5
1142
    ----------------------------------------------------------------------------
1143
    WAIT UNTIL sync='1';
1144
    state <= s_toggle_cnt_en;
1145
    cnt_en <= '1';
1146
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1147
 
1148
    -- . 1-1 toggle
1149
    cnt_en <= '0';
1150
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1151
      WAIT UNTIL rising_edge(clk);
1152
      cnt_en <= '0';
1153
      WAIT UNTIL rising_edge(clk);
1154
      cnt_en <= '1';
1155
    END LOOP;
1156
    cnt_en <= '1';
1157
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1158
 
1159
    -- . 1-2 toggle
1160
    cnt_en <= '0';
1161
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1162
      WAIT UNTIL rising_edge(clk);
1163
      cnt_en <= '0';
1164
      WAIT UNTIL rising_edge(clk);
1165
      WAIT UNTIL rising_edge(clk);
1166
      cnt_en <= '1';
1167
    END LOOP;
1168
    cnt_en <= '1';
1169
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1170
 
1171
    -- . 2-1 toggle
1172
    cnt_en <= '0';
1173
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1174
      WAIT UNTIL rising_edge(clk);
1175
      WAIT UNTIL rising_edge(clk);
1176
      cnt_en <= '0';
1177
      WAIT UNTIL rising_edge(clk);
1178
      cnt_en <= '1';
1179
    END LOOP;
1180
    cnt_en <= '1';
1181
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1182
 
1183
    -- . 2-2 toggle
1184
    cnt_en <= '0';
1185
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1186
      WAIT UNTIL rising_edge(clk);
1187
      WAIT UNTIL rising_edge(clk);
1188
      cnt_en <= '0';
1189
      WAIT UNTIL rising_edge(clk);
1190
      WAIT UNTIL rising_edge(clk);
1191
      cnt_en <= '1';
1192
    END LOOP;
1193
    cnt_en <= '1';
1194
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1195
 
1196
    -- . 1-3 toggle
1197
    cnt_en <= '0';
1198
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1199
      WAIT UNTIL rising_edge(clk);
1200
      cnt_en <= '0';
1201
      WAIT UNTIL rising_edge(clk);
1202
      WAIT UNTIL rising_edge(clk);
1203
      WAIT UNTIL rising_edge(clk);
1204
      cnt_en <= '1';
1205
    END LOOP;
1206
    cnt_en <= '1';
1207
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1208
 
1209
    -- . 3-1 toggle
1210
    cnt_en <= '0';
1211
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1212
      WAIT UNTIL rising_edge(clk);
1213
      WAIT UNTIL rising_edge(clk);
1214
      WAIT UNTIL rising_edge(clk);
1215
      cnt_en <= '0';
1216
      WAIT UNTIL rising_edge(clk);
1217
      cnt_en <= '1';
1218
    END LOOP;
1219
    cnt_en <= '1';
1220
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1221
 
1222
    -- . 2-3 toggle
1223
    cnt_en <= '0';
1224
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1225
      WAIT UNTIL rising_edge(clk);
1226
      WAIT UNTIL rising_edge(clk);
1227
      cnt_en <= '0';
1228
      WAIT UNTIL rising_edge(clk);
1229
      WAIT UNTIL rising_edge(clk);
1230
      WAIT UNTIL rising_edge(clk);
1231
      cnt_en <= '1';
1232
    END LOOP;
1233
    cnt_en <= '1';
1234
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1235
 
1236
    -- . 3-2 toggle
1237
    cnt_en <= '0';
1238
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1239
      WAIT UNTIL rising_edge(clk);
1240
      WAIT UNTIL rising_edge(clk);
1241
      WAIT UNTIL rising_edge(clk);
1242
      cnt_en <= '0';
1243
      WAIT UNTIL rising_edge(clk);
1244
      WAIT UNTIL rising_edge(clk);
1245
      cnt_en <= '1';
1246
    END LOOP;
1247
    cnt_en <= '1';
1248
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1249
 
1250
    ----------------------------------------------------------------------------
1251
    -- Interval 6
1252
    ----------------------------------------------------------------------------
1253
    WAIT UNTIL sync='1';
1254
    state <= s_toggle_both;
1255
    cnt_en <= '1';
1256
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1257
 
1258
    FOR I IN 1 TO c_dp_nof_both LOOP
1259
      cnt_en <= '0';
1260
      FOR J IN 1 TO I LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1261
      cnt_en <= '1';
1262
      FOR J IN I TO c_dp_nof_both LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1263
    END LOOP;
1264
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1265
 
1266
    ----------------------------------------------------------------------------
1267
    -- Interval 7
1268
    ----------------------------------------------------------------------------
1269
    WAIT UNTIL sync='1';
1270
    state <= s_pulse_cnt_en;
1271
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1272
 
1273
    FOR I IN 1 TO 15 LOOP
1274
      FOR J IN 1 TO 15 LOOP
1275
        cnt_en <= '0';
1276
        FOR K IN 1 TO I LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1277
        cnt_en <= '1';
1278
        WAIT UNTIL rising_edge(clk);
1279
      END LOOP;
1280
      FOR J IN 1 TO 20 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1281
    END LOOP;
1282
    cnt_en <= '1';
1283
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1284
 
1285
    ----------------------------------------------------------------------------
1286
    -- Interval 8
1287
    ----------------------------------------------------------------------------
1288
    WAIT UNTIL sync='1';
1289
    state <= s_chirp_out_ready;
1290
    cnt_en <= '1';
1291
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1292
 
1293
    ----------------------------------------------------------------------------
1294
    -- Interval 9
1295
    ----------------------------------------------------------------------------
1296
    WAIT UNTIL sync='1';
1297
    state <= s_random;
1298
    cnt_en <= '1';
1299
 
1300
    FOR I IN 0 TO c_dp_sync_interval - c_dp_test_interval LOOP
1301
      lfsr <= func_common_random(lfsr);
1302
      cnt_en <= lfsr(lfsr'HIGH);
1303
      WAIT UNTIL rising_edge(clk);
1304
    END LOOP;
1305
 
1306
    ----------------------------------------------------------------------------
1307
    -- Done
1308
    ----------------------------------------------------------------------------
1309
    WAIT UNTIL sync='1';
1310
    state <= s_done;
1311
    WAIT UNTIL rising_edge(clk);
1312
    cnt_en <= '0';
1313
 
1314
    -- pulse done
1315
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1316
    done <= '1';
1317
    WAIT UNTIL rising_edge(clk);
1318
    done <= '0';
1319
 
1320
    ----------------------------------------------------------------------------
1321
    -- Testbench end
1322
    ----------------------------------------------------------------------------
1323
    -- set tb_end
1324
    WAIT UNTIL sync='1';
1325
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1326
    tb_end <= '1';
1327
    WAIT;
1328
  END proc_dp_count_en;
1329
 
1330
 
1331
  ------------------------------------------------------------------------------
1332
  -- PROCEDURE: Stimuli for out_ready
1333
  ------------------------------------------------------------------------------
1334
  PROCEDURE proc_dp_out_ready(SIGNAL rst       : IN    STD_LOGIC;
1335
                              SIGNAL clk       : IN    STD_LOGIC;
1336
                              SIGNAL sync      : IN    STD_LOGIC;
1337
                              SIGNAL lfsr      : INOUT STD_LOGIC_VECTOR;
1338
                              SIGNAL out_ready : OUT   STD_LOGIC) IS
1339
  BEGIN
1340
    out_ready <= '0';
1341
    WAIT UNTIL rst='0';
1342
    WAIT UNTIL rising_edge(clk);
1343
 
1344
    ----------------------------------------------------------------------------
1345
    -- Interval 1 : Assert both cnt_en and out_ready
1346
    ----------------------------------------------------------------------------
1347
    WAIT UNTIL sync='1';
1348
    out_ready <= '1';
1349
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1350
 
1351
    ----------------------------------------------------------------------------
1352
    -- Interval 2 : Make out_ready low for 1 or more cycles
1353
    ----------------------------------------------------------------------------
1354
    WAIT UNTIL sync='1';
1355
    out_ready <= '1';
1356
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1357
 
1358
    -- . 1 cycle
1359
    out_ready <= '0';
1360
    WAIT UNTIL rising_edge(clk);
1361
    out_ready <= '1';
1362
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1363
 
1364
    -- . 2 cycle
1365
    out_ready <= '0';
1366
    WAIT UNTIL rising_edge(clk);
1367
    WAIT UNTIL rising_edge(clk);
1368
    out_ready <= '1';
1369
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1370
 
1371
    -- . 3 cycle
1372
    out_ready <= '0';
1373
    WAIT UNTIL rising_edge(clk);
1374
    WAIT UNTIL rising_edge(clk);
1375
    WAIT UNTIL rising_edge(clk);
1376
    out_ready <= '1';
1377
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1378
 
1379
    -- . 4 cycle
1380
    out_ready <= '0';
1381
    WAIT UNTIL rising_edge(clk);
1382
    WAIT UNTIL rising_edge(clk);
1383
    WAIT UNTIL rising_edge(clk);
1384
    WAIT UNTIL rising_edge(clk);
1385
    out_ready <= '1';
1386
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1387
 
1388
    -- . 5 cycle
1389
    out_ready <= '0';
1390
    WAIT UNTIL rising_edge(clk);
1391
    WAIT UNTIL rising_edge(clk);
1392
    WAIT UNTIL rising_edge(clk);
1393
    WAIT UNTIL rising_edge(clk);
1394
    WAIT UNTIL rising_edge(clk);
1395
    out_ready <= '1';
1396
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1397
 
1398
    -- . 6 cycle
1399
    out_ready <= '0';
1400
    WAIT UNTIL rising_edge(clk);
1401
    WAIT UNTIL rising_edge(clk);
1402
    WAIT UNTIL rising_edge(clk);
1403
    WAIT UNTIL rising_edge(clk);
1404
    WAIT UNTIL rising_edge(clk);
1405
    WAIT UNTIL rising_edge(clk);
1406
    out_ready <= '1';
1407
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1408
 
1409
    -- . 7 cycle
1410
    out_ready <= '0';
1411
    WAIT UNTIL rising_edge(clk);
1412
    WAIT UNTIL rising_edge(clk);
1413
    WAIT UNTIL rising_edge(clk);
1414
    WAIT UNTIL rising_edge(clk);
1415
    WAIT UNTIL rising_edge(clk);
1416
    WAIT UNTIL rising_edge(clk);
1417
    WAIT UNTIL rising_edge(clk);
1418
    out_ready <= '1';
1419
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1420
 
1421
    ----------------------------------------------------------------------------
1422
    -- Interval 3
1423
    ----------------------------------------------------------------------------
1424
    WAIT UNTIL sync='1';
1425
    out_ready <= '1';
1426
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1427
 
1428
    ----------------------------------------------------------------------------
1429
    -- Interval 4 : Toggle out_ready for 1 or more cycles
1430
    ----------------------------------------------------------------------------
1431
    WAIT UNTIL sync='1';
1432
    out_ready <= '1';
1433
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1434
 
1435
    -- . 1-1 toggle
1436
    out_ready <= '0';
1437
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1438
      WAIT UNTIL rising_edge(clk);
1439
      out_ready <= '0';
1440
      WAIT UNTIL rising_edge(clk);
1441
      out_ready <= '1';
1442
    END LOOP;
1443
    out_ready <= '1';
1444
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1445
 
1446
    -- . 1-2 toggle
1447
    out_ready <= '0';
1448
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1449
      WAIT UNTIL rising_edge(clk);
1450
      out_ready <= '0';
1451
      WAIT UNTIL rising_edge(clk);
1452
      WAIT UNTIL rising_edge(clk);
1453
      out_ready <= '1';
1454
    END LOOP;
1455
    out_ready <= '1';
1456
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1457
 
1458
    -- . 2-1 toggle
1459
    out_ready <= '0';
1460
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1461
      WAIT UNTIL rising_edge(clk);
1462
      WAIT UNTIL rising_edge(clk);
1463
      out_ready <= '0';
1464
      WAIT UNTIL rising_edge(clk);
1465
      out_ready <= '1';
1466
    END LOOP;
1467
    out_ready <= '1';
1468
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1469
 
1470
    -- . 2-2 toggle
1471
    out_ready <= '0';
1472
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1473
      WAIT UNTIL rising_edge(clk);
1474
      WAIT UNTIL rising_edge(clk);
1475
      out_ready <= '0';
1476
      WAIT UNTIL rising_edge(clk);
1477
      WAIT UNTIL rising_edge(clk);
1478
      out_ready <= '1';
1479
    END LOOP;
1480
    out_ready <= '1';
1481
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1482
 
1483
    -- . 1-3 toggle
1484
    out_ready <= '0';
1485
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1486
      WAIT UNTIL rising_edge(clk);
1487
      out_ready <= '0';
1488
      WAIT UNTIL rising_edge(clk);
1489
      WAIT UNTIL rising_edge(clk);
1490
      WAIT UNTIL rising_edge(clk);
1491
      out_ready <= '1';
1492
    END LOOP;
1493
    out_ready <= '1';
1494
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1495
 
1496
    -- . 3-1 toggle
1497
    out_ready <= '0';
1498
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1499
      WAIT UNTIL rising_edge(clk);
1500
      WAIT UNTIL rising_edge(clk);
1501
      WAIT UNTIL rising_edge(clk);
1502
      out_ready <= '0';
1503
      WAIT UNTIL rising_edge(clk);
1504
      out_ready <= '1';
1505
    END LOOP;
1506
    out_ready <= '1';
1507
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1508
 
1509
    -- . 2-3 toggle
1510
    out_ready <= '0';
1511
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1512
      WAIT UNTIL rising_edge(clk);
1513
      WAIT UNTIL rising_edge(clk);
1514
      out_ready <= '0';
1515
      WAIT UNTIL rising_edge(clk);
1516
      WAIT UNTIL rising_edge(clk);
1517
      WAIT UNTIL rising_edge(clk);
1518
      out_ready <= '1';
1519
    END LOOP;
1520
    out_ready <= '1';
1521
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1522
 
1523
    -- . 3-2 toggle
1524
    out_ready <= '0';
1525
    FOR I IN 1 TO c_dp_nof_toggle LOOP
1526
      WAIT UNTIL rising_edge(clk);
1527
      WAIT UNTIL rising_edge(clk);
1528
      WAIT UNTIL rising_edge(clk);
1529
      out_ready <= '0';
1530
      WAIT UNTIL rising_edge(clk);
1531
      WAIT UNTIL rising_edge(clk);
1532
      out_ready <= '1';
1533
    END LOOP;
1534
    out_ready <= '1';
1535
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1536
 
1537
    ----------------------------------------------------------------------------
1538
    -- Interval 5
1539
    ----------------------------------------------------------------------------
1540
    WAIT UNTIL sync='1';
1541
    out_ready <= '1';
1542
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1543
 
1544
    ----------------------------------------------------------------------------
1545
    -- Interval 6
1546
    ----------------------------------------------------------------------------
1547
    WAIT UNTIL sync='1';
1548
    out_ready <= '1';
1549
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1550
 
1551
    FOR I IN 1 TO c_dp_nof_both LOOP
1552
      out_ready <= '0';
1553
      FOR J IN I TO c_dp_nof_both LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1554
      out_ready <= '1';
1555
      FOR J IN 1 TO I LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1556
    END LOOP;
1557
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1558
 
1559
    ----------------------------------------------------------------------------
1560
    -- Interval 7
1561
    ----------------------------------------------------------------------------
1562
    WAIT UNTIL sync='1';
1563
    out_ready <= '1';
1564
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1565
 
1566
    ----------------------------------------------------------------------------
1567
    -- Interval 8 : Chirp out_ready
1568
    ----------------------------------------------------------------------------
1569
    WAIT UNTIL sync='1';
1570
    out_ready <= '1';
1571
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1572
 
1573
    -- . slow toggle
1574
    out_ready <= '0';
1575
    FOR I IN 0 TO c_dp_nof_toggle LOOP
1576
      out_ready <= '0';
1577
      FOR J IN 0 TO I LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1578
      out_ready <= '1';
1579
      FOR J IN 0 TO I LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1580
    END LOOP;
1581
    out_ready <= '1';
1582
    FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1583
 
1584
    ----------------------------------------------------------------------------
1585
    -- Interval 9 : Random
1586
    ----------------------------------------------------------------------------
1587
    WAIT UNTIL sync='1';
1588
    out_ready <= '1';
1589
 
1590
    FOR I IN 0 TO c_dp_sync_interval - c_dp_test_interval LOOP
1591
      lfsr <= func_common_random(lfsr);
1592
      out_ready <= lfsr(lfsr'HIGH);
1593
      WAIT UNTIL rising_edge(clk);
1594
    END LOOP;
1595
 
1596
    ----------------------------------------------------------------------------
1597
    -- Done
1598
    ----------------------------------------------------------------------------
1599
    WAIT;
1600
  END proc_dp_out_ready;
1601
 
1602
 
1603
  ------------------------------------------------------------------------------
1604
  -- PROCEDURE: DUT output verify enable
1605
  ------------------------------------------------------------------------------
1606
 
1607
  -- Fixed delay until verify_en active
1608
  PROCEDURE proc_dp_verify_en(CONSTANT c_delay   : IN  NATURAL;
1609
                              SIGNAL   rst       : IN  STD_LOGIC;
1610
                              SIGNAL   clk       : IN  STD_LOGIC;
1611
                              SIGNAL   sync      : IN  STD_LOGIC;
1612
                              SIGNAL   verify_en : OUT STD_LOGIC) IS
1613
  BEGIN
1614
    verify_en <= '0';
1615
    WAIT UNTIL rst='0';
1616
    WAIT UNTIL rising_edge(clk);
1617
 
1618
    WAIT UNTIL sync='1';
1619
    -- Use c_delay delay before enabling the p_verify.
1620
    FOR I IN 0 TO c_delay LOOP WAIT UNTIL rising_edge(clk); END LOOP;
1621
 
1622
    verify_en <= '1';
1623
    WAIT;
1624
  END proc_dp_verify_en;
1625
 
1626
 
1627
  -- Dynamicly depend on first valid data to make verify_en active
1628
  PROCEDURE proc_dp_verify_en(CONSTANT c_continuous : IN  BOOLEAN;
1629
                              SIGNAL   clk          : IN  STD_LOGIC;
1630
                              SIGNAL   valid        : IN  STD_LOGIC;
1631
                              SIGNAL   sop          : IN  STD_LOGIC;
1632
                              SIGNAL   eop          : IN  STD_LOGIC;
1633
                              SIGNAL   verify_en    : OUT STD_LOGIC) IS
1634
  BEGIN
1635
    IF rising_edge(clk) THEN
1636
      IF c_continuous=TRUE THEN
1637
        -- Verify across frames (so enable data verify after the first data has been output)
1638
        IF valid='1' THEN
1639
          verify_en <= '1';
1640
        END IF;
1641
      ELSE
1642
        -- Verify only per frame (so re-enable data verify after the every sop)
1643
        IF eop='1' THEN
1644
          verify_en <= '0';
1645
        ELSIF sop='1' THEN
1646
          verify_en <= '1';
1647
        END IF;
1648
      END IF;
1649
    END IF;
1650
  END proc_dp_verify_en;
1651
 
1652
  -- Run and verify for some cycles
1653
  PROCEDURE proc_dp_verify_run_some_cycles(CONSTANT nof_pre_clk    : IN   NATURAL;
1654
                                           CONSTANT nof_verify_clk : IN   NATURAL;
1655
                                           CONSTANT nof_post_clk   : IN   NATURAL;
1656
                                           SIGNAL   clk            : IN   STD_LOGIC;
1657
                                           SIGNAL   verify_en      : OUT  STD_LOGIC) IS
1658
  BEGIN
1659
    proc_common_wait_some_cycles(clk, nof_pre_clk);
1660
    verify_en <= '1';
1661
    proc_common_wait_some_cycles(clk, nof_verify_clk);
1662
    verify_en <= '0';
1663
    proc_common_wait_some_cycles(clk, nof_post_clk);
1664
  END proc_dp_verify_run_some_cycles;
1665
 
1666
 
1667
  ------------------------------------------------------------------------------
1668
  -- PROCEDURE: Verify the expected value
1669
  ------------------------------------------------------------------------------
1670
  --  e.g. to check that a test has ran at all
1671
  PROCEDURE proc_dp_verify_value(CONSTANT c_str : IN STRING;
1672
                                 CONSTANT mode  : IN t_dp_value_enum;
1673
                                 SIGNAL   clk   : IN STD_LOGIC;
1674
                                 SIGNAL   en    : IN STD_LOGIC;
1675
                                 SIGNAL   exp   : IN STD_LOGIC_VECTOR;
1676
                                 SIGNAL   res   : IN STD_LOGIC_VECTOR) IS
1677
  BEGIN
1678
    IF rising_edge(clk) THEN
1679
      IF en='1' THEN
1680
        IF mode = e_equal AND UNSIGNED(res) /= UNSIGNED(exp) THEN
1681
          REPORT "DP : Wrong " & c_str & " result value" SEVERITY ERROR;
1682
        END IF;
1683
        IF mode = e_at_least AND UNSIGNED(res) < UNSIGNED(exp) THEN
1684
          REPORT "DP : Wrong " & c_str & " result value too small" SEVERITY ERROR;
1685
        END IF;
1686
      END IF;
1687
    END IF;
1688
  END proc_dp_verify_value;
1689
 
1690
  PROCEDURE proc_dp_verify_value(CONSTANT mode : IN t_dp_value_enum;
1691
                                 SIGNAL   clk  : IN STD_LOGIC;
1692
                                 SIGNAL   en   : IN STD_LOGIC;
1693
                                 SIGNAL   exp  : IN STD_LOGIC_VECTOR;
1694
                                 SIGNAL   res  : IN STD_LOGIC_VECTOR) IS
1695
  BEGIN
1696
    proc_dp_verify_value("", mode, clk, en, exp, res);
1697
  END proc_dp_verify_value;
1698
 
1699
  PROCEDURE proc_dp_verify_value(CONSTANT c_str : IN STRING;
1700
                                 SIGNAL   clk   : IN STD_LOGIC;
1701
                                 SIGNAL   en    : IN STD_LOGIC;
1702
                                 SIGNAL   exp   : IN STD_LOGIC;
1703
                                 SIGNAL   res   : IN STD_LOGIC) IS
1704
  BEGIN
1705
    IF rising_edge(clk) THEN
1706
      IF en='1' THEN
1707
        IF res /= exp THEN
1708
          REPORT "DP : Wrong " & c_str & " result value" SEVERITY ERROR;
1709
        END IF;
1710
      END IF;
1711
    END IF;
1712
  END proc_dp_verify_value;
1713
 
1714
  ------------------------------------------------------------------------------
1715
  -- PROCEDURE: Verify output global and local BSN
1716
  ------------------------------------------------------------------------------
1717
  -- Verify BSN:
1718
  -- . incrementing or replicated global BSN
1719
  -- . incrementing local BSN that starts at 1
1720
  --
1721
  --               _              _              _              _             
1722
  --  sync      __| |____________| |____________| |____________| |____________
1723
  --               _    _    _    _    _    _    _    _    _    _    _    _
1724
  --   sop      __| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__  c_block_per_sync = 3
1725
  --
1726
  -- c_use_local_bsn = FALSE:
1727
  --                                                                            c_nof_replicated_global_bsn = 1
1728
  --        bsn    3    4    5    6    7    8    9    10   11   12   13   14    c_global_bsn_increment = 1
1729
  --        bsn    3    5    7    9   11   13   15    17   19   21   22   23    c_global_bsn_increment = 2
1730
  --
1731
  -- c_use_local_bsn = TRUE:
1732
  --
1733
  -- global bsn    3              4              5               6              c_global_bsn_increment = 1, c_nof_replicated_global_bsn = 1
1734
  -- global bsn    3              6              9              12              c_global_bsn_increment = 3, c_nof_replicated_global_bsn = 1
1735
  -- global bsn    3              3              9               9              c_global_bsn_increment = 6, c_nof_replicated_global_bsn = 2
1736
  --  local bsn    -    1    2    -    1    2    -    1    2     -    1    2    range 1:c_block_per_sync-1
1737
  --        
1738
  -- The verify_en should initially be set to '0' and gets enabled when
1739
  -- sufficient BSN history is available to do the verification.
1740
  --
1741
  PROCEDURE proc_dp_verify_bsn(CONSTANT c_use_local_bsn             : IN    BOOLEAN;    -- use local BSN or only use global BSN
1742
                               CONSTANT c_global_bsn_increment      : IN    POSITIVE;   -- increment per global BSN
1743
                               CONSTANT c_nof_replicated_global_bsn : IN    POSITIVE;   -- number of replicated global BSN
1744
                               CONSTANT c_block_per_sync            : IN    POSITIVE;   -- of sop/eop blocks per sync interval
1745
                               SIGNAL   clk                         : IN    STD_LOGIC;
1746
                               SIGNAL   out_sync                    : IN    STD_LOGIC;
1747
                               SIGNAL   out_sop                     : IN    STD_LOGIC;
1748
                               SIGNAL   out_bsn                     : IN    STD_LOGIC_VECTOR;
1749
                               SIGNAL   verify_en                   : INOUT STD_LOGIC;  -- initialize '0', becomes '1' when bsn verification starts
1750
                               SIGNAL   cnt_replicated_global_bsn   : INOUT NATURAL;
1751
                               SIGNAL   prev_out_bsn_global         : INOUT STD_LOGIC_VECTOR;
1752
                               SIGNAL   prev_out_bsn_local          : INOUT STD_LOGIC_VECTOR) IS
1753
  BEGIN
1754
    IF rising_edge(clk) THEN
1755
      -- out_sop must be active, because only then out_bsn will differ from the previous out_bsn
1756
      IF out_sop='1' THEN
1757
        IF c_use_local_bsn=FALSE THEN
1758
          ------------------------------------------------------------------
1759
          -- Only use global BSN
1760
          ------------------------------------------------------------------
1761
          prev_out_bsn_global <= out_bsn;
1762
          -- verify
1763
          IF  out_sync='1' THEN
1764
            verify_en <= '1';
1765
          END IF;
1766
          IF verify_en='1' THEN
1767
            ASSERT UNSIGNED(out_bsn) = UNSIGNED(prev_out_bsn_global)+c_global_bsn_increment REPORT "DP : Wrong BSN increment" SEVERITY ERROR;
1768
          END IF;
1769
        ELSE
1770
          ------------------------------------------------------------------
1771
          -- Use global and local BSN
1772
          ------------------------------------------------------------------
1773
          IF out_sync='1' THEN
1774
            prev_out_bsn_global <= out_bsn;
1775
            IF UNSIGNED(out_bsn) /= UNSIGNED(prev_out_bsn_global) THEN
1776
              verify_en <= '1';                -- wait until after last replicated global bsn
1777
              cnt_replicated_global_bsn <= 0;
1778
            ELSE
1779
              cnt_replicated_global_bsn <= cnt_replicated_global_bsn + 1;
1780
            END IF;
1781
            prev_out_bsn_local <= TO_UVEC(0, prev_out_bsn_global'LENGTH);
1782
          ELSE
1783
            prev_out_bsn_local <= out_bsn;
1784
          END IF;
1785
          -- verify
1786
          IF verify_en='1' THEN
1787
            IF out_sync='1' THEN
1788
              IF UNSIGNED(out_bsn) /= UNSIGNED(prev_out_bsn_global) THEN
1789
                ASSERT cnt_replicated_global_bsn=c_nof_replicated_global_bsn-1 REPORT "DP : Wrong number of replicated global BSN" SEVERITY ERROR;
1790
                ASSERT UNSIGNED(out_bsn)=UNSIGNED(prev_out_bsn_global)+c_global_bsn_increment REPORT "DP : Wrong global BSN increment" SEVERITY ERROR;
1791
              ELSE
1792
                ASSERT UNSIGNED(out_bsn)=UNSIGNED(prev_out_bsn_global) REPORT "DP : Wrong replicated global BSN" SEVERITY ERROR;
1793
              END IF;
1794
              ASSERT UNSIGNED(prev_out_bsn_local)=c_block_per_sync-1 REPORT "DP : Wrong last local BSN in sync interval" SEVERITY ERROR;
1795
            ELSE
1796
              ASSERT UNSIGNED(out_bsn)=UNSIGNED(prev_out_bsn_local)+1 REPORT "DP : Wrong local BSN increment" SEVERITY ERROR;
1797
            END IF;
1798
          END IF;
1799
        END IF;
1800
      END IF;
1801
    END IF;
1802
  END proc_dp_verify_bsn;
1803
 
1804
  ------------------------------------------------------------------------------
1805
  -- PROCEDURE: Verify the DUT output data
1806
  ------------------------------------------------------------------------------
1807
 
1808
  -- Verify incrementing data
1809
  -- . wrap at c_out_data_max when >0, else no wrap when c_out_data_max=0
1810
  -- . default increment by 1, but also allow an increment by c_out_data_gap
1811
  PROCEDURE proc_dp_verify_data(CONSTANT c_str           : IN    STRING;
1812
                                CONSTANT c_ready_latency : IN    NATURAL;
1813
                                CONSTANT c_out_data_max  : IN    UNSIGNED;
1814
                                CONSTANT c_out_data_gap  : IN    UNSIGNED;
1815
                                SIGNAL   clk             : IN    STD_LOGIC;
1816
                                SIGNAL   verify_en       : IN    STD_LOGIC;
1817
                                SIGNAL   out_ready       : IN    STD_LOGIC;  -- only needed when c_ready_latency = 0
1818
                                SIGNAL   out_val         : IN    STD_LOGIC;
1819
                                SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
1820
                                SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR) IS
1821
  BEGIN
1822
    IF rising_edge(clk) THEN
1823
      -- out_val must be active, because only the out_data will it differ from the previous out_data
1824
      IF out_val='1' THEN
1825
        -- for ready_latency > 0 out_val indicates new data
1826
        -- for ready_latency = 0 out_val only indicates new data when it is confirmed by out_ready
1827
        IF c_ready_latency/=0 OR (c_ready_latency=0 AND out_ready='1') THEN
1828
          IF c_out_data_max=0 THEN
1829
            prev_out_data <= out_data;                           -- no wrap detection
1830
          ELSIF UNSIGNED(out_data)<c_out_data_max THEN
1831
            prev_out_data <= out_data;                           -- no wrap
1832
          ELSE
1833
            prev_out_data <= TO_SVEC(-1, prev_out_data'LENGTH);  -- do wrap
1834
          END IF;
1835
          IF verify_en='1' THEN
1836
            IF UNSIGNED(out_data) /= UNSIGNED(prev_out_data)+1 AND                               -- check increment +1
1837
               UNSIGNED(out_data) /= UNSIGNED(prev_out_data)+c_out_data_gap AND                  -- increment +c_out_data_gap
1838
               UNSIGNED(out_data) /= UNSIGNED(prev_out_data)+c_out_data_gap-c_out_data_max THEN  -- increment +c_out_data_gap wrapped
1839
              REPORT "DP : Wrong out_data " & c_str & " count" SEVERITY ERROR;
1840
            END IF;
1841
          END IF;
1842
        END IF;
1843
      END IF;
1844
    END IF;
1845
  END proc_dp_verify_data;
1846
 
1847
  -- Verify incrementing data that wraps in range 0 ... c_out_data_max
1848
  PROCEDURE proc_dp_verify_data(CONSTANT c_str           : IN    STRING;
1849
                                CONSTANT c_ready_latency : IN    NATURAL;
1850
                                CONSTANT c_out_data_max  : IN    UNSIGNED;
1851
                                SIGNAL   clk             : IN    STD_LOGIC;
1852
                                SIGNAL   verify_en       : IN    STD_LOGIC;
1853
                                SIGNAL   out_ready       : IN    STD_LOGIC;
1854
                                SIGNAL   out_val         : IN    STD_LOGIC;
1855
                                SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
1856
                                SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR) IS
1857
  BEGIN
1858
    proc_dp_verify_data(c_str, c_ready_latency, c_out_data_max, TO_UNSIGNED(1,1), clk, verify_en, out_ready, out_val, out_data, prev_out_data);
1859
  END proc_dp_verify_data;
1860
 
1861
  -- Verify incrementing data
1862
  PROCEDURE proc_dp_verify_data(CONSTANT c_str           : IN    STRING;
1863
                                CONSTANT c_ready_latency : IN    NATURAL;
1864
                                SIGNAL   clk             : IN    STD_LOGIC;
1865
                                SIGNAL   verify_en       : IN    STD_LOGIC;
1866
                                SIGNAL   out_ready       : IN    STD_LOGIC;
1867
                                SIGNAL   out_val         : IN    STD_LOGIC;
1868
                                SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
1869
                                SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR) IS
1870
  BEGIN
1871
    proc_dp_verify_data(c_str, c_ready_latency, TO_UNSIGNED(0,1), TO_UNSIGNED(1,1), clk, verify_en, out_ready, out_val, out_data, prev_out_data);
1872
  END proc_dp_verify_data;
1873
 
1874
  -- Verify incrementing data with RL > 0 or no flow control
1875
  PROCEDURE proc_dp_verify_data(CONSTANT c_str           : IN    STRING;
1876
                                CONSTANT c_out_data_max  : IN    UNSIGNED;
1877
                                CONSTANT c_out_data_gap  : IN    UNSIGNED;
1878
                                SIGNAL   clk             : IN    STD_LOGIC;
1879
                                SIGNAL   verify_en       : IN    STD_LOGIC;
1880
                                SIGNAL   out_val         : IN    STD_LOGIC;
1881
                                SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
1882
                                SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR) IS
1883
  BEGIN
1884
    -- Use out_val as void signal to pass on to unused out_ready, because a signal input can not connect a constant or variable
1885
    proc_dp_verify_data(c_str, 1, c_out_data_max, c_out_data_gap, clk, verify_en, out_val, out_val, out_data, prev_out_data);
1886
  END proc_dp_verify_data;
1887
 
1888
  PROCEDURE proc_dp_verify_data(CONSTANT c_str           : IN    STRING;
1889
                                CONSTANT c_out_data_max  : IN    NATURAL;
1890
                                CONSTANT c_out_data_gap  : IN    NATURAL;
1891
                                SIGNAL   clk             : IN    STD_LOGIC;
1892
                                SIGNAL   verify_en       : IN    STD_LOGIC;
1893
                                SIGNAL   out_val         : IN    STD_LOGIC;
1894
                                SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
1895
                                SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR) IS
1896
    CONSTANT c_data_w : NATURAL := out_data'LENGTH;
1897
  BEGIN
1898
    proc_dp_verify_data(c_str, TO_UNSIGNED(c_out_data_max, c_data_w), TO_UNSIGNED(c_out_data_gap, c_data_w), clk, verify_en, out_val, out_data, prev_out_data);
1899
  END proc_dp_verify_data;
1900
 
1901
  PROCEDURE proc_dp_verify_data(CONSTANT c_str           : IN    STRING;
1902
                                CONSTANT c_out_data_max  : IN    NATURAL;
1903
                                SIGNAL   clk             : IN    STD_LOGIC;
1904
                                SIGNAL   verify_en       : IN    STD_LOGIC;
1905
                                SIGNAL   out_val         : IN    STD_LOGIC;
1906
                                SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
1907
                                SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR) IS
1908
    CONSTANT c_data_w : NATURAL := out_data'LENGTH;
1909
  BEGIN
1910
    proc_dp_verify_data(c_str, TO_UNSIGNED(c_out_data_max, c_data_w), TO_UNSIGNED(1, 1), clk, verify_en, out_val, out_data, prev_out_data);
1911
  END proc_dp_verify_data;
1912
 
1913
  PROCEDURE proc_dp_verify_data(CONSTANT c_str           : IN    STRING;
1914
                                SIGNAL   clk             : IN    STD_LOGIC;
1915
                                SIGNAL   verify_en       : IN    STD_LOGIC;
1916
                                SIGNAL   out_val         : IN    STD_LOGIC;
1917
                                SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
1918
                                SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR) IS
1919
  BEGIN
1920
    -- Use out_val as void signal to pass on to unused out_ready, because a signal input can not connect a constant or variable
1921
    proc_dp_verify_data(c_str, 1, TO_UNSIGNED(0,1), TO_UNSIGNED(1,1), clk, verify_en, out_val, out_val, out_data, prev_out_data);
1922
  END proc_dp_verify_data;
1923
 
1924
  ------------------------------------------------------------------------------
1925
  -- PROCEDURE: Verify incrementing symbols in data
1926
  -- . for c_data_w = c_symbol_w proc_dp_verify_symbols() = proc_dp_verify_data()
1927
  ------------------------------------------------------------------------------
1928
  PROCEDURE proc_dp_verify_symbols(CONSTANT c_ready_latency : IN    NATURAL;
1929
                                   CONSTANT c_data_w        : IN    NATURAL;
1930
                                   CONSTANT c_symbol_w      : IN    NATURAL;
1931
                                   SIGNAL   clk             : IN    STD_LOGIC;
1932
                                   SIGNAL   verify_en       : IN    STD_LOGIC;
1933
                                   SIGNAL   out_ready       : IN    STD_LOGIC;
1934
                                   SIGNAL   out_val         : IN    STD_LOGIC;
1935
                                   SIGNAL   out_eop         : IN    STD_LOGIC;
1936
                                   SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
1937
                                   SIGNAL   out_empty       : IN    STD_LOGIC_VECTOR;
1938
                                   SIGNAL   prev_out_data   : INOUT STD_LOGIC_VECTOR) IS
1939
    CONSTANT c_nof_symbols_per_data : NATURAL := c_data_w/c_symbol_w;  -- must be an integer
1940
    CONSTANT c_empty_w              : NATURAL := ceil_log2(c_nof_symbols_per_data);
1941
    VARIABLE v_data                 : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0);
1942
    VARIABLE v_symbol               : STD_LOGIC_VECTOR(c_symbol_w-1 DOWNTO 0);
1943
    VARIABLE v_empty                : NATURAL;
1944
  BEGIN
1945
    IF rising_edge(clk) THEN
1946
      -- out_val must be active, because only the out_data will it differ from the previous out_data
1947
      IF out_val='1' THEN
1948
        -- for ready_latency > 0 out_val indicates new data
1949
        -- for ready_latency = 0 out_val only indicates new data when it is confirmed by out_ready
1950
        IF c_ready_latency/=0 OR (c_ready_latency=0 AND out_ready='1') THEN
1951
          prev_out_data <= out_data;
1952
          IF verify_en='1' THEN
1953
            v_data  := prev_out_data(c_data_w-1 DOWNTO 0);
1954
            FOR I IN 0 TO c_nof_symbols_per_data-1 LOOP
1955
              v_data((I+1)*c_symbol_w-1 DOWNTO I*c_symbol_w) := INCR_UVEC(v_data((I+1)*c_symbol_w-1 DOWNTO I*c_symbol_w), c_nof_symbols_per_data);  -- increment each symbol
1956
            END LOOP;
1957
            IF out_eop='0' THEN
1958
              IF UNSIGNED(out_data) /= UNSIGNED(v_data) THEN
1959
                REPORT "DP : Wrong out_data symbols count" SEVERITY ERROR;
1960
              END IF;
1961
            ELSE
1962
              v_empty := TO_UINT(out_empty(c_empty_w-1 DOWNTO 0));
1963
              IF UNSIGNED(out_data(c_data_w-1 DOWNTO v_empty*c_symbol_w)) /= UNSIGNED(v_data(c_data_w-1 DOWNTO v_empty*c_symbol_w)) THEN
1964
                REPORT "DP : Wrong out_data symbols count at eop" SEVERITY ERROR;
1965
              END IF;
1966
              IF v_empty>0 THEN
1967
                -- adjust prev_out_data for potentially undefined empty symbols in out_data
1968
                v_symbol := v_data((v_empty+1)*c_symbol_w-1 DOWNTO v_empty*c_symbol_w);  -- last valid symbol
1969
                FOR I IN 0 TO c_nof_symbols_per_data-1 LOOP
1970
                  v_data((I+1)*c_symbol_w-1 DOWNTO I*c_symbol_w) := v_symbol;   -- put the last valid symbol at the end of the v_data
1971
                  v_symbol := INCR_UVEC(v_symbol, -1);                          -- decrement each symbol towards the beginning of v_data
1972
                END LOOP;
1973
                prev_out_data <= v_data;
1974
              END IF;
1975
            END IF;
1976
          END IF;
1977
        END IF;
1978
      END IF;
1979
    END IF;
1980
  END proc_dp_verify_symbols;
1981
 
1982
 
1983
  ------------------------------------------------------------------------------
1984
  -- PROCEDURE: Verify the DUT output data with empty
1985
  -- . account for stream empty
1986
  -- . support last word replace (e.g. by a CRC instead of the count, or use
1987
  --   c_last_word=out_data for no replace)
1988
  ------------------------------------------------------------------------------
1989
  PROCEDURE proc_dp_verify_data_empty(CONSTANT c_ready_latency : IN    NATURAL;
1990
                                      CONSTANT c_last_word     : IN    NATURAL;
1991
                                      SIGNAL   clk             : IN    STD_LOGIC;
1992
                                      SIGNAL   verify_en       : IN    STD_LOGIC;
1993
                                      SIGNAL   out_ready       : IN    STD_LOGIC;
1994
                                      SIGNAL   out_val         : IN    STD_LOGIC;
1995
                                      SIGNAL   out_eop         : IN    STD_LOGIC;
1996
                                      SIGNAL   out_eop_1       : INOUT STD_LOGIC;
1997
                                      SIGNAL   out_eop_2       : INOUT STD_LOGIC;
1998
                                      SIGNAL   out_data        : IN    STD_LOGIC_VECTOR;
1999
                                      SIGNAL   out_data_1      : INOUT STD_LOGIC_VECTOR;
2000
                                      SIGNAL   out_data_2      : INOUT STD_LOGIC_VECTOR;
2001
                                      SIGNAL   out_data_3      : INOUT STD_LOGIC_VECTOR;
2002
                                      SIGNAL   out_empty       : IN    STD_LOGIC_VECTOR;
2003
                                      SIGNAL   out_empty_1     : INOUT STD_LOGIC_VECTOR) IS
2004 5 danv
    VARIABLE v_last_word    : STD_LOGIC_VECTOR(out_data'HIGH DOWNTO 0);
2005
    VARIABLE v_ref_data     : STD_LOGIC_VECTOR(out_data'HIGH DOWNTO 0);
2006
    VARIABLE v_empty_data   : STD_LOGIC_VECTOR(out_data'HIGH DOWNTO 0);
2007 2 danv
  BEGIN
2008
    IF rising_edge(clk) THEN
2009
      -- out_val must be active, because only then out_data will differ from the previous out_data
2010
      IF out_val='1' THEN
2011
        -- for ready_latency > 0 out_val indicates new data
2012
        -- for ready_latency = 0 out_val only indicates new data when it is confirmed by out_ready
2013
        IF c_ready_latency/=0 OR (c_ready_latency=0 AND out_ready='1') THEN
2014
          -- default expected data
2015
          out_data_1  <= out_data;
2016
          out_data_2  <= out_data_1;
2017
          out_data_3  <= out_data_2;
2018
          out_empty_1 <= out_empty;
2019
          out_eop_1   <= out_eop;
2020
          out_eop_2   <= out_eop_1;
2021
          IF verify_en='1' THEN
2022
            -- assume sufficient valid cycles between eop and sop, so no need to check for out_sop with regard to eop empty
2023
            IF out_eop='0' AND out_eop_1='0' AND out_eop_2='0'THEN
2024
              -- verify out_data from eop-n to eop-2 and from eop+1 to eop+n, n>2
2025
              v_ref_data := INCR_UVEC(out_data_2, 1);
2026
              IF UNSIGNED(out_data_1) /= UNSIGNED(v_ref_data) THEN
2027
                REPORT "DP : Wrong out_data count" SEVERITY ERROR;
2028
              END IF;
2029
            ELSE
2030
              -- the empty and crc replace affect data at eop_1 and eop, so need to check data from eop-2 to eop-1 to eop to eop+1
2031
              v_last_word := TO_UVEC(c_last_word, out_data'LENGTH);
2032
              IF out_eop='1' THEN
2033
                -- verify out_data at eop
2034
                CASE TO_INTEGER(UNSIGNED(out_empty)) IS
2035
                  WHEN 0 => v_empty_data := v_last_word;
2036
                  WHEN 1 => v_empty_data := v_last_word(3*c_byte_w-1 DOWNTO 0) & c_slv0(1*c_byte_w-1 DOWNTO 0);
2037
                  WHEN 2 => v_empty_data := v_last_word(2*c_byte_w-1 DOWNTO 0) & c_slv0(2*c_byte_w-1 DOWNTO 0);
2038
                  WHEN 3 => v_empty_data := v_last_word(1*c_byte_w-1 DOWNTO 0) & c_slv0(3*c_byte_w-1 DOWNTO 0);
2039
                  WHEN OTHERS => NULL;
2040
                END CASE;
2041
                IF UNSIGNED(out_data) /= UNSIGNED(v_empty_data) THEN
2042
                  REPORT "DP : Wrong out_data count at eop" SEVERITY ERROR;
2043
                END IF;
2044
              ELSIF out_eop_1='1' THEN
2045
                -- verify out_data from eop-2 to eop-1
2046
                v_ref_data := INCR_UVEC(out_data_3, 1);
2047
                CASE TO_INTEGER(UNSIGNED(out_empty_1)) IS
2048
                  WHEN 0 => v_empty_data := v_ref_data;
2049
                  WHEN 1 => v_empty_data := v_ref_data(4*c_byte_w-1 DOWNTO 1*c_byte_w) & v_last_word(4*c_byte_w-1 DOWNTO 3*c_byte_w);
2050
                  WHEN 2 => v_empty_data := v_ref_data(4*c_byte_w-1 DOWNTO 2*c_byte_w) & v_last_word(4*c_byte_w-1 DOWNTO 2*c_byte_w);
2051
                  WHEN 3 => v_empty_data := v_ref_data(4*c_byte_w-1 DOWNTO 3*c_byte_w) & v_last_word(4*c_byte_w-1 DOWNTO 1*c_byte_w);
2052
                  WHEN OTHERS => NULL;
2053
                END CASE;
2054
                IF UNSIGNED(out_data_2) /= UNSIGNED(v_empty_data) THEN
2055
                  REPORT "DP : Wrong out_data count at eop-1" SEVERITY ERROR;
2056
                END IF;
2057
                -- verify out_data from eop-2 to eop+1
2058
                v_ref_data := INCR_UVEC(out_data_3, 3);
2059
                IF UNSIGNED(out_data) /= UNSIGNED(v_ref_data) THEN
2060
                  REPORT "DP : Wrong out_data count at eop+1" SEVERITY ERROR;
2061
                END IF;
2062
              END IF;
2063
            END IF;
2064
          END IF;
2065
        END IF;
2066
      END IF;
2067
    END IF;
2068
  END proc_dp_verify_data_empty;
2069
 
2070
 
2071
  ------------------------------------------------------------------------------
2072
  -- PROCEDURE: Verify the DUT output other SOSI data
2073
  -- . Suited to verify the empty, error, channel fields assuming that these
2074
  --   are treated in the same way in parallel to the SOSI data.
2075
  ------------------------------------------------------------------------------
2076
  PROCEDURE proc_dp_verify_other_sosi(CONSTANT c_str       : IN STRING;
2077
                                      CONSTANT c_exp_data  : IN STD_LOGIC_VECTOR;    -- use constant to support assignment via FUNCTION return value
2078
                                      SIGNAL   clk         : IN STD_LOGIC;
2079
                                      SIGNAL   verify_en   : IN STD_LOGIC;
2080
                                      SIGNAL   res_data    : IN STD_LOGIC_VECTOR) IS
2081
  BEGIN
2082
    IF rising_edge(clk) THEN
2083
      IF verify_en='1' THEN
2084
        IF    c_str="bsn" THEN
2085
          IF UNSIGNED(c_exp_data(c_dp_bsn_w-1 DOWNTO 0))/=UNSIGNED(res_data(c_dp_bsn_w-1 DOWNTO 0)) THEN
2086
            REPORT "DP : Wrong sosi.bsn value" SEVERITY ERROR;
2087
          END IF;
2088
        ELSIF c_str="empty" THEN
2089
          IF UNSIGNED(c_exp_data(c_dp_empty_w-1 DOWNTO 0))/=UNSIGNED(res_data(c_dp_empty_w-1 DOWNTO 0)) THEN
2090
            REPORT "DP : Wrong sosi.empty value" SEVERITY ERROR;
2091
          END IF;
2092
        ELSIF c_str="channel" THEN
2093
          IF UNSIGNED(c_exp_data(c_dp_channel_user_w-1 DOWNTO 0))/=UNSIGNED(res_data(c_dp_channel_user_w-1 DOWNTO 0)) THEN
2094
            REPORT "DP : Wrong sosi.channel value" SEVERITY ERROR;
2095
          END IF;
2096
        ELSIF c_str="error" THEN
2097
          IF UNSIGNED(c_exp_data(c_dp_error_w-1 DOWNTO 0))/=UNSIGNED(res_data(c_dp_error_w-1 DOWNTO 0)) THEN
2098
            REPORT "DP : Wrong sosi.error value" SEVERITY ERROR;
2099
          END IF;
2100
        ELSE
2101
          REPORT "proc_dp_verify_other_sosi : Unknown sosi." & c_str & "field" SEVERITY FAILURE;
2102
        END IF;
2103
      END IF;
2104
    END IF;
2105
  END proc_dp_verify_other_sosi;
2106
 
2107
 
2108
  ------------------------------------------------------------------------------
2109
  -- PROCEDURE: Verify the DUT output valid
2110
  ------------------------------------------------------------------------------
2111
  PROCEDURE proc_dp_verify_valid(CONSTANT c_ready_latency : IN    NATURAL;
2112
                                 SIGNAL   clk             : IN    STD_LOGIC;
2113
                                 SIGNAL   verify_en       : IN    STD_LOGIC;
2114
                                 SIGNAL   out_ready       : IN    STD_LOGIC;
2115
                                 SIGNAL   prev_out_ready  : INOUT STD_LOGIC_VECTOR;
2116
                                 SIGNAL   out_val         : IN    STD_LOGIC) IS
2117
  BEGIN
2118
    IF rising_edge(clk) THEN
2119
      -- for ready_latency > 0 out_val may only be asserted after out_ready
2120
      -- for ready_latency = 0 out_val may always be asserted
2121
      prev_out_ready <= (prev_out_ready'RANGE=>'0');
2122
      IF c_ready_latency/=0 THEN
2123
        IF c_ready_latency=1 THEN
2124
          prev_out_ready(0) <= out_ready;
2125
        ELSE
2126
          prev_out_ready    <= out_ready & prev_out_ready(0 TO c_ready_latency-1);
2127
        END IF;
2128
        IF verify_en='1' AND out_val='1' THEN
2129
          IF prev_out_ready(c_ready_latency-1)/='1' THEN
2130
            REPORT "DP : Wrong ready latency between out_ready and out_val" SEVERITY ERROR;
2131
          END IF;
2132
        END IF;
2133
      END IF;
2134
    END IF;
2135
  END proc_dp_verify_valid;
2136
 
2137
  PROCEDURE proc_dp_verify_valid(SIGNAL   clk             : IN    STD_LOGIC;
2138
                                 SIGNAL   verify_en       : IN    STD_LOGIC;
2139
                                 SIGNAL   out_ready       : IN    STD_LOGIC;
2140
                                 SIGNAL   prev_out_ready  : INOUT STD_LOGIC;
2141
                                 SIGNAL   out_val         : IN    STD_LOGIC) IS
2142
  BEGIN
2143
    -- Can not reuse:
2144
    --   proc_dp_verify_valid(1, clk, verify_en, out_ready, prev_out_ready, out_val);
2145
    -- because prev_out_ready needs to map from STD_LOGIC to STD_LOGIC_VECTOR. Therefore copy paste code for RL=1:
2146
    IF rising_edge(clk) THEN
2147
      -- for ready_latency = 1 out_val may only be asserted after out_ready
2148
      prev_out_ready <= out_ready;
2149
      IF verify_en='1' AND out_val='1' THEN
2150
        IF prev_out_ready/='1' THEN
2151
          REPORT "DP : Wrong ready latency between out_ready and out_val" SEVERITY ERROR;
2152
        END IF;
2153
      END IF;
2154
    END IF;
2155
  END proc_dp_verify_valid;
2156
 
2157
  ------------------------------------------------------------------------------
2158
  -- PROCEDURE: Verify the DUT output sync
2159
  -- . sync is defined such that it can only be active at sop
2160
  -- . assume that the sync occures priodically at bsn MOD c_sync_period = c_sync_offset
2161
  ------------------------------------------------------------------------------
2162
  PROCEDURE proc_dp_verify_sync(CONSTANT c_sync_period   : IN    NATURAL;    -- BSN sync period
2163
                                CONSTANT c_sync_offset   : IN    NATURAL;    -- BSN sync offset
2164
                                SIGNAL   clk             : IN    STD_LOGIC;
2165
                                SIGNAL   verify_en       : IN    STD_LOGIC;
2166
                                SIGNAL   sync            : IN    STD_LOGIC;
2167
                                SIGNAL   sop             : IN    STD_LOGIC;
2168
                                SIGNAL   bsn             : IN    STD_LOGIC_VECTOR) IS
2169
    CONSTANT c_bsn_w         : NATURAL := sel_a_b(bsn'LENGTH>31, 31, bsn'LENGTH);  -- use maximally 31 bit of BSN slv to allow calculations with integers
2170
    VARIABLE v_expected_sync : BOOLEAN;
2171
  BEGIN
2172
    IF rising_edge(clk) THEN
2173
      IF verify_en='1' THEN
2174
        v_expected_sync := (TO_UINT(bsn(c_bsn_w-1 DOWNTO 0))-c_sync_offset) MOD c_sync_period = 0;
2175
        -- Check for unexpected sync
2176
        IF sync='1' THEN
2177
          ASSERT v_expected_sync = TRUE
2178
            REPORT "Error: Unexpected sync at BSN" SEVERITY ERROR;
2179
          ASSERT sop = '1'
2180
            REPORT "Error: Unexpected sync at inactive sop" SEVERITY ERROR;
2181
        END IF;
2182
        -- Check for missing sync
2183
        IF sop='1' AND v_expected_sync=TRUE THEN
2184
          ASSERT sync = '1'
2185
            REPORT "Error: Missing sync" SEVERITY ERROR;
2186
        END IF;
2187
      END IF;
2188
    END IF;
2189
  END proc_dp_verify_sync;
2190
 
2191
 
2192
  ------------------------------------------------------------------------------
2193
  -- PROCEDURE: Verify the DUT output sop and eop
2194
  ------------------------------------------------------------------------------
2195
  -- sop and eop in pairs, valid during packet and invalid between packets
2196
  PROCEDURE proc_dp_verify_sop_and_eop(CONSTANT c_ready_latency : IN    NATURAL;
2197
                                       CONSTANT c_verify_valid  : IN    BOOLEAN;
2198
                                       SIGNAL   clk             : IN    STD_LOGIC;
2199
                                       SIGNAL   out_ready       : IN    STD_LOGIC;
2200
                                       SIGNAL   out_val         : IN    STD_LOGIC;
2201
                                       SIGNAL   out_sop         : IN    STD_LOGIC;
2202
                                       SIGNAL   out_eop         : IN    STD_LOGIC;
2203
                                       SIGNAL   hold_sop        : INOUT STD_LOGIC) IS
2204
  BEGIN
2205
    IF rising_edge(clk) THEN
2206
      IF out_val='0' THEN
2207
        IF out_sop='1' THEN REPORT "DP : Wrong active sop during invalid" SEVERITY ERROR; END IF;
2208
        IF out_eop='1' THEN REPORT "DP : Wrong active eop during invalid" SEVERITY ERROR; END IF;
2209
      ELSE
2210
        -- for ready_latency > 0 out_val indicates new data
2211
        -- for ready_latency = 0 out_val only indicates new data when it is confirmed by out_ready
2212
        IF c_ready_latency/=0 OR (c_ready_latency=0 AND out_ready='1') THEN
2213
          IF out_sop='1' THEN
2214
            hold_sop <= '1';
2215
            IF hold_sop='1' THEN
2216
              REPORT "DP : Unexpected sop without eop" SEVERITY ERROR;
2217
            END IF;
2218
          END IF;
2219
          IF out_eop='1' THEN
2220
            hold_sop <= '0';
2221
            IF hold_sop='0' AND out_sop='0' THEN
2222
              REPORT "DP : Unexpected eop without sop" SEVERITY ERROR;
2223
            END IF;
2224
          END IF;
2225
          -- out_val='1'
2226
          IF c_verify_valid=TRUE AND out_sop='0' AND hold_sop='0' THEN
2227
            REPORT "DP : Unexpected valid in gap between eop and sop" SEVERITY ERROR;
2228
          END IF;
2229
        END IF;
2230
      END IF;
2231
    END IF;
2232
  END proc_dp_verify_sop_and_eop;
2233
 
2234
  PROCEDURE proc_dp_verify_sop_and_eop(CONSTANT c_ready_latency : IN    NATURAL;
2235
                                       SIGNAL   clk             : IN    STD_LOGIC;
2236
                                       SIGNAL   out_ready       : IN    STD_LOGIC;
2237
                                       SIGNAL   out_val         : IN    STD_LOGIC;
2238
                                       SIGNAL   out_sop         : IN    STD_LOGIC;
2239
                                       SIGNAL   out_eop         : IN    STD_LOGIC;
2240
                                       SIGNAL   hold_sop        : INOUT STD_LOGIC) IS
2241
  BEGIN
2242
    proc_dp_verify_sop_and_eop(c_ready_latency, TRUE, clk, out_ready, out_val, out_sop, out_eop, hold_sop);
2243
  END proc_dp_verify_sop_and_eop;
2244
 
2245
  PROCEDURE proc_dp_verify_sop_and_eop(SIGNAL   clk      : IN    STD_LOGIC;
2246
                                       SIGNAL   out_val  : IN    STD_LOGIC;
2247
                                       SIGNAL   out_sop  : IN    STD_LOGIC;
2248
                                       SIGNAL   out_eop  : IN    STD_LOGIC;
2249
                                       SIGNAL   hold_sop : INOUT STD_LOGIC) IS
2250
  BEGIN
2251
    -- Use out_val as void signal to pass on to unused out_ready, because a signal input can not connect a constant or variable
2252
    proc_dp_verify_sop_and_eop(1, TRUE, clk, out_val, out_val, out_sop, out_eop, hold_sop);
2253
  END proc_dp_verify_sop_and_eop;
2254
 
2255
  PROCEDURE proc_dp_verify_block_size(CONSTANT c_ready_latency : IN    NATURAL;
2256
                                      SIGNAL   alt_size        : IN    NATURAL;     -- alternative size
2257
                                      SIGNAL   exp_size        : IN    NATURAL;     -- expected size 
2258
                                      SIGNAL   clk             : IN    STD_LOGIC;
2259
                                      SIGNAL   out_ready       : IN    STD_LOGIC;
2260
                                      SIGNAL   out_val         : IN    STD_LOGIC;
2261
                                      SIGNAL   out_sop         : IN    STD_LOGIC;
2262
                                      SIGNAL   out_eop         : IN    STD_LOGIC;
2263
                                      SIGNAL   cnt_size        : INOUT NATURAL) IS
2264
  BEGIN
2265
    IF rising_edge(clk) THEN
2266
      IF out_val='1' THEN
2267
        -- for ready_latency > 0 out_val indicates new data
2268
        -- for ready_latency = 0 out_val only indicates new data when it is confirmed by out_ready
2269
        IF c_ready_latency/=0 OR (c_ready_latency=0 AND out_ready='1') THEN
2270
          IF out_sop='1' THEN
2271
            cnt_size <= 1;
2272
          ELSIF out_eop='1' THEN
2273
            cnt_size <= 0;
2274
            IF cnt_size/=alt_size-1 AND cnt_size/=exp_size-1 THEN
2275
              REPORT "DP : Unexpected block size" SEVERITY ERROR;
2276
            END IF;
2277
          ELSE
2278
            cnt_size <= cnt_size+1;
2279
          END IF;
2280
        END IF;
2281
      END IF;
2282
    END IF;
2283
  END proc_dp_verify_block_size;
2284
 
2285
  PROCEDURE proc_dp_verify_block_size(CONSTANT c_ready_latency : IN    NATURAL;
2286
                                      SIGNAL   exp_size        : IN    NATURAL;
2287
                                      SIGNAL   clk             : IN    STD_LOGIC;
2288
                                      SIGNAL   out_ready       : IN    STD_LOGIC;
2289
                                      SIGNAL   out_val         : IN    STD_LOGIC;
2290
                                      SIGNAL   out_sop         : IN    STD_LOGIC;
2291
                                      SIGNAL   out_eop         : IN    STD_LOGIC;
2292
                                      SIGNAL   cnt_size        : INOUT NATURAL) IS
2293
  BEGIN
2294
    proc_dp_verify_block_size(c_ready_latency, exp_size, exp_size, clk, out_ready, out_val, out_sop, out_eop, cnt_size);
2295
  END proc_dp_verify_block_size;
2296
 
2297
  PROCEDURE proc_dp_verify_block_size(SIGNAL   alt_size        : IN    NATURAL;     -- alternative size
2298
                                      SIGNAL   exp_size        : IN    NATURAL;     -- expected size   
2299
                                      SIGNAL   clk             : IN    STD_LOGIC;
2300
                                      SIGNAL   out_val         : IN    STD_LOGIC;
2301
                                      SIGNAL   out_sop         : IN    STD_LOGIC;
2302
                                      SIGNAL   out_eop         : IN    STD_LOGIC;
2303
                                      SIGNAL   cnt_size        : INOUT NATURAL) IS
2304
  BEGIN
2305
    -- Use out_val as void signal to pass on to unused out_ready, because a signal input can not connect a constant or variable
2306
    proc_dp_verify_block_size(1, alt_size, exp_size, clk, out_val, out_val, out_sop, out_eop, cnt_size);
2307
  END proc_dp_verify_block_size;
2308
 
2309
  PROCEDURE proc_dp_verify_block_size(SIGNAL   exp_size        : IN    NATURAL;
2310
                                      SIGNAL   clk             : IN    STD_LOGIC;
2311
                                      SIGNAL   out_val         : IN    STD_LOGIC;
2312
                                      SIGNAL   out_sop         : IN    STD_LOGIC;
2313
                                      SIGNAL   out_eop         : IN    STD_LOGIC;
2314
                                      SIGNAL   cnt_size        : INOUT NATURAL) IS
2315
  BEGIN
2316
    -- Use out_val as void signal to pass on to unused out_ready, because a signal input can not connect a constant or variable
2317
    proc_dp_verify_block_size(1, exp_size, exp_size, clk, out_val, out_val, out_sop, out_eop, cnt_size);
2318
  END proc_dp_verify_block_size;
2319
 
2320
  ------------------------------------------------------------------------------
2321
  -- PROCEDURE: Verify the DUT output invalid between frames
2322
  ------------------------------------------------------------------------------
2323
  PROCEDURE proc_dp_verify_gap_invalid(SIGNAL clk     : IN    STD_LOGIC;
2324
                                       SIGNAL in_val  : IN    STD_LOGIC;
2325
                                       SIGNAL in_sop  : IN    STD_LOGIC;
2326
                                       SIGNAL in_eop  : IN    STD_LOGIC;
2327
                                       SIGNAL out_gap : INOUT STD_LOGIC) IS
2328
  BEGIN
2329
    IF rising_edge(clk) THEN
2330
      IF in_eop='1' THEN
2331
        out_gap <= '1';
2332
      ELSIF in_sop='1' THEN
2333
        out_gap <= '0';
2334
      ELSIF in_val='1' AND out_gap='1' THEN
2335
        REPORT "DP : Wrong valid in gap between eop and sop" SEVERITY ERROR;
2336
      END IF;
2337
    END IF;
2338
  END proc_dp_verify_gap_invalid;
2339
 
2340
 
2341
  ------------------------------------------------------------------------------
2342
  -- PROCEDURE: Verify the DUT output control (use for sop, eop)
2343
  ------------------------------------------------------------------------------
2344
  PROCEDURE proc_dp_verify_ctrl(CONSTANT c_offset  : IN NATURAL;
2345
                                CONSTANT c_period  : IN NATURAL;
2346
                                CONSTANT c_str     : IN STRING;
2347
                                SIGNAL   clk       : IN STD_LOGIC;
2348
                                SIGNAL   verify_en : IN STD_LOGIC;
2349
                                SIGNAL   data      : IN STD_LOGIC_VECTOR;
2350
                                SIGNAL   valid     : IN STD_LOGIC;
2351
                                SIGNAL   ctrl      : IN STD_LOGIC) IS
2352
    VARIABLE v_data : INTEGER;
2353
  BEGIN
2354
    IF rising_edge(clk) THEN
2355
      IF verify_en='1' THEN
2356
        v_data := TO_UINT(data);
2357
        IF ((v_data-c_offset) MOD c_period)=0 THEN
2358
          IF valid='1' AND ctrl/='1' THEN
2359
            REPORT "DP : Wrong data control, missing " & c_str SEVERITY ERROR;
2360
          END IF;
2361
        ELSE
2362
          IF ctrl='1' THEN
2363
            REPORT "DP : Wrong data control, unexpected " & c_str SEVERITY ERROR;
2364
          END IF;
2365
        END IF;
2366
      END IF;
2367
    END IF;
2368
  END proc_dp_verify_ctrl;
2369
 
2370
 
2371
  ------------------------------------------------------------------------------
2372
  -- PROCEDURE: Wait for stream valid
2373
  ------------------------------------------------------------------------------
2374
  PROCEDURE proc_dp_stream_valid(SIGNAL clk      : IN  STD_LOGIC;
2375
                                 SIGNAL in_valid : IN  STD_LOGIC) IS
2376
  BEGIN
2377
    WAIT UNTIL rising_edge(clk);
2378
    WHILE in_valid /= '1' LOOP
2379
      WAIT UNTIL rising_edge(clk);
2380
    END LOOP;
2381
  END proc_dp_stream_valid;
2382
 
2383
 
2384
  ------------------------------------------------------------------------------
2385
  -- PROCEDURE: Wait for stream valid AND sop
2386
  ------------------------------------------------------------------------------
2387
  PROCEDURE proc_dp_stream_valid_sop(SIGNAL clk      : IN  STD_LOGIC;
2388
                                     SIGNAL in_valid : IN  STD_LOGIC;
2389
                                     SIGNAL in_sop   : IN  STD_LOGIC) IS
2390
  BEGIN
2391
    WAIT UNTIL rising_edge(clk);
2392
    WHILE in_valid /= '1' AND in_sop /= '1' LOOP
2393
      WAIT UNTIL rising_edge(clk);
2394
    END LOOP;
2395
  END proc_dp_stream_valid_sop;
2396
 
2397
 
2398
  ------------------------------------------------------------------------------
2399
  -- PROCEDURE: Wait for stream valid AND eop
2400
  ------------------------------------------------------------------------------
2401
  PROCEDURE proc_dp_stream_valid_eop(SIGNAL clk      : IN  STD_LOGIC;
2402
                                     SIGNAL in_valid : IN  STD_LOGIC;
2403
                                     SIGNAL in_eop   : IN  STD_LOGIC) IS
2404
  BEGIN
2405
    WAIT UNTIL rising_edge(clk);
2406
    WHILE in_valid /= '1' AND in_eop /= '1' LOOP
2407
      WAIT UNTIL rising_edge(clk);
2408
    END LOOP;
2409
  END proc_dp_stream_valid_eop;
2410
 
2411
END tb_dp_pkg;

powered by: WebSVN 2.1.0

© copyright 1999-2021 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.