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_tx_ctrl.vhd] - Blame information for rev 183

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

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : Testbench for tx ctrl
3
-- Project    : UDP2HIBI
4
-------------------------------------------------------------------------------
5
-- File       : tb_tx_ctrl.vhd
6
-- Author     : Jussi Nieminen  <niemin95@galapagosinkeiju.cs.tut.fi>
7
-- Last update: 2012-03-21
8
-- Platform   : Sim only
9
-------------------------------------------------------------------------------
10
-- Description: A couple of hard-coded test cases for ctrl-registers.
11
-------------------------------------------------------------------------------
12
-- Revisions  :
13
-- Date        Version  Author  Description
14
-- 2009/12/14  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_tx_ctrl is
24
end tb_tx_ctrl;
25
 
26
 
27
architecture tb of tb_tx_ctrl is
28
 
29
  constant period_c              : time    := 20 ns;  -- 20 ns= 50 MHz
30
  constant frequency_c           : integer := 50_000_000;
31
  constant udp_ip_period_c       : time    := 40 ns;  -- 40ns = 25MHz
32
  constant multiclk_fifo_depth_c : integer := 10;
33
 
34
  signal clk            : std_logic := '1';
35
  signal clk_udp_to_duv : std_logic := '1';
36
  signal rst_n          : std_logic := '0';
37
 
38
 
39
 
40
  -- Send running numbers to constant IP-addr and port
41
  signal test_len : integer;            -- in bytes
42
  type test_data_type is array (0 to 19) of std_logic_vector(15 downto 0);
43
  constant test_data_c : test_data_type := (
44
    x"0100", x"0302", x"0504", x"0706", x"0908", x"0b0a", x"0d0c", x"0f0e", x"1110", x"1312",
45
    x"2120", x"2322", x"2524", x"2726", x"2928", x"2b2a", x"2d2c", x"2f2e", x"3130", x"3332");
46
  constant test_ip_c          : std_logic_vector(ip_addr_w_c-1 downto 0)  := x"01234567";
47
  constant test_dest_port_c   : std_logic_vector(udp_port_w_c-1 downto 0) := x"fefe";
48
  constant test_source_port_c : std_logic_vector(udp_port_w_c-1 downto 0) := x"cbcb";
49
 
50
 
51
  --
52
  -- Data and parameters to DUV
53
  --  data from receiver (=tb), goes to multiclk fifo inside duv
54
  signal tx_data_to_duv           : std_logic_vector(udp_block_data_w_c-1 downto 0) := (others => '0');
55
  signal tx_we_to_duv             : std_logic                                       := '0';
56
  signal tx_full_from_duv         : std_logic;
57
  --  parameters from hibi_receiver (=tb)
58
  signal new_tx_to_duv            : std_logic                                       := '0';
59
  signal tx_len_to_duv            : std_logic_vector(tx_len_w_c-1 downto 0)         := (others => '0');
60
  signal new_tx_ack_from_duv      : std_logic;
61
  signal timeout_to_duv           : std_logic_vector(timeout_w_c-1 downto 0)        := (others => '0');
62
  --  parameters from ctrl regs (=tb)
63
  signal tx_ip_to_duv             : std_logic_vector(ip_addr_w_c-1 downto 0)        := (others => '0');
64
  signal tx_dest_port_to_duv      : std_logic_vector(udp_port_w_c-1 downto 0)       := (others => '0');
65
  signal tx_source_port_to_duv    : std_logic_vector(udp_port_w_c-1 downto 0)       := (others => '0');
66
  signal timeout_release_from_duv : std_logic;
67
 
68
 
69
  --
70
  -- Data and parameters from DUV
71
  --  data to udp/ip, comes from multclk fifo inside duv
72
  signal tx_data_from_duv       : std_logic_vector(udp_block_data_w_c-1 downto 0);
73
  signal tx_data_valid_from_duv : std_logic;
74
  signal tx_re_to_duv           : std_logic := '0';
75
  --  parameters to udp/ip
