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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : A block which sends data to HIBI
3
-- Project    : 
4
-------------------------------------------------------------------------------
5
-- File       : hibi_sender_n2h2.vhd
6
-- Author     : kulmala3
7
-- Created    : 13.01.2005
8
-- Last update: 2011-11-11
9
-- Description: This blocks creates traffic for the HIBI block.
10
--              Reads a configraution file, where each line has 3 integers:
11
--              dest_agent delay_cycles num_of_words
12
--
13
--              This is derived from a block "hibi_sender" but modified for
14
--              testing Nios-to-HIBI2 (n2h2).
15
-------------------------------------------------------------------------------
16
-- Copyright (c) 2005 
17
-------------------------------------------------------------------------------
18
-- Revisions  :
19
-- Date        Version  Author  Description
20
-- 13.01.2005  1.0      AK      Created
21
-------------------------------------------------------------------------------
22
-------------------------------------------------------------------------------
23
-- Funbase IP library Copyright (C) 2011 TUT Department of Computer Systems
24
--
25
-- This file is part of HIBI
26
--
27
-- This source file may be used and distributed without
28
-- restriction provided that this copyright statement is not
29
-- removed from the file and that any derivative work contains
30
-- the original copyright notice and the associated disclaimer.
31
--
32
-- This source file is free software; you can redistribute it
33
-- and/or modify it under the terms of the GNU Lesser General
34
-- Public License as published by the Free Software Foundation;
35
-- either version 2.1 of the License, or (at your option) any
36
-- later version.
37
--
38
-- This source is distributed in the hope that it will be
39
-- useful, but WITHOUT ANY WARRANTY; without even the implied
40
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
41
-- PURPOSE.  See the GNU Lesser General Public License for more
42
-- details.
43
--
44
-- You should have received a copy of the GNU Lesser General
45
-- Public License along with this source; if not, download it
46
-- from http://www.opencores.org/lgpl.shtml
47
-------------------------------------------------------------------------------
48
 
49
 
50
library ieee;
51
use ieee.std_logic_1164.all;
52
use ieee.std_logic_arith.all;
53
use ieee.std_logic_unsigned.all;
54
use std.textio.all;
55
use work.tb_n2h2_pkg.all;               -- incl. e.g. const array "addresses"
56
 
57
entity hibi_sender_n2h2 is
58
 
59
  generic (
60
    --data_1_g     : string  := "";       -- obsolete?
61
    conf_file_g  : string  := "";
62
    own_number_g : integer := 0;        -- 1-4
63
    comm_width_g : integer := 5;
64
    n_dest_g : integer := 3;
65
    data_width_g : integer := 0);
66
 
67
  port (
68
    clk       : in  std_logic;
69
    rst_n     : in  std_logic;
70
    pause_in  : in  std_logic;
71
    pause_ack : out std_logic;
72
    done_out  : out std_logic;          -- if this has finished
73
 
74
    -- HIBI WRAPPER PORTS
75
    agent_av_out    : out std_logic;
76
    agent_data_out  : out std_logic_vector(data_width_g-1 downto 0);
77
    agent_comm_out  : out std_logic_vector (comm_width_g-1 downto 0);
78
    agent_empty_out : out std_logic;
79
    agent_re_in     : in  std_logic
80
 
81
    -- note that this only sends, so these signals are removed
82
    --    agent_empty_in : in  std_logic;
83
    --    agent_one_d_in : in  std_logic;
84
    --    agent_re_out   : out std_logic;
85
    --    agent_av_in    : in  std_logic;
86
    --    agent_comm_in  : in  std_logic_vector (comm_width_g-1 downto 0);
87
    --    agent_data_in  : in  std_logic_vector(data_width_g-1 downto 0);
88
    -- aren't needed
89
    );
90
 
91
end hibi_sender_n2h2;
92
 
93
 
94
architecture rtl of hibi_sender_n2h2 is
95
 
96
 
97
  -- Use only one command: basic write operation
98
  constant hibi_write_c : std_logic_vector(comm_width_g-1 downto 0) := "00010";
