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/] [3.0/] [vhd/] [fifo_mux_rd.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : HIBI fifo mux rd
3
-- Project    : Nocbench, Funbase
4
-------------------------------------------------------------------------------
5
-- File       : fifo_mux_rd.vhd
6
-- Authors    : Lasse Lehtonen
7
-- Company    : Tampere University of Technology
8
-- Created    : 2011-10-25
9
-- Last update: 2011-11-28
10
-- Platform   : 
11
-- Standard   : VHDL'93
12
-------------------------------------------------------------------------------
13
-- Description: Read side logic for double fifos
14
--
15
-- Makes two fifos look like a single fifo for the reader. Fifo 0 has higher
16
-- priority. This block adds additional address flits in normal mode
17
-- (multiplexed address and data) if high and low priority transfers get mixed
18
-- together. In sad mode (simultaneous addr+data), this does not happen.
19
-- 
20
--
21
-------------------------------------------------------------------------------
22
-- Copyright (c) 2010 Tampere University of Technology
23
--
24
-- 
25
-------------------------------------------------------------------------------
26
-- Revisions  :
27
-- Date        Version  Author  Description
28
-- 2010-10-25  1.0      ase     Created
29
-------------------------------------------------------------------------------
30
-------------------------------------------------------------------------------
31
-- Funbase IP library Copyright (C) 2011 TUT Department of Computer Systems
32
--
33
-- This file is part of HIBI
34
--
35
-- This source file may be used and distributed without
36
-- restriction provided that this copyright statement is not
37
-- removed from the file and that any derivative work contains
38
-- the original copyright notice and the associated disclaimer.
39
--
40
-- This source file is free software; you can redistribute it
41
-- and/or modify it under the terms of the GNU Lesser General
42
-- Public License as published by the Free Software Foundation;
43
-- either version 2.1 of the License, or (at your option) any
44
-- later version.
45
--
46
-- This source is distributed in the hope that it will be
47
-- useful, but WITHOUT ANY WARRANTY; without even the implied
48
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
49
-- PURPOSE.  See the GNU Lesser General Public License for more
50
-- details.
51
--
52
-- You should have received a copy of the GNU Lesser General
53
-- Public License along with this source; if not, download it
54
-- from http://www.opencores.org/lgpl.shtml
55
-------------------------------------------------------------------------------
56
 
57
library ieee;
58
use ieee.std_logic_1164.all;
59
 
60
use work.hibiv3_pkg.all;
61
 
62
 
63
entity fifo_mux_rd is
64
 
65
  generic (
66
    data_width_g    : integer;
67
    comm_width_g    : integer;
68
    separate_addr_g : integer;
69
    debug_g         : integer := 0
70
    );
71
  port (
72
    clk   : in std_logic;
73
    rst_n : in std_logic;
74
 
75
    data_0_in  : in  std_logic_vector (data_width_g-1 downto 0);
76
    comm_0_in  : in  std_logic_vector (comm_width_g-1 downto 0);
77
    av_0_in    : in  std_logic;
78
    one_d_0_in : in  std_logic;
79
    empty_0_in : in  std_logic;
80
    re_0_Out   : out std_logic;
81
 
82
    data_1_in  : in  std_logic_vector (data_width_g-1 downto 0);
83
    comm_1_in  : in  std_logic_vector (comm_width_g-1 downto 0);
84
    av_1_in    : in  std_logic;
85
    one_d_1_in : in  std_logic;
86
    empty_1_in : in  std_logic;
87
    re_1_Out   : out std_logic;
88
 
89
    re_in     : in  std_logic;
90
    data_out  : out std_logic_vector (data_width_g-1 downto 0);
91
    comm_out  : out std_logic_vector (comm_width_g-1 downto 0);
92
    av_out    : out std_logic;
93
    one_d_Out : out std_logic;
94
    empty_Out : out std_logic
95
    );
96
 
97
end fifo_mux_rd;
98
 
99
 
100
architecture rtl of fifo_mux_rd is
101
 
102
  -----------------------------------------------------------------------------
103
  -- CONSTANTS
104
  -----------------------------------------------------------------------------
105
 
106
  -----------------------------------------------------------------------------
107
  -- REGISTERS
108
  -----------------------------------------------------------------------------
109
  -- Mux must repeat the latest address when the FIFO changes and there is data
110
  -- coming from the FIFO. This is called addr reinjection.
111
  --
112
  -- Last address+comm flits, for reinjection if switching fifos between
113
  -- transmissions
114
  signal last_addr_0_r : std_logic_vector(data_width_g-1 downto 0);
115
  signal last_comm_0_r : std_logic_vector(comm_width_g-1 downto 0);
116
  signal last_addr_1_r : std_logic_vector(data_width_g-1 downto 0);
117
  signal last_comm_1_r : std_logic_vector(comm_width_g-1 downto 0);
118
 
119
  -- '1' if reinjection of address flit is needed
120
  signal reinject_0_r : std_logic;
121
  signal reinject_1_r : std_logic;
122
 
123
  -- '1' if only address flit has been sent from the corresponding fifo.
124
  -- Then, one must wait for data from the same fifo before changing the fifo.
125
  signal only_addr_read_0_r : std_logic;
126
  signal only_addr_read_1_r : std_logic;
127
 
128
  -- '0' when using fifo_0, '1' otherwise
129
  signal fifo_select_r : std_logic;
130
 
131
  -- '1' when fifo select is locked (because of exclusive data access)
132
  -- Lock stays on until there is a specific 'release lock' command arrives
133
  signal excl_locked_r : std_logic;
134
 
135
  -----------------------------------------------------------------------------
136
  -- COMBINATORIAL SIGNALS
137
  -----------------------------------------------------------------------------
138
  signal empty_out_s : std_logic;
139
  signal re_0_out_s  : std_logic;
140
  signal re_1_out_s  : std_logic;
141
 
142
begin  -- rtl
143
 
144
  -----------------------------------------------------------------------------
145
  -- COMMON PART
146
  -----------------------------------------------------------------------------
147
  empty_out <= empty_out_s;
148
  re_0_out  <= re_0_out_s;
149
  re_1_out  <= re_1_out_s;
150
 
151
  -----------------------------------------------------------------------------
152
  -- MULTIPLEXED ADDRESS AND DATA BUSES
153
  -----------------------------------------------------------------------------
154
  normal_mode : if separate_addr_g = 0 generate
155
 
156
    --
157
    -- Decide from which FIFO, the data goes to the reader
158
    -- 
159
    main_p : process (clk, rst_n) is
160
      variable only_addr_read_0_v : std_logic;
161
      variable only_addr_read_1_v : std_logic;
162
      variable excl_locked_v      : std_logic;
163
    begin  -- process main_p
164
      if rst_n = '0' then               -- asynchronous reset (active low)
165
 
166
        fifo_select_r      <= '0';
167
        --last_addr_0_r      <= (others => '0');
168
        --last_comm_0_r      <= (others => '0');
169
        --last_addr_1_r      <= (others => '0');
170
        --last_comm_1_r      <= (others => '0');
171
        only_addr_read_0_r <= '0';
172
        only_addr_read_1_r <= '0';
173
        reinject_0_r       <= '0';
174
        reinject_1_r       <= '0';
175
        excl_locked_r      <= '0';
176
 
177
      elsif clk'event and clk = '1' then  -- rising clock edge
178
 
179
        -- Latch address flits when available
180
        if empty_0_in = '0' and av_0_in = '1' then
181
          last_addr_0_r <= data_0_in;
182
          last_comm_0_r <= comm_0_in;
183
        end if;
184
 
185
        if empty_1_in = '0' and av_1_in = '1' then
186
          last_addr_1_r <= data_1_in;
187
          last_comm_1_r <= comm_1_in;
188
        end if;
189
 
190
 
191
        -- Check if only address flits have been sent.
192
        -- One cannot change the input fifo before some data has arrived after
193
        -- the addr.
194
        only_addr_read_0_v := only_addr_read_0_r;
195
        only_addr_read_1_v := only_addr_read_1_r;
196
 
197
        if fifo_select_r = '0' then
198
 
199
          if reinject_0_r = '1' then
200
            if re_0_out_s = '1' then
201
              only_addr_read_0_v := '1';
202
            end if;
203
          else
204
            if av_0_in = '1' and re_0_out_s = '1' and empty_0_in = '0' then
205
              only_addr_read_0_v := '1';
206
            elsif av_0_in = '0' and re_0_out_s = '1' then
207
              only_addr_read_0_v := '0';
208
            end if;
209
          end if;
210
 
211
        else
212
 
213
          if reinject_1_r = '1' then
214
            if re_1_out_s = '1' then
215
              only_addr_read_1_v := '1';
216
            end if;
217
          else
218
            if av_1_in = '1' and re_1_out_s = '1' and empty_1_in = '0' then
219
              only_addr_read_1_v := '1';
220
            elsif av_1_in = '0' and re_1_out_s = '1' then
221
              only_addr_read_1_v := '0';
222
            end if;
223
          end if;
224
 
225
        end if;
226
 
227
        only_addr_read_0_r <= only_addr_read_0_v;
228
        only_addr_read_1_r <= only_addr_read_1_v;
229
 
230
        -- Select signal must be locked so that wrong priority data
231
        -- can't intervene when the right priority fifo is empty
232
        -- momentarily
233
        excl_locked_v := excl_locked_r;
234
 
235
        if fifo_select_r = '0' then
236
          if comm_0_in = EXCL_LOCK_c and re_0_out_s = '1' then
237
            excl_locked_v := '1';
238
          elsif comm_0_in = EXCL_RELEASE_c and re_0_out_s = '1' then
239
            excl_locked_v := '0';
240
          end if;
241
        end if;
242
 
243
        excl_locked_r <= excl_locked_v;
244
 
245
        -- Decide which fifo to use
246
        if excl_locked_v = '0' then
247
 
248
          if fifo_select_r = '0' then
249
 
250
            if only_addr_read_0_r = '0' and only_addr_read_0_v = '0' and
251
              ((av_0_in = '1' and one_d_0_in = '1')
252
               or (empty_0_in = '1'))
253
              and empty_1_in = '0'
254
              and (av_1_in = '0' or one_d_1_in = '0') then
255
              fifo_select_r <= '1';
256
            end if;
257
 
258
          else
259
 
260
            if only_addr_read_1_r = '0' and only_addr_read_1_v = '0'
261
              and empty_0_in = '0'
262
              and (av_0_in = '0' or one_d_0_in = '0') then
263
              fifo_select_r <= '0';
264
            end if;
265
 
266
          end if;
267
 
268
        end if;
269
 
270
        -- Check the need for reinjection
271
        if fifo_select_r = '0' then
272
 
273
          if empty_1_in = '0' and av_1_in = '0' then
274
            reinject_1_r <= '1';
275
          else
276
            reinject_1_r <= '0';
277
          end if;
278
 
279
          if re_in = '1' then
280
            reinject_0_r <= '0';
281
          end if;
282
 
283
        else
284
 
285
          if empty_0_in = '0' and av_0_in = '0' then
286
            reinject_0_r <= '1';
287
          else
288
            reinject_0_r <= '0';
289
          end if;
290
 
291
          if re_in = '1' then
292
            reinject_1_r <= '0';
293
          end if;
294
 
295
        end if;
296
 
297
 
298
      end if;
299
    end process main_p;
300
 
301
 
302
    -- Forward combinatorially the correct data to the reader: either from one
303
    -- of the FIFOs, or by reinjecting the latest addr again.
304
    mux_p : process (fifo_select_r, data_0_in, data_1_in, comm_0_in, comm_1_in,
305
                     av_0_in, av_1_in, one_d_0_in, one_d_1_in, empty_0_in,
306
                     empty_1_in, re_in, last_addr_0_r, last_addr_1_r,
307
                     last_comm_0_r, last_comm_1_r, reinject_0_r,
308
                     reinject_1_r, empty_out_s) is
309
    begin  -- process mux_p
310
 
311
      if fifo_select_r = '0' then
312
 
313
        if reinject_0_r = '0' then
314
          data_out    <= data_0_in;
315
          comm_out    <= comm_0_in;
316
          av_out      <= av_0_in;
317
          one_d_out   <= one_d_0_in and not av_0_in;
318
          empty_out_s <= empty_0_in or (one_d_0_in and av_0_in);
319
          re_0_out_s  <= re_in and not (empty_0_in or (one_d_0_in and av_0_in));
320
          re_1_out_s  <= '0';
321
        else
322
          data_out    <= last_addr_0_r;
323
          comm_out    <= last_comm_0_r;
324
          av_out      <= '1';
325
          one_d_out   <= '0';
326
          empty_out_s <= '0';
327
          re_0_out_s  <= '0';
328
          re_1_out_s  <= '0';
329
        end if;
330
 
331
 
332
      else
333
 
334
        if reinject_1_r = '0' then
335
          data_out    <= data_1_in;
336
          comm_out    <= comm_1_in;
337
          av_out      <= av_1_in;
338
          one_d_out   <= one_d_1_in and not av_1_in;
339
          empty_out_s <= empty_1_in or (one_d_1_in and av_1_in);
340
          re_0_out_s  <= '0';
341
          re_1_out_s  <= re_in and not (empty_1_in or (one_d_1_in and av_1_in));
342
        else
343
          data_out    <= last_addr_1_r;
344
          comm_out    <= last_comm_1_r;
345
          av_out      <= '1';
346
          one_d_out   <= '0';
347
          empty_out_s <= '0';
348
          re_0_out_s  <= '0';
349
          re_1_out_s  <= '0';
350
        end if;
351
 
352
      end if;
353
 
354
      -- pragma synthesis_off
355
      -- pragma translate_off
356
 
357
      if debug_g > 0 and empty_out_s = '1' then
358
 
359
        data_out <= (others => 'X');
360
        comm_out <= (others => 'X');
361
 
362
      end if;
363
 
364
      -- pragma translate_on
365
      -- pragma synthesis_on
366
 
367
    end process mux_p;
368
 
369
 
370
  end generate normal_mode;
371
 
372
  -----------------------------------------------------------------------------
373
  -- SEPARATED ADDRESS AND DATA BUSES
374
  -- Actually, addr and data are concatenated into a wide data bus. This is
375
  -- much simpler case than above.
376
  -----------------------------------------------------------------------------
377
  sad_mode : if separate_addr_g = 1 generate
378
 
379
    fifo_sel_p : process (clk, rst_n) is
380
      variable excl_locked_v : std_logic;
381
    begin  -- process fifo_sel_p
382
      if rst_n = '0' then               -- asynchronous reset (active low)
383
 
384
        fifo_select_r <= '0';
385
        excl_locked_r <= '0';
386
 
387
      elsif clk'event and clk = '1' then  -- rising clock edge
388
 
389
        excl_locked_v := excl_locked_r;
390
 
391
        -- Select signal must be locked so that lower priority data
392
        -- can't intervene when the higher priority fifo is empty
393
        -- momentarily
394
        if fifo_select_r = '0' then
395
          if comm_0_in = EXCL_LOCK_c and re_0_out_s = '1' then
396
            excl_locked_v := '1';
397
          elsif comm_0_in = EXCL_RELEASE_c and re_0_out_s = '1' then
398
            excl_locked_v := '0';
399
          end if;
400
        end if;
401
 
402
        excl_locked_r <= excl_locked_v;
403
 
404
        if excl_locked_v = '0' then
405
          fifo_select_r <= empty_0_in;
406
        end if;
407
 
408
      end if;
409
    end process fifo_sel_p;
410
 
411
    -- Forward combinatorially the correct data to the reader from one
412
    -- of the FIFOs.
413
    mux_p : process (fifo_select_r, data_0_in, data_1_in, comm_0_in, comm_1_in,
414
                     av_0_in, av_1_in, one_d_0_in, one_d_1_in, empty_0_in,
415
                     empty_1_in, re_in, empty_out_s) is
416
    begin  -- process mux_p
417
 
418
      if fifo_select_r = '0' then
419
 
420
        data_out    <= data_0_in;
421
        comm_out    <= comm_0_in;
422
        av_out      <= av_0_in;
423
        one_d_out   <= one_d_0_in;
424
        empty_out_s <= empty_0_in;
425
        re_0_out_s  <= re_in and not empty_0_in;
426
        re_1_out_s  <= '0';
427
 
428
      else
429
 
430
        data_out    <= data_1_in;
431
        comm_out    <= comm_1_in;
432
        av_out      <= av_1_in;
433
        one_d_out   <= one_d_1_in;
434
        empty_out_s <= empty_1_in;
435
        re_0_out_s  <= '0';
436
        re_1_out_s  <= re_in and not empty_1_in;
437
 
438
      end if;
439
 
440
      -- pragma synthesis_off
441
      -- pragma translate_off
442
 
443
      if debug_g > 0 and empty_out_s = '1' then
444
 
445
        data_out <= (others => 'X');
446
        comm_out <= (others => 'X');
447
 
448
      end if;
449
 
450
      -- pragma translate_on
451
      -- pragma synthesis_on
452
 
453
    end process mux_p;
454
 
455
  end generate sad_mode;
456
 
457
end rtl;
458
 

powered by: WebSVN 2.1.0

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