76
  signal new_tx_from_duv        : std_logic;
77
  signal tx_len_from_duv        : std_logic_vector(tx_len_w_c-1 downto 0);
78
  signal dest_ip_from_duv       : std_logic_vector(ip_addr_w_c-1 downto 0);
79
  signal dest_port_from_duv     : std_logic_vector(udp_port_w_c-1 downto 0);
80
  signal source_port_from_duv   : std_logic_vector(udp_port_w_c-1 downto 0);
81
 
82
 
83
 
84
  signal locked : std_logic := '0';
85
 
86
  -- Signals used for communication between processes and 2 state machines
87
  signal write_data  : std_logic := '0';  -- request write to start
88
  signal write_done  : std_logic;
89
  type   write_state_type is (idle, writing);
90
  signal write_state : write_state_type;
91
 
92
  signal read_data  : std_logic := '0';  -- request read to start
93
  signal read_done  : std_logic;
94
  type   read_state_type is (rx_idle, reading);
95
  signal read_state : read_state_type;
96
 
97
 
98
 
99
  -- For timeout testing
100
  signal   do_timeout          : std_logic := '0';  -- test timeout or not?
101
  constant last_correct_word_c : integer   := 5;    -- #words before stopping
102
  constant test_timeout_c      : integer   := 50;   -- #cycles that DUV waits
103
 
104
  -- Tb should finish within certain #cycles, otherwise it is stuck
105
  constant tb_timeout_value_c : integer := 10_000;  -- #cycles
106
  signal   timeout_cnt        : integer;
107
 
108
 
109
  -------------------------------------------------------------------------------
110
begin  -- tb
111
  -------------------------------------------------------------------------------
112
 
113
 
114
  -- clk and reset generation
115
  rst_n          <= '1'                after 4*period_c;
116
  clk            <= not clk            after period_c/2;
117
  clk_udp_to_duv <= not clk_udp_to_duv after udp_ip_period_c/2;
118
 
119
 
120
 
121
  duv : entity work.tx_ctrl
122
    generic map (
123
      frequency_g           => frequency_c,
124
      multiclk_fifo_depth_g => multiclk_fifo_depth_c
125
      )
126
    port map (
127
 
128
      clk               => clk,
129
      clk_udp           => clk_udp_to_duv,
130
      rst_n             => rst_n,
131
      -- for multiclk fifo
132
      tx_data_in        => tx_data_to_duv,
133
      tx_we_in          => tx_we_to_duv,
134
      tx_full_out       => tx_full_from_duv,
135
      -- from multiclk fifo to udp/ip
136
      tx_data_out       => tx_data_from_duv,
137
      tx_data_valid_out => tx_data_valid_from_duv,
138
      tx_re_in          => tx_re_to_duv,
139
      -- other signals to udp/ip
140
      new_tx_out        => new_tx_from_duv,
141
      tx_len_out        => tx_len_from_duv,
142
      dest_ip_out       => dest_ip_from_duv,
143
      dest_port_out     => dest_port_from_duv,
144
      source_port_out   => source_port_from_duv,
145
      -- signals to and from hibi_receiver
146
      new_tx_in         => new_tx_to_duv,
147
      tx_len_in         => tx_len_to_duv,
148
      new_tx_ack_out    => new_tx_ack_from_duv,
149
      timeout_in        => timeout_to_duv,
150
 
151
      -- signals to and from ctrl regs
152
      tx_ip_in            => tx_ip_to_duv,
153
      tx_dest_port_in     => tx_dest_port_to_duv,
154
      tx_source_port_in   => tx_source_port_to_duv,
155
      timeout_release_out => timeout_release_from_duv
156
      );
157
 
158
 
159
  -------------------------------------------------------------------------------
160
  -- This process models hibi receiver and ctrl regs
161
  -------------------------------------------------------------------------------
162
  main : process
163
  begin  -- process
164
 
165
    if rst_n = '0' then
166
      wait until rst_n = '1';
167
    end if;
168
 