99
 
100
 
101
 
102
 
103
  -- Registers may be reset to 'Z' to 'X' so that reset state is clearly
104
  -- distinguished from active state. Using dbg_level+Rst_Value array, the rst value may
105
  -- be easily set to '0' for synthesis.
106
  constant rst_value_arr : std_logic_vector (6 downto 0) := 'X' & 'Z' & 'X' & 'Z' & 'X' & 'Z' & '0';
107
 
108
  -- right now gives a lot of warnings when other than 0
109
  constant dbg_level : integer range 0 to 3 := 0;  -- 0= no debug, use 0 for synthesis
110
 
111
 
112
  -- This procedure reads the (opened) file. The file line structure is as follows:
113
  -- 1st integer: destination agent (1,2,3,4) (not own!)
114
  -- 2nd integer: delay cycles before sending
115
  -- 3rd integer: amount of data words to be sent.
116
  procedure read_hibi_conf_file (
117
    dest_agent_n  : out integer;
118
    delay         : out integer;
119
    amount        : out integer;
120
    file conf_dat :     text) is
121
 
122
    variable file_row         : line;
123
    variable dest_agent_n_var : integer;
124
    variable delay_var        : integer;
125
    variable amount_var       : integer;
126
    variable dest_ok          : boolean := false;  -- ES 2011-11-11
127
  begin  -- read_hibi_conf_file
128
 
129
    -- Loop until finding a line that is not a comment
130
    while dest_ok = false and not(endfile(conf_dat)) loop
131
      readline(conf_dat, file_row);
132
      read (file_row, dest_agent_n_var, dest_ok);
133
 
134
      if dest_ok = FALSE then
135
        --Reading of the delay value failed
136
        --=> assume that this line is comment or empty, and skip other it
137
        -- assert false report "Skipped a line" severity note;
138
        next;                           -- start new loop interation
139
      end if;
140
 
141
      read (file_row, delay_var);
142
      read (file_row, amount_var);
143
 
144
      -- Return the values
145
      dest_agent_n := dest_agent_n_var;
146
      delay        := delay_var;
147
      amount       := amount_var;
148
    end loop;
149
 
150
  end read_hibi_conf_file;
151
 
152
 
153
 
154
  -- Main FSM
155
  type   control_states is (read_hibi_conf, wait_sending, write_hibi, wait_hibi, finish, write_addr, pause);
156
  signal control_r : control_states := read_hibi_conf;
157
 
158
 
159
 
160
  -- Fifo signals
161
  signal agent_comm_to_fifo : std_logic_vector (comm_width_g-1 downto 0);
162
  signal agent_data_to_fifo : std_logic_vector(data_width_g-1 downto 0);
163
  signal agent_av_to_fifo   : std_logic;
164
  signal data_to_fifo    : std_logic_vector (1+comm_width_g+data_width_g-1 downto 0);  --concatenated from above
165
  signal we_to_fifo      : std_logic;
166
  signal full_from_fifo  : std_logic;
167
  signal one_p_from_fifo : std_logic;
168
 
169
  signal re_to_fifo      : std_logic;
170
  signal data_from_fifo  : std_logic_vector (1+comm_width_g+data_width_g-1 downto 0);
171
  signal empty_from_fifo : std_logic;
172
  signal one_d_from_fifo : std_logic;
173
 
174
 
175
 
176
 
177
  -- internal
178
  constant data_fixed_width_c : integer := 32;
179
  constant n_words_output_c : integer := data_width_g/ data_fixed_width_c;
180
  type dest_amount_cnt_type is array (0 to n_dest_g-1) of std_logic_vector(data_fixed_width_c-1 downto 0);
181
  signal data_r : dest_amount_cnt_type;  -- 32 bit words always!
182
 
183
  signal sent_packets_r : integer;
184
 
185
begin  -- rtl
186
 
187
  agent_av_out   <= data_from_fifo(1+comm_width_g+data_width_g-1);
188
  agent_comm_out <= data_from_fifo(comm_width_g+data_width_g-1 downto data_width_g);
