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.communication/] [n2h2/] [1.0/] [tb/] [blocks/] [tb_n2h2_rx.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : Testbench for design "n2h2_rx"
3
-------------------------------------------------------------------------------
4
-- File       : tb_n2h2_rx.vhdl
5
-- Author     : kulmala3
6
-- Created    : 22.03.2005
7
-- Last update: 2011-11-11
8
-- Description: 
9
-------------------------------------------------------------------------------
10
-- Copyright (c) 2005 
11
-------------------------------------------------------------------------------
12
-- Revisions  :
13
-- Date        Version  Author  Description
14
-- 22.03.2005  1.0      AK      Created
15
-- 2011-11-04  1.01     ES      Commenting
16
-------------------------------------------------------------------------------
17
-------------------------------------------------------------------------------
18
-- Funbase IP library Copyright (C) 2011 TUT Department of Computer Systems
19
--
20
-- This file is part of HIBI
21
--
22
-- This source file may be used and distributed without
23
-- restriction provided that this copyright statement is not
24
-- removed from the file and that any derivative work contains
25
-- the original copyright notice and the associated disclaimer.
26
--
27
-- This source file is free software; you can redistribute it
28
-- and/or modify it under the terms of the GNU Lesser General
29
-- Public License as published by the Free Software Foundation;
30
-- either version 2.1 of the License, or (at your option) any
31
-- later version.
32
--
33
-- This source is distributed in the hope that it will be
34
-- useful, but WITHOUT ANY WARRANTY; without even the implied
35
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
36
-- PURPOSE.  See the GNU Lesser General Public License for more
37
-- details.
38
--
39
-- You should have received a copy of the GNU Lesser General
40
-- Public License along with this source; if not, download it
41
-- from http://www.opencores.org/lgpl.shtml
42
-------------------------------------------------------------------------------
43
 
44
library ieee;
45
use ieee.std_logic_1164.all;
46
use ieee.std_logic_arith.all;
47
use ieee.std_logic_unsigned.all;
48
use work.tb_n2h2_pkg.all;
49
-- use work.log2_pkg.all;
50
 
51
 
52
entity tb_n2h2_rx is
53
 
54
end tb_n2h2_rx;
55
 
56
 
57
 
58
architecture tb of tb_n2h2_rx is
59
 
60
  -- Includes following components
61
  -- DUT                i.e. Nios-to-HIBI v.2 DMA controller
62
  -- config_writer      initializes DMA
63
  -- config_reader      reads the configuration just in case
64
  -- config_mux         multiplexes addr to DUT from cfg_writer and reader
65
  -- hibi_sender        models incoming data from HIBI bus
66
  -- avalon_readers     model the DP-RAM where DMA writes      
67
 
68
 
69
  -- Rough data_flow
70
  --
71
  --   cfdg_writer  --->  mux  ---> DUT <---- hibi_sender
72
  --                       ^         |
73
  --   cfg_reader < -------|         |-------> avalon_reader(s)
74
  --
75
  --
76
 
77
 
78
  constant conf_file_hsender_c : string := "tbrx_conf_hibisend.dat";
79
  constant conf_file_c         : string := "tbrx_conf_rx.dat";
80
  constant data_file_c         : string := "tbrx_data_file.dat";
81
 
82
  -- component n2h2 rx generics
83
  constant n_chans_c          : integer := 3;   -- # simultaneous rx transfers
84
  constant n_chans_bits_c     : integer := 2;   -- log2(n_chans_c)
85
  constant data_width_c       : integer := 64;  -- 32b and 64b are legal
86
  constant addr_width_c       : integer := 32;  -- In bits
87
  constant comm_width_c       : integer := 5;   -- In bits
88
  constant hibi_addr_cmp_hi_c : integer := 31;  -- How many incoming addr 
89
  constant hibi_addr_cmp_lo_c : integer := 0;   --  addr bits are used
90
  constant amount_width_c     : integer := 5;   -- 2**5 flits max
91
 
92
  -- clock and reset
93
  constant Period : time := 10 ns;
94
 
95
 
96
  signal clk   : std_logic := '0';
97
  signal clk2  : std_logic := '0';
98
  signal rst_n : std_logic := '0';
99
 
100
 
101
  -- cpu side signals
102
 
103
  -- system control signals.
104
  -- TB has state machine taht starts and stops helper blocks, such
105
  -- config_writer and hibi_sender
106
  type system_control_states is (config, wait_for_config, check_config,
107
                                 wait_check, wait_for_irq);
108
  signal system_control_r    : system_control_states;
109
  signal hibi_sender_start   : std_logic;
110
  signal hibi_sender_rst_n   : std_logic;
111
  type   chan_addr_array is array (n_chans_c-1 downto 0) of std_logic_vector(addr_width_c-1 downto 0);
112
  signal my_own_addr         : chan_addr_array;
113
 
114
  signal avalon_reader_rst_n : std_logic;
115
  signal hibi_data_read      : std_logic;
116
 
117
  signal irq_was_up  : std_logic;
118
  signal irq_counter : integer;
119
 
120
 
121
 
122
  -- Component ports: from CPU (=cfg writer), from HIBI, and to memory 
123
  signal avalon_cfg_addr_to_dma       : std_logic_vector(log2(n_chans_c)+conf_bits_c-1 downto 0);
124
  signal avalon_cfg_writedata_to_dma  : std_logic_vector(addr_width_c-1 downto 0);
125
  signal avalon_cfg_we_to_dma         : std_logic;
126
  signal avalon_cfg_readdata_from_dma : std_logic_vector(addr_width_c-1 downto 0);
127
  signal avalon_cfg_re_to_dma         : std_logic;
128
  signal avalon_cfg_cs_to_dma         : std_logic;
129
  signal rx_irq_from_dma              : std_logic;
130
  signal tx_start_from_dma            : std_logic;
131
  signal tx_status_done_to_dma        : std_logic;
132
 
133
  signal hibi_av_to_dma    : std_logic;
134
  signal hibi_data_to_dma  : std_logic_vector(data_width_c-1 downto 0);
135
  signal hibi_comm_to_dma  : std_logic_vector(4 downto 0);
136
  signal hibi_empty_to_dma : std_logic;
137
  signal hibi_re_from_dma  : std_logic;
138
 
139
  signal avalon_addr_from_dma      : std_logic_vector(addr_width_c-1 downto 0);
140
  signal avalon_writedata_from_dma : std_logic_vector(data_width_c-1 downto 0);
141
  signal avalon_we_from_dma        : std_logic;
142
  signal avalon_be_from_dma        : std_logic_vector(data_width_c/8-1 downto 0);
143
  signal avalon_waitrequest_to_dma : std_logic;
144
  signal avalon_waitreqvec_to_dma  : std_logic_vector(n_chans_c-1 downto 0);
145
 
146
 
147
 
148
  -- Config writer
149
  signal start_to_cfgw             : std_logic;
150
  signal avalon_cfg_addr_from_cfgw : std_logic_vector(log2(n_chans_c)+conf_bits_c-1 downto 0);
151
  signal avalon_cfg_cs_from_cfgw   : std_logic;
152
  signal done_from_cfgw            : std_logic;
153
  signal init_to_cfgw              : std_logic;
154
 
155
  -- Config reader
156
  signal start_to_cfgr             : std_logic;
157
  signal avalon_cfg_addr_from_cfgr : std_logic_vector(log2(n_chans_c)+conf_bits_c-1 downto 0);
158
  signal avalon_cfg_cs_from_cfgr   : std_logic;
159
  signal done_from_cfgr            : std_logic;
160
 
161
  -- Tb <-> hibi writer
162
  signal done_from_hibi_sender : std_logic;
163
  signal pause_hibi_send       : std_logic;
164
  signal pause_ack_hibi_send   : std_logic;
165
 
166
  -- Tb <-> Avalon reader
167
  signal init_to_reader           : std_logic_vector(n_chans_c-1 downto 0);
168
  signal not_my_addr_from_readers : std_logic_vector(n_chans_c-1 downto 0);
169
 
170
 
171
 
172
begin  -- tb
173
 
174
  tx_status_done_to_dma <= '0';
175
 
176
  --
177
  -- This process gives start pulses the helper components
178
  -- and check interrupt reuqest from the DMA
179
  -- 
180
  process (clk, rst_n)
181
  begin  -- process
182
    if rst_n = '0' then                 -- asynchronous reset (active low)
183
      system_control_r  <= config;
184
      start_to_cfgr     <= '0';
185
      start_to_cfgw     <= '0';
186
      hibi_sender_start <= '0';
187
      --      reset_buses_r <= '1';
188
      init_to_cfgw      <= '0';
189
      irq_was_up        <= '0';
190
      irq_counter       <= 0;
191
      pause_hibi_send   <= '0';
192
      for i in n_chans_c-1 downto 0 loop
193
        init_to_reader(i) <= '0';
194
      end loop;  -- i
195
 
196
    elsif clk'event and clk = '1' then  -- rising clock edge
197
      case system_control_r is
198
        when config =>
199
          -- write the dma config
200
          start_to_cfgw    <= '1';
201
          system_control_r <= wait_for_config;
202
 
203
        when wait_for_config =>
204
          start_to_cfgw <= '0';
205
          -- wait until it finishes configuring all channels
206
          if done_from_cfgw = '1' then
207
            system_control_r <= check_config;
208
          end if;
209
 
210
        when check_config =>
211
          -- check that the config is written alright
212
          start_to_cfgr    <= '1';
213
          system_control_r <= wait_check;
214
 
215
        when wait_check =>
216
          -- wait for check to complete
217
          start_to_cfgr <= '0';
218
          if done_from_cfgr = '1' then
219
            system_control_r  <= wait_for_irq;
220
            -- unleash the hibi_sender
221
            hibi_sender_start <= '1';
222
          end if;
223
 
224
        when wait_for_irq =>
225
          -- check that irq amounts etc are all right.
226
          -- TODO stuff here, e.g. acknowleding the interrupt
227
          init_to_cfgw <= '0';
228
          if done_from_cfgw = '1' then
229
            pause_hibi_send <= '0';
230
          end if;
231
 
232
          if rx_irq_from_dma = '1' and irq_was_up = '0' then
233
            irq_counter <= irq_counter + 1;
234
            irq_was_up  <= '1';
235
          elsif rx_irq_from_dma = '0' then
236
            irq_was_up <= '0';
237
          end if;
238
 
239
          if irq_counter = n_chans_c then
240
            if pause_ack_hibi_send = '1' and hibi_empty_to_dma = '1' then
241
              init_to_cfgw    <= '1';
242
              pause_hibi_send <= '1';
243
              irq_counter     <= 0;
244
            else
245
              init_to_cfgw    <= '0';
246
              pause_hibi_send <= '1';
247
            end if;
248
          end if;
249
 
250
        when others => null;
251
      end case;
252
 
253
 
254
 
255
    end if;
256
  end process;
257
 
258
  --
259
  -- OR the wait requests together
260
  --
261
  waitreq : process (avalon_waitreqvec_to_dma)
262
  begin  -- process waitreq
263
    if avalon_waitreqvec_to_dma /= conv_std_logic_vector(0, n_chans_c) then
264
      avalon_waitrequest_to_dma <= '1';
265
    else
266
      avalon_waitrequest_to_dma <= '0';
267
    end if;
268
 
269
  end process waitreq;
270
 
271
  --
272
  -- Design-undet-test instantiation
273
  -- 
274
  DUT : entity work.n2h2_rx_channels
275
    generic map (
276
      n_chans_g          => n_chans_c,
277
      n_chans_bits_g     => n_chans_bits_c,
278
      data_width_g       => data_width_c,
279
      addr_width_g       => addr_width_c,
280
      hibi_addr_cmp_hi_g => hibi_addr_cmp_hi_c,
281
      hibi_addr_cmp_lo_g => hibi_addr_cmp_lo_c,
282
      amount_width_g     => amount_width_c)
283
    port map (
284
      clk                     => clk,
285
      rst_n                   => rst_n,
286
      -- Outgoing data to memory
287
      avalon_addr_out         => avalon_addr_from_dma,
288
      avalon_writedata_out    => avalon_writedata_from_dma,
289
      avalon_we_out           => avalon_we_from_dma,
290
      avalon_be_out           => avalon_be_from_dma,
291
      avalon_waitrequest_in   => avalon_waitrequest_to_dma,
292
      -- Incoming data from hibi
293
      hibi_av_in              => hibi_av_to_dma,
294
      hibi_data_in            => hibi_data_to_dma,
295
      hibi_comm_in            => hibi_comm_to_dma,
296
      hibi_empty_in           => hibi_empty_to_dma,
297
      hibi_re_out             => hibi_re_from_dma,
298
      -- Incoming configurationg from Avalon (=cpu = conf writer)
299
      avalon_cfg_addr_in      => avalon_cfg_addr_to_dma,
300
      avalon_cfg_writedata_in => avalon_cfg_writedata_to_dma,
301
      avalon_cfg_we_in        => avalon_cfg_we_to_dma,
302
      avalon_cfg_readdata_out => avalon_cfg_readdata_from_dma,
303
      avalon_cfg_re_in        => avalon_cfg_re_to_dma,
304
      avalon_cfg_cs_in        => avalon_cfg_cs_to_dma,
305
      rx_irq_out              => rx_irq_from_dma,
306
      tx_start_out            => tx_start_from_dma,
307
      tx_status_done_in       => tx_status_done_to_dma
308
      );
309
 
310
 
311
  --
312
  -- This configures DMA for receiving
313
  -- 
314
  avalon_cfg_writer_1 : entity work.avalon_cfg_writer
315
    generic map (
316
      n_chans_g    => n_chans_c,
317
      data_width_g => addr_width_c,
318
      conf_file_g  => conf_file_c)
319
    port map (
320
      clk                      => clk,
321
      rst_n                    => rst_n,
322
      start_in                 => start_to_cfgw,
323
      avalon_cfg_addr_out      => avalon_cfg_addr_from_cfgw,
324
      avalon_cfg_writedata_out => avalon_cfg_writedata_to_dma,
325
      avalon_cfg_we_out        => avalon_cfg_we_to_dma,
326
      avalon_cfg_cs_out        => avalon_cfg_cs_from_cfgw,
327
      init_in                  => init_to_cfgw,
328
      done_out                 => done_from_cfgw
329
      );
330
 
331
  --
332
  -- This reads the above configuration from DMA
333
  -- 
334
  -- different clock...
335
  avalon_cfg_reader_1 : entity work.avalon_cfg_reader
336
    generic map (
337
      n_chans_g    => n_chans_c,
338
      data_width_g => addr_width_c,
339
      conf_file_g  => conf_file_c)
340
    port map (
341
      clk                    => clk2,
342
      rst_n                  => rst_n,
343
      start_in               => start_to_cfgr,
344
      avalon_cfg_addr_out    => avalon_cfg_addr_from_cfgr,
345
      avalon_cfg_readdata_in => avalon_cfg_readdata_from_dma,
346
      avalon_cfg_re_out      => avalon_cfg_re_to_dma,
347
      avalon_cfg_cs_out      => avalon_cfg_cs_from_cfgr,
348
      done_out               => done_from_cfgr
349
      );
350
 
351
  --
352
  -- Mimic Avalon so that configuration can be both written and read
353
  -- to/from DMA
354
  cfg_mux : process (avalon_cfg_cs_from_cfgw, avalon_cfg_cs_from_cfgr,
355
                     avalon_cfg_addr_from_cfgr, avalon_cfg_addr_from_cfgw)
356
    variable vector : std_logic_vector(1 downto 0);
357
  begin  -- process cfg mux
358
    vector := avalon_cfg_cs_from_cfgw & avalon_cfg_cs_from_cfgr;
359
    case vector is
360
      when "01" =>
361
        avalon_cfg_addr_to_dma <= avalon_cfg_addr_from_cfgr;
362
        avalon_cfg_cs_to_dma   <= avalon_cfg_cs_from_cfgr;
363
 
364
      when others =>
365
        --      when "00" | "10" | "11" =>
366
        avalon_cfg_addr_to_dma <= avalon_cfg_addr_from_cfgw;
367
        avalon_cfg_cs_to_dma   <= avalon_cfg_cs_from_cfgw;
368
 
369
    end case;
370
 
371
  end process cfg_mux;
372
 
373
 
374
 
375
  --
376
  -- This models the traffic coming from HIBI bus to DMA.
377
  -- 
378
  hibi_sender_n2h2_1 : entity work.hibi_sender_n2h2
379
    generic map (
380
      --data_1_g     => data_file_c,      -- obsolete?
381
      conf_file_g  => conf_file_hsender_c,
382
      own_number_g => 0,                -- used to be 4, ES 2011-11-11
383
      comm_width_g => comm_width_c,
384
      data_width_g => data_width_c
385
      )
386
    port map (
387
      clk             => clk,
388
      rst_n           => hibi_sender_rst_n,
389
      pause_in        => pause_hibi_send,
390
      pause_ack       => pause_ack_hibi_send,
391
      done_out        => done_from_hibi_sender,
392
 
393
      agent_av_out    => hibi_av_to_dma,
394
      agent_data_out  => hibi_data_to_dma,
395
      agent_comm_out  => hibi_comm_to_dma,
396
      agent_empty_out => hibi_empty_to_dma,
397
      agent_re_in     => hibi_re_from_dma
398
      );
399
 
400
  hibi_sender_rst_n <= hibi_sender_start and rst_n;
401
 
402
 
403
 
404
  --
405
  -- Check the data written to mem. There is a separate
406
  -- checker module (avalon_reader) for each rx channel
407
  --
408
  avalon_reader_rst_n <= rst_n;
409
  avalon : for i in n_chans_c-1 downto 0 generate
410
    --my_own_addr(i) <= conv_std_logic_vector(ava_addresses_c(i), data_width_c);
411
    my_own_addr(i) <= conv_std_logic_vector(ava_addresses_c(i), addr_width_c);
412
 
413
    avalon_reader_i : entity work.avalon_reader
414
      generic map (
415
        -- data_file_g  => data_file_c,
416
        addr_width_g => addr_width_c,
417
        data_width_g => data_width_c
418
        )
419
      port map (
420
        clk                    => clk,
421
        rst_n                  => avalon_reader_rst_n,
422
        avalon_addr_in         => avalon_addr_from_dma,
423
        avalon_writedata_in    => avalon_writedata_from_dma,
424
        avalon_we_in           => avalon_we_from_dma,
425
        avalon_be_in           => avalon_be_from_dma,
426
        waitrequest_real_in    => avalon_waitrequest_to_dma,
427
        avalon_waitrequest_out => avalon_waitreqvec_to_dma(i),
428
        increment_data_ptr     => hibi_data_read,  -- obsolete?
429
        my_own_addr_in         => my_own_addr(i),
430
        not_my_addr_out        => not_my_addr_from_readers(i),
431
        init_in                => pause_hibi_send
432
        );
433
  end generate avalon;
434
 
435
  hibi_data_read    <= hibi_empty_to_dma nor hibi_av_to_dma;  -- obsolete?
436
  assert not_my_addr_from_readers /= "111" report "Address mismatch on avalon!" severity error;
437
 
438
 
439
 
440
 
441
 
442
  --
443
  -- Generate clocks and reset
444
  --
445
 
446
  CLOCK1 : process                      -- generate clock signal for design
447
    variable clktmp : std_logic := '0';
448
  begin
449
    wait for PERIOD/2;
450
    clktmp := not clktmp;
451
    Clk    <= clktmp;
452
  end process CLOCK1;
453
 
454
  CLOCK2 : process                      -- generate clock signal for design
455
    variable clktmp : std_logic := '0';
456
  begin
457
    clktmp := not clktmp;
458
    Clk2   <= clktmp;
459
    wait for PERIOD/2;
460
  end process CLOCK2;
461
 
462
  RESET : process
463
  begin
464
    Rst_n <= '0';                       -- Reset the testsystem
465
    wait for 6*PERIOD;                  -- Wait 
466
    Rst_n <= '1';                       -- de-assert reset
467
    wait;
468
  end process RESET;
469
 
470
 
471
 
472
end tb;
473
 
474
-------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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