169
    wait for period_c*4;
170
 
171
 
172
    tx_ip_to_duv          <= test_ip_c;
173
    tx_dest_port_to_duv   <= test_dest_port_c;
174
    tx_source_port_to_duv <= test_source_port_c;
175
 
176
    -- Perform multiple tests with different test_len
177
    for k in 1 to 40 loop
178
 
179
      test_len <= k;
180
      wait for period_c;
181
 
182
      for n in 0 to 1 loop
183
 
184
 
185
 
186
        -- Cause timeout at the second round on purpose, when len is long enough
187
        if n = 1 and k > 2*last_correct_word_c + 2 then
188
          do_timeout <= '1';
189
        end if;
190
 
191
 
192
 
193
 
194
        -- Ask the other test process to start writing, wait that it starts,
195
        -- and give parameters
196
        write_data <= '1';
197
        wait for period_c*2;
198
 
199
        new_tx_to_duv  <= '1';
200
        tx_len_to_duv  <= std_logic_vector(to_unsigned(test_len, tx_len_w_c));
201
        timeout_to_duv <= std_logic_vector(to_unsigned(test_timeout_c, timeout_w_c));
202
 
203
        wait for period_c;
204
        write_data <= '0';
205
 
206
 
207
        -- Wait that DUV acknowledges the data
208
        if new_tx_ack_from_duv = '0' then
209
          wait until new_tx_ack_from_duv = '1';
210
        end if;
211
        wait for period_c;
212
 
213
        new_tx_to_duv <= '0';
214
        wait for period_c;
215
 
216
 
217
 
218
        -- Check that outputs to udp/ip are correct
219
        assert
220
          new_tx_from_duv = '1'
221
          and to_integer(unsigned(tx_len_from_duv)) = test_len
222
          and dest_ip_from_duv = test_ip_c
223
          and source_port_from_duv = test_source_port_c
224
          and dest_port_from_duv = test_dest_port_c
225
          report "Failure in test : Invalid tx info to UDP/IP." severity failure;
226
 
227
 
228
        -- Ask reading process to start
229
        read_data <= '1';
230
        -- longer wait because of slower clk in udp
231
        wait for period_c*3;
232
        read_data <= '0';
233
 
234
 
235
        if write_done = '0' then
236
          wait until write_done = '1';
237
        end if;
238
 
239
 
240
        -- Test timeout
241
        if do_timeout = '1' then
242
          wait for (test_timeout_c + 1) * period_c;
243
          -- now it should happen
244
          wait for period_c;
245
          -- now timeout_release_from_duv should be up
246
          assert timeout_release_from_duv = '1'
247
            report "No timeout release from duv." severity failure;
248
          assert tx_full_from_duv = '1'
249
            report "Full signal not lifted after timeout." severity failure;
250
        end if;
251
 
252
 
253
        if read_done = '0' then
254
          wait until read_done = '1';
255
        end if;
256
 
257
 
258
      end loop;  -- n
259
 
260
      do_timeout <= '0';
261
      wait for period_c*30;
262
    end loop;  -- k
263
 
264
    wait for period_c*30;
265
 
266
    report "Simulation ended." severity failure;
267
 
268
  end process main;
269
 
270
  -----------------------------------------------------------------------------
271
  -- This process models hibi receiver. Writes test_len words to DUV.
272
  -----------------------------------------------------------------------------
273
  writer : process (clk, rst_n)
274
    variable write_cnt : integer := 0;
275
  begin  -- process writer
276
    if rst_n = '0' then                 -- asynchronous reset (active low)
277
 
278
      tx_data_to_duv <= (others => '0');
279
      tx_we_to_duv   <= '0';
280
      write_state    <= idle;
281
      write_done     <= '0';
282
 
283
    elsif clk'event and clk = '1' then  -- rising clock edge
284
 
285
      case write_state is
286
        when idle =>
287
          tx_we_to_duv <= '0';
288
 
289
          -- Start writing when main process asks that
290
          if write_data = '1' then