189
  agent_data_out <= data_from_fifo(data_width_g-1 downto 0);
190
  data_to_fifo   <= agent_av_to_fifo & agent_comm_to_fifo & agent_data_to_fifo;
191
 
192
  --
193
  -- Instead of full HIBI bus, we only need one FIFO. This component
194
  -- puts data to the FIFO, that will be read by the DUT.
195
  --
196
  fifo_1 : entity work.fifo
197
    generic map (
198
      data_width_g => 1+comm_width_g+data_width_g,  -- av, comm, data
199
      depth_g      => 10)
200
    port map (
201
      clk       => clk,
202
      rst_n     => rst_n,
203
      data_in   => data_to_fifo,
204
      we_in     => we_to_fifo,
205
      full_out  => full_from_fifo,
206
      one_p_out => one_p_from_fifo,
207
      re_in     => agent_re_in,
208
      data_out  => data_from_fifo,
209
      empty_out => agent_empty_out,
210
      one_d_out => one_d_from_fifo);
211
 
212
  --
213
  -- Generate transfers according to conf file
214
  --
215
  main : process (clk, rst_n)
216
    file conf_data_file : text open read_mode is conf_file_g;
217
    --    file data_file_1    : text open read_mode is data_1_g;
218
 
219
    variable delay_r        : integer;
220
    variable amount_r       : integer;
221
    variable dest_agent_n_r : integer;
222
    variable file_number_r  : integer;
223
    --    variable data_r         : integer;
224
  begin  -- process main
225
    if rst_n = '0' then                 -- asynchronous reset (active low)
226
      control_r          <= read_hibi_conf;
227
      agent_data_to_fifo <= (others => rst_value_arr(dbg_level*1));
228
      agent_av_to_fifo   <= '0';
229
      agent_comm_to_fifo <= (others => rst_value_arr(dbg_level*1));
230
      we_to_fifo         <= '0';
231
      done_out           <= '0';
232
      amount_r           := 0;
233
      delay_r            := 0;
234
      dest_agent_n_r     := 0;
235
      for i in 0 to n_dest_g-1 loop
236
        data_r(i) <= (others => '0');
237
      end loop;  -- i
238
      file_number_r  := 0;
239
      pause_ack      <= '0';
240
      sent_packets_r <= 0;
241
 
242
 
243
    elsif clk'event and clk = '1' then  -- rising clock edge
244
 
245
      case control_r is
246
        when read_hibi_conf =>
247
          -- If there's still data left, we read the configuration
248
          -- file and act accordingly. If some delay is specified,
249
          -- we go and wait it (wait_sending). If delay = 0,
250
          -- then we send the address right away          
251
          if pause_in = '1' then
252
            control_r <= pause;
253
          else
254
 
255
            if endfile(conf_data_file) then
256
              control_r <= finish;
257
              assert false report "End of the configuration file reached" severity note;
258
            end if;
259
            read_hibi_conf_file (
260
              dest_agent_n => dest_agent_n_r,
261
              delay        => delay_r,
262
              amount       => amount_r,
263
              conf_dat     => conf_data_file);
264
            if delay_r = 0 then
265
              control_r <= write_addr;
266
            else
267
              control_r <= wait_sending;
268
            end if;
269
          end if;
270
            we_to_fifo         <= '0';
271
            agent_av_to_fifo   <= '0';
272
            agent_data_to_fifo <= (others => rst_value_arr(dbg_level*1));
273
            agent_comm_to_fifo <= (others => rst_value_arr(dbg_level*1));
274
 
275
 
276
        when wait_sending =>
277
          -- Let's wait the given amount of time before proceeding with sending
278
          delay_r := delay_r-1;
279
          if delay_r = 0 then
280
            control_r <= write_addr;
281
          end if;
282
          dest_agent_n_r := dest_agent_n_r;
283
          amount_r       := amount_r;--dest_agent_n_r;
284
 
285
        when write_addr =>
286
          -- When there is room in fifo, we write the address to it and then
