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

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.interface/] [udp2hibi/] [1.0/] [tb/] [tb_hibi_transmitter.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : Testbench for hibi transmitter
3
-- Project    : UDP2HIBI
4
-------------------------------------------------------------------------------
5
-- File       : tb_hibi_transmitter.vhd
6
-- Author     : Jussi Nieminen
7
-- Last update: 2012-03-22
8
-- Platform   : Sim only
9
-------------------------------------------------------------------------------
10
-- Description: A couple of hard-coded directed tests and checking.
11
-------------------------------------------------------------------------------
12
-- Revisions  :
13
-- Date        Version  Author  Description
14
-- 2009/12/21  1.0      niemin95        Created
15
-------------------------------------------------------------------------------
16
 
17
library ieee;
18
use ieee.std_logic_1164.all;
19
use ieee.numeric_std.all;
20
use work.udp2hibi_pkg.all;
21
 
22
 
23
entity tb_hibi_transmitter is
24
  port (
25
    read_tmp          : out integer;
26
    current_test_case : out integer range 0 to 10
27
    );
28
end tb_hibi_transmitter;
29
 
30
 
31
architecture tb of tb_hibi_transmitter is
32
 
33
  constant hibi_data_width_c : integer := 32;
34
  constant hibi_addr_width_c : integer := 32;
35
  constant hibi_comm_width_c : integer := 5;  --3;
36
  constant ack_fifo_depth_c  : integer := 5;
37
 
38
 
39
 
40
  constant period_c : time      := 20 ns;
41
  signal   clk      : std_logic := '1';
42
  signal   rst_n    : std_logic := '0';
43
 
44
 
45
  -- to/from rx_ctrl
46
  signal send_request_to_duv   : std_logic                                      := '0';
47
  signal rx_len_to_duv         : std_logic_vector(tx_len_w_c-1 downto 0)        := (others => '0');
48
  signal ready_for_tx_from_duv : std_logic;
49
  signal rx_empty_to_duv       : std_logic                                      := '1';
50
  signal rx_data_to_duv        : std_logic_vector(hibi_data_width_c-1 downto 0) := (others => '0');
51
  signal rx_re_from_duv        : std_logic;
52
  -- from ctrl_regs
53
  signal rx_addr_to_duv        : std_logic_vector(hibi_addr_width_c-1 downto 0) := (others => '0');
54
  signal ack_addr_to_duv       : std_logic_vector(hibi_addr_width_c-1 downto 0) := (others => '0');
55
  signal send_tx_ack_to_duv    : std_logic                                      := '0';
56
  signal send_tx_nack_to_duv   : std_logic                                      := '0';
57
  signal send_rx_ack_to_duv    : std_logic                                      := '0';
58
  signal send_rx_nack_to_duv   : std_logic                                      := '0';
59
 
60
 
61
  -- to/from HIBI  
62
  signal hibi_comm_from_duv    : std_logic_vector(hibi_comm_width_c-1 downto 0);
63
  signal hibi_data_from_duv    : std_logic_vector(hibi_data_width_c-1 downto 0);
64
  signal hibi_av_from_duv      : std_logic;
65
  signal hibi_we_from_duv      : std_logic;
66
  signal hibi_full_to_duv      : std_logic                                      := '0';
67
 
68
 
69
  signal send_en : std_logic := '0';
70
 
71
  --------------------------------------------
72
  constant test_data_amount_c : integer        := 16;
73
  type     test_data_type is array (0 to test_data_amount_c-1) of std_logic_vector(hibi_data_width_c-1 downto 0);
74
  constant test_data          : test_data_type :=
75
    (x"03020100", x"07060504", x"0b0a0908", x"0f0e0d0c",
76
      x"13121110", x"17161514", x"1b1a1918", x"1f1e1d1c",
77
      x"23222120", x"27262524", x"2b2a2928", x"2f2e2d2c",
78
      x"33323130", x"37363534", x"3b3a3938", x"3f3e3d3c");
79
 
80
  -- HIBI transmitter sends two kinds on data: ack/nack and udp data
81
  -- The test cases:
82
  -- 1. tx conf ack
83
  -- 2. rx conf ack right after previous
84
  -- 3. new rx
85
  -- 4. little pause and tx conf nack
86
  -- 5. more data from the earlier rx
87
  -- 6. a little pause
88
  -- 7. more data
89
  -- 8. new rx
90
  -- 9. rx conf nack with new data waiting at rx fifo
91
  -- 10. rx continues
92
 
93
  -- to check the addresses sent
94
  type     addr_array is array (0 to 7) of std_logic_vector(hibi_addr_width_c-1 downto 0);
95
  constant addresses_to_check : addr_array :=
96
    (x"01234567", x"12345678", x"23456789", x"3456789a",
97
      x"23456789", x"456789ab", x"56789abc", x"456789ab");
98
 
99
  type     rx_len_array is array (0 to 1) of std_logic_vector(tx_len_w_c-1 downto 0);
100
  -- these don't have to be equal with the data that is send by sender process,
101
  -- because hibi transmitter just sends this value in header without using it
102
  -- in any other way
103
  constant rx_lens : rx_len_array := ("00010011001", "00001100110");
104
 
105
 
106
  -- empty/full signal is lifted after this amount of reads/writes has
107
  -- been done:
108
  constant empty_freq_c : integer := 13;
109
  constant full_freq_c  : integer := 3;
110
 
111
 
112
-------------------------------------------------------------------------------
113
begin  -- tb
114
-------------------------------------------------------------------------------
115
 
116
  --
117
  -- Structure: DUV + 3 processes
118
  --
119
  --  main-----------------+
120
  --   |                   |
121
  --   v                   V
122
  --  rx_ctrl --> DUV --> HIBI
123
  --
124
  --
125
 
126
 
127
  duv : entity work.hibi_transmitter
128
    generic map (
129
      hibi_data_width_g => hibi_data_width_c,
130
      hibi_addr_width_g => hibi_addr_width_c,
131
      hibi_comm_width_g => hibi_comm_width_c,
132
      ack_fifo_depth_g  => ack_fifo_depth_c
133
      )
134
    port map (
135
      clk              => clk,
136
      rst_n            => rst_n,
137
      hibi_comm_out    => hibi_comm_from_duv,
138
      hibi_data_out    => hibi_data_from_duv,
139
      hibi_av_out      => hibi_av_from_duv,
140
      hibi_we_out      => hibi_we_from_duv,
141
      hibi_full_in     => hibi_full_to_duv,
142
 
143
      send_request_in  => send_request_to_duv,
144
      rx_len_in        => rx_len_to_duv,
145
      ready_for_tx_out => ready_for_tx_from_duv,
146
      rx_empty_in      => rx_empty_to_duv,
147
      rx_data_in       => rx_data_to_duv,
148
      rx_re_out        => rx_re_from_duv,
149
      rx_addr_in       => rx_addr_to_duv,
150
 
151
      ack_addr_in      => ack_addr_to_duv,
152
      send_tx_ack_in   => send_tx_ack_to_duv,
153
      send_tx_nack_in  => send_tx_nack_to_duv,
154
      send_rx_ack_in   => send_rx_ack_to_duv,
155
      send_rx_nack_in  => send_rx_nack_to_duv
156
      );
157
 
158
 
159
  -- clk generation
160
  clk   <= not clk after period_c/2;
161
  rst_n <= '1'     after period_c*4;
162
 
163
 
164
 
165
  -----------------------------------------------------------------------------
166
  -- Keeps track of test pahse and request rx-ctrl process to provide more data
167
  -----------------------------------------------------------------------------
168
  main : process
169
  begin  -- process main
170
 
171
    if rst_n = '0' then
172
      wait until rst_n = '1';
173
    end if;
174
 
175
    wait for period_c*4;
176
 
177
 
178
    -- test cases
179
    -- 1. tx ack
180
    -- 2. rx ack right after the tx ack
181
    -- 3. new rx
182
    -- 4. little pause and tx nack
183
    -- 5. more data from the earlier rx
184
    -- 6. a little pause
185
    -- 7. more data
186
    -- 8. new rx
187
    -- 9. rx nack with new data waiting at rx fifo
188
    -- 10. rx continues
189
 
190
    -- 1.
191
    current_test_case  <= 1;
192
    send_tx_ack_to_duv <= '1';
193
    ack_addr_to_duv    <= addresses_to_check(0);
194
    wait for period_c;
195
    send_tx_ack_to_duv <= '0';
196
    wait for period_c;
197
    -- 2.
198
    current_test_case  <= 2;
199
    send_rx_ack_to_duv <= '1';
200
    ack_addr_to_duv    <= addresses_to_check(1);
201
    wait for period_c;
202
    send_rx_ack_to_duv <= '0';
203
 
204
    wait for period_c*10;
205
 
206
    -- 3.
207
    current_test_case <= 3;
208
    if ready_for_tx_from_duv = '0' then
209
      wait until ready_for_tx_from_duv = '1';
210
    end if;
211
    send_request_to_duv <= '1';
212
    rx_len_to_duv       <= rx_lens(0);
213
    rx_addr_to_duv      <= addresses_to_check(2);
214
    wait for period_c;
215
    send_request_to_duv <= '0';
216
    send_en             <= '1';
217
 
218
    -- let data flow for a while...
219
    wait for period_c*40;
220
 
221
    -- 4.
222
    current_test_case <= 4;
223
    send_en           <= '0';
224
    wait for period_c*5;
225
 
226
    send_tx_nack_to_duv <= '1';
227
    ack_addr_to_duv     <= addresses_to_check(3);
228
    wait for period_c;
229
    send_tx_nack_to_duv <= '0';
230
    wait for period_c*3;
231
 
232
    -- 5.
233
    current_test_case <= 5;
234
    send_en           <= '1';
235
    wait for period_c*25;
236
 
237
    -- 6.
238
    current_test_case <= 6;
239
    send_en           <= '0';
240
    wait for period_c*10;
241
 
242
    -- 7.
243
    current_test_case <= 7;
244
    send_en           <= '1';
245
    wait for period_c*31;
246
    send_en           <= '0';
247
    wait for period_c;
248
 
249
    -- 8.
250
    current_test_case <= 8;
251
    if ready_for_tx_from_duv = '0' then
252
      wait until ready_for_tx_from_duv = '1';
253
    end if;
254
    send_request_to_duv <= '1';
255
    rx_len_to_duv       <= rx_lens(1);
256
    rx_addr_to_duv      <= addresses_to_check(5);
257
    wait for period_c;
258
    send_request_to_duv <= '0';
259
    send_en             <= '1';
260
 
261
    wait for period_c*11;
262
 
263
    -- 9.
264
    current_test_case   <= 9;
265
    send_rx_nack_to_duv <= '1';
266
    ack_addr_to_duv     <= addresses_to_check(6);
267
    wait for period_c;
268
    send_rx_nack_to_duv <= '0';
269
 
270
    -- 10.
271
    current_test_case <= 10;
272
    wait for period_c*27;
273
    send_en           <= '0';
274
 
275
 
276
    -- halt
277
    wait for period_c*20;
278
    report "Simulation ended." severity failure;
279
 
280
  end process main;
281
 
282
 
283
  -----------------------------------------------------------------------------
284
  -- This process mimick the rx-ctrl component which gets data from UDP/IP
285
  -- and gives it to hibi-transmitter. Enabled by main process.
286
  -----------------------------------------------------------------------------
287
  rx_ctrl : process (clk, rst_n)
288
    variable send_cnt  : integer   := 0;
289
    variable empty_cnt : integer   := 0;
290
    variable empty     : std_logic := '0';
291
  begin  -- process rx_ctrl
292
    if rst_n = '0' then                 -- asynchronous reset (active low)
293
 
294
    elsif clk'event and clk = '1' then  -- rising clock edge
295
 
296
      if send_en = '1' then
297
 
298
        -- Be empty every once and a while
299
        if empty = '0' and empty_cnt = empty_freq_c then
300
          -- Be empty every once and a while
301
          empty           := '1';
302
          rx_empty_to_duv <= '1';
303
          empty_cnt       := 0;
304
          if rx_re_from_duv = '1' and rx_empty_to_duv = '0' then
305
            send_cnt       := send_cnt + 1;
306
            rx_data_to_duv <= test_data(send_cnt mod test_data_amount_c);
307
          end if;
308
 
309
        elsif empty = '1' and rx_empty_to_duv = '1' then
310
          if empty_cnt = 3 then
311
            -- stop being empty
312
            empty     := '0';
313
            empty_cnt := 0;
314
 
315
          else
316
            empty_cnt := empty_cnt + 1;
317
          end if;
318
 
319
        else
320
          rx_empty_to_duv <= '0';
321
          rx_data_to_duv  <= test_data(send_cnt mod test_data_amount_c);
322
 
323
          if rx_re_from_duv = '1' and rx_empty_to_duv = '0' then
324
            send_cnt       := send_cnt + 1;
325
            empty_cnt      := empty_cnt + 1;
326
            rx_data_to_duv <= test_data(send_cnt mod test_data_amount_c);
327
          end if;
328
        end if;
329
 
330
      else
331
        if rx_re_from_duv = '1' and rx_empty_to_duv = '0' then
332
          send_cnt  := send_cnt + 1;
333
          empty_cnt := empty_cnt + 1;
334
        end if;
335
        rx_empty_to_duv <= '1';
336
        rx_data_to_duv  <= (others => 'Z');
337
      end if;
338
 
339
    end if;
340
  end process rx_ctrl;
341
 
342
 
343
  -----------------------------------------------------------------------------
344
  -- This process mimicks hibi wrapper and check data written by DUV.
345
  -----------------------------------------------------------------------------
346
  hibi_wrapper : process (clk, rst_n)
347
    variable full_cnt      : integer   := 0;
348
    variable full          : std_logic := '0';
349
    variable read_cnt      : integer   := 0;
350
    variable addr_cnt      : integer   := 0;
351
    variable header_coming : std_logic := '0';
352
  begin  -- process hibi_wrapper
353
    if rst_n = '0' then                 -- asynchronous reset (active low)
354
 
355
    elsif clk'event and clk = '1' then  -- rising clock edge
356
 
357
      if hibi_av_from_duv = '1' and hibi_we_from_duv = '1' and hibi_full_to_duv = '0' then
358
 
359
        assert hibi_data_from_duv = addresses_to_check(addr_cnt)
360
          report "Failure in test: Invalid address." severity failure;
361
 
362
        -- with current test structure, a header follows every time except
363
        -- after addr 4 and 7
364
        if addr_cnt = 4 or addr_cnt = 7 then
365
          addr_cnt := addr_cnt + 1;
366
        else
367
          header_coming := '1';
368
        end if;
369
 
370
      elsif header_coming = '1' and hibi_we_from_duv = '1' and hibi_full_to_duv = '0' then
371
        -- test cases
372
        -- 1. tx ack
373
        -- 2. rx ack right after the tx ack
374
        -- 3. new rx
375
        -- 4. little pause and tx nack
376
        -- 5. more data from the earlier rx
377
        -- 6. a little pause
378
        -- 7. more data
379
        -- 8. new rx
380
        -- 9. rx nack with new data waiting at rx fifo
381
        -- 10. rx continues
382
 
383
        case addr_cnt is
384
          when 0 =>
385
            -- tx ack
386
            assert
387
              hibi_data_from_duv(id_hi_idx_c downto id_lo_idx_c) = ack_header_id_c and
388
              hibi_data_from_duv(id_lo_idx_c-1) = '1'
389
              report "Failure in test: Invalid header (tx ack)" severity failure;
390
          when 1 =>
391
            -- rx ack
392
            assert
393
              hibi_data_from_duv(id_hi_idx_c downto id_lo_idx_c) = ack_header_id_c and
394
              hibi_data_from_duv(id_lo_idx_c-1) = '0'
395
              report "Failure in test: Invalid header (rx ack)" severity failure;
396
          when 2 =>
397
            -- new rx
398
            assert
399
              hibi_data_from_duv(id_hi_idx_c downto id_lo_idx_c) = rx_data_header_id_c and
400
              hibi_data_from_duv(id_lo_idx_c-1 downto id_lo_idx_c-tx_len_w_c) = rx_lens(0)
401
              report "Failure in test: Ivalid header (new rx)" severity failure;
402
          when 3 =>
403
            -- tx nack
404
            assert
405
              hibi_data_from_duv(id_hi_idx_c downto id_lo_idx_c) = nack_header_id_c and
406
              hibi_data_from_duv(id_lo_idx_c-1) = '1'
407
              report "Failure in test: Invalid header (tx nack)" severity failure;
408
          when 5 =>
409
            -- new rx #2
410
            assert
411
              hibi_data_from_duv(id_hi_idx_c downto id_lo_idx_c) = rx_data_header_id_c and
412
              hibi_data_from_duv(id_lo_idx_c-1 downto id_lo_idx_c-tx_len_w_c) = rx_lens(1)
413
              report "Failure in test: Invalid header (new rx #2)" severity failure;
414
          when 6 =>
415
            -- rx nack
416
            assert
417
              hibi_data_from_duv(id_hi_idx_c downto id_lo_idx_c) = nack_header_id_c and
418
              hibi_data_from_duv(id_lo_idx_c-1) = '0'
419
              report "Failure in test: Invalid header (rx nack)" severity failure;
420
          when others => null;
421
        end case;
422
 
423
        header_coming := '0';
424
        addr_cnt      := addr_cnt + 1;
425
 
426
 
427
      else
428
        -- Accept the incoming data. Pretend to be full occasionally.
429
 
430
        if full = '0' and full_cnt = full_freq_c then
431
          -- be full
432
          full             := '1';
433
          full_cnt         := 0;
434
          hibi_full_to_duv <= '1';
435
        end if;
436
 
437
        if full = '1' and hibi_full_to_duv = '1' then
438
          if full_cnt = 4 then
439
            -- stop being full
440
            full             := '0';
441
            full_cnt         := 0;
442
            hibi_full_to_duv <= '0';
443
          else
444
            full_cnt := full_cnt + 1;
445
          end if;
446
 
447
        else
448
          -- read normally
449
 
450
          if hibi_we_from_duv = '1' and hibi_full_to_duv = '0' then
451
            assert hibi_data_from_duv = test_data(read_cnt mod test_data_amount_c)
452
              report "Failure in test: Invalid data." severity failure;
453
 
454
            read_cnt := read_cnt + 1;
455
            read_tmp <= read_cnt;
456
            full_cnt := full_cnt + 1;
457
          end if;
458
        end if;
459
      end if;
460
    end if;
461
  end process hibi_wrapper;
462
end tb;

powered by: WebSVN 2.1.0

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