291
            write_state <= writing;
292
            write_done  <= '0';
293
          end if;
294
 
295
        when writing =>
296
 
297
          if tx_full_from_duv = '0' then
298
 
299
            if write_cnt = test_len/2 + (test_len mod 2) then
300
              -- All has been written
301
              write_done   <= '1';
302
              write_cnt    := 0;
303
              write_state  <= idle;
304
              tx_we_to_duv <= '0';
305
 
306
            else
307
              -- Write two bytes at a time
308
              tx_data_to_duv <= test_data_c(write_cnt);
309
              tx_we_to_duv   <= '1';
310
              write_cnt      := write_cnt + 1;
311
 
312
              -- Occasionally, stop writing after few words.  Check elsewhere that
313
              -- DUV does correct timeout operation
314
              if do_timeout = '1' and write_cnt = last_correct_word_c + 1 then
315
                write_done  <= '1';
316
                write_state <= idle;
317
                write_cnt   := 0;
318
              end if;
319
            end if;
320
          end if;
321
 
322
        when others => null;
323
      end case;
324
 
325
    end if;
326
  end process writer;
327
 
328
 
329
 
330
 
331
 
332
  -----------------------------------------------------------------------------
333
  -- This models UDP/IP
334
  -----------------------------------------------------------------------------
335
  reader : process (clk_udp_to_duv, rst_n)
336
    variable read_cnt : integer;
337
  begin  -- process reader
338
    if rst_n = '0' then                 -- asynchronous reset (active low)
339
      read_state <= rx_idle;
340
      read_done  <= '0';
341
      read_cnt   := 0;
342
 
343
    elsif clk_udp_to_duv'event and clk_udp_to_duv = '1' then
344
                                        -- rising clock edge
345
 
346
      case read_state is
347
 
348
 
349
        when rx_idle =>
350
          tx_re_to_duv <= '0';
351
 
352
          -- Start writing when main process asks that
353
          if read_data = '1' then
354
            read_state <= reading;
355
            read_done  <= '0';
356
          end if;
357
 
358
        when reading =>
359
 
360
          if tx_data_valid_from_duv = '1' then
361
            tx_re_to_duv <= '1';
362
          else
363
            tx_re_to_duv <= '0';
364
          end if;
365
 
366
          if tx_re_to_duv = '1' and tx_data_valid_from_duv = '1' then
367
 
368
            -- Check that data is valid
369
            if do_timeout = '1' and read_cnt > last_correct_word_c then
370
              assert tx_data_from_duv = x"0000"
371
                report "Invalid data from duv after timeout!" severity failure;
372
            else
373
              assert tx_data_from_duv = test_data_c(read_cnt)
374
                report "Invalid data from duv during normal action!" severity failure;
375
            end if;
376
 
377
            read_cnt := read_cnt + 1;
378
 
379
            if read_cnt = test_len/2 + (test_len mod 2) then
380
              -- All has been read
381
              read_state <= rx_idle;
382
              read_done  <= '1';
383
              read_cnt   := 0;
384
            end if;
385
 
386
          end if;
387
 
388
        when others => null;
389
      end case;
390
 
391
    end if;
392
  end process reader;
393
 
394
 
395
 
396
  -----------------------------------------------------------------------------
397
  -- Make sure that the testbench doesn't get stuck forever
398
  -----------------------------------------------------------------------------
399
  tb_timeout : process (clk, rst_n)
400
 
401
  begin  -- process tb_timeout
402
    if rst_n = '0' then                 -- asynchronous reset (active low)
403
      timeout_cnt <= 0;
404
    elsif clk'event and clk = '1' then  -- rising clock edge
405
      if timeout_cnt = tb_timeout_value_c then
406
        report "Testbench timeout, something has failed!" severity failure;
407
      else
408
        timeout_cnt <= timeout_cnt + 1;
409
      end if;
410
    end if;
411
  end process tb_timeout;
412
 
413
 
414
 
415
end tb;

powered by: WebSVN 2.1.0

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