287
          -- go to the state where the actual data is sent (write_hibi)
288
          -- Note that part of dst agent address is gotten from the array
289
          -- defined in separate package.
290
          if full_from_fifo = '0' then
291
            we_to_fifo         <= '1';
292
            agent_av_to_fifo   <= '1';
293
            agent_comm_to_fifo <= hibi_write_c;
294
 
295
            -- Addr defines not only the target, but also
296
            -- identifies the sender and packet number.
297
            -- Hence, sent addresses are always incremented by one.
298
            agent_data_to_fifo <= conv_std_logic_vector
299
                                  (addresses_c(dest_agent_n_r)
300
                                   + own_number_g + sent_packets_r
301
                                   , data_width_g);
302
 
303
            sent_packets_r <= sent_packets_r + 1;
304
            control_r <= write_hibi;
305
          else
306
            we_to_fifo         <= '0';
307
            agent_av_to_fifo   <= '0';
308
            agent_data_to_fifo <= (others => rst_value_arr(dbg_level*1));
309
            agent_comm_to_fifo <= (others => rst_value_arr(dbg_level*1));
310
            control_r          <= write_addr;
311
          end if;
312
 
313
        when write_hibi =>
314
          -- Outputs runnign numbers: 0,1,2...
315
 
316
          if full_from_fifo = '0' then
317
 
318
            for i in 0 to n_words_output_c-1 loop
319
              agent_data_to_fifo(data_fixed_width_c*(i+1)-1 downto data_fixed_width_c*i) <= data_r(dest_agent_n_r)+i;
320
              amount_r := amount_r-1;
321
              if amount_r = 0 then
322
                control_r  <= read_hibi_conf;
323
                we_to_fifo <= '1';
324
                exit;
325
              end if;
326
            end loop;  -- i
327
            data_r(dest_agent_n_r) <= data_r(dest_agent_n_r) + n_words_output_c;
328
 
329
            agent_av_to_fifo   <= '0';
330
            agent_comm_to_fifo <= hibi_write_c;
331
 
332
            if one_p_from_fifo = '1' then
333
              control_r  <= wait_hibi;
334
              we_to_fifo <= '0';
335
            end if;
336
 
337
          else
338
            control_r          <= wait_hibi;
339
            agent_data_to_fifo <= (others => rst_value_arr(dbg_level*1));
340
            we_to_fifo         <= '0';
341
            agent_av_to_fifo   <= '0';
342
            agent_comm_to_fifo <= (others => rst_value_arr(dbg_level*1));
343
          end if;
344
 
345
        when wait_hibi =>
346
          -- hibi was full so we wait until it becames free again
347
          if full_from_fifo = '0' then
348
            control_r  <= write_hibi;
349
            we_to_fifo <= '1';
350
            if amount_r = 0 then
351
              control_r <= read_hibi_conf;
352
            end if;
353
          else
354
            control_r  <= wait_hibi;
355
            we_to_fifo <= '0';
356
          end if;
357
          --          agent_data_to_fifo <= (others => rst_value_arr(dbg_level*1));
358
          --          agent_av_to_fifo   <= '0';
359
          --          agent_comm_to_fifo <= (others => rst_value_arr(dbg_level*1));
360
 
361
        when finish =>
362
          -- Notify that we're done.
363
          done_out           <= '1';
364
          agent_data_to_fifo <= (others => rst_value_arr(dbg_level*1));
365
          we_to_fifo         <= '0';
366
          agent_av_to_fifo   <= '0';
367
          agent_comm_to_fifo <= (others => rst_value_arr(dbg_level*1));
368
 
369
        when pause =>
370
          if pause_in = '0' then
371
            pause_ack <= '0';
372
            control_r <= read_hibi_conf;
373
          else
374
            pause_ack <= '1';
375
            control_r <= pause;
376
          end if;
377
        when others => null;
378
      end case;
379
 
380
 
381
 
382
    end if;
383
  end process main;
384
 
385
 
386
end rtl;

powered by: WebSVN 2.1.0

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