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 2

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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