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

Subversion Repositories rio

[/] [rio/] [branches/] [2.0.0-development/] [rtl/] [vhdl/] [RioPacketBuffer.vhd] - Blame information for rev 51

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 magro732
-------------------------------------------------------------------------------
2
-- 
3
-- RapidIO IP Library Core
4
-- 
5
-- This file is part of the RapidIO IP library project
6
-- http://www.opencores.org/cores/rio/
7
-- 
8
-- Description
9
-- Containing RapidIO packet buffering functionallity. Two different entities
10
-- are implemented, one with transmission window support and one without.
11
-- 
12
-- To Do:
13 51 magro732
-- - Copy code from Bombardier internal reporitory to get configurable sizes.
14
-- - Add an additional size-memory to be able to access both window and back at
15
--   the same time.
16
-- - Add support for priorities, seperate queue for each level.
17 3 magro732
-- 
18
-- Author(s): 
19
-- - Magnus Rosenius, magro732@opencores.org 
20
-- 
21
-------------------------------------------------------------------------------
22
-- 
23
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
24
-- 
25
-- This source file may be used and distributed without 
26
-- restriction provided that this copyright statement is not 
27
-- removed from the file and that any derivative work contains 
28
-- the original copyright notice and the associated disclaimer. 
29
-- 
30
-- This source file is free software; you can redistribute it 
31
-- and/or modify it under the terms of the GNU Lesser General 
32
-- Public License as published by the Free Software Foundation; 
33
-- either version 2.1 of the License, or (at your option) any 
34
-- later version. 
35
-- 
36
-- This source is distributed in the hope that it will be 
37
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
38
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
39
-- PURPOSE. See the GNU Lesser General Public License for more 
40
-- details. 
41
-- 
42
-- You should have received a copy of the GNU Lesser General 
43
-- Public License along with this source; if not, download it 
44
-- from http://www.opencores.org/lgpl.shtml 
45
-- 
46
-------------------------------------------------------------------------------
47
 
48
 
49
-------------------------------------------------------------------------------
50
-- RioPacketBuffer
51
-------------------------------------------------------------------------------
52
 
53
library ieee;
54
use ieee.std_logic_1164.all;
55
use ieee.numeric_std.all;
56
use work.rio_common.all;
57
 
58
 
59
-------------------------------------------------------------------------------
60
-- Entity for RioPacketBuffer.
61
-------------------------------------------------------------------------------
62
entity RioPacketBuffer is
63 7 magro732
  generic(
64
    SIZE_ADDRESS_WIDTH : natural := 6;
65
    CONTENT_ADDRESS_WIDTH : natural := 8);
66 3 magro732
  port(
67
    clk : in std_logic;
68
    areset_n : in std_logic;
69
 
70
    inboundWriteFrameFull_o : out std_logic;
71
    inboundWriteFrame_i : in std_logic;
72
    inboundWriteFrameAbort_i : in std_logic;
73
    inboundWriteContent_i : in std_logic;
74
    inboundWriteContentData_i : in std_logic_vector(31 downto 0);
75
    inboundReadFrameEmpty_o : out std_logic;
76
    inboundReadFrame_i : in std_logic;
77
    inboundReadFrameRestart_i : in std_logic;
78
    inboundReadFrameAborted_o : out std_logic;
79
    inboundReadContentEmpty_o : out std_logic;
80
    inboundReadContent_i : in std_logic;
81
    inboundReadContentEnd_o : out std_logic;
82
    inboundReadContentData_o : out std_logic_vector(31 downto 0);
83
 
84
    outboundWriteFrameFull_o : out std_logic;
85
    outboundWriteFrame_i : in std_logic;
86
    outboundWriteFrameAbort_i : in std_logic;
87
    outboundWriteContent_i : in std_logic;
88
    outboundWriteContentData_i : in std_logic_vector(31 downto 0);
89
    outboundReadFrameEmpty_o : out std_logic;
90
    outboundReadFrame_i : in std_logic;
91
    outboundReadFrameRestart_i : in std_logic;
92
    outboundReadFrameAborted_o : out std_logic;
93
    outboundReadContentEmpty_o : out std_logic;
94
    outboundReadContent_i : in std_logic;
95
    outboundReadContentEnd_o : out std_logic;
96
    outboundReadContentData_o : out std_logic_vector(31 downto 0));
97
end entity;
98
 
99
 
100
-------------------------------------------------------------------------------
101
-- Architecture for RioPacketBuffer.
102
-------------------------------------------------------------------------------
103
architecture RioPacketBufferImpl of RioPacketBuffer is
104
 
105
  component PacketBufferContinous is
106 7 magro732
    generic(
107
      SIZE_ADDRESS_WIDTH : natural;
108
      CONTENT_ADDRESS_WIDTH : natural);
109
    port(
110
      clk : in std_logic;
111
      areset_n : in std_logic;
112 3 magro732
 
113 7 magro732
      writeFrameFull_o : out std_logic;
114
      writeFrame_i : in std_logic;
115
      writeFrameAbort_i : in std_logic;
116
      writeContent_i : in std_logic;
117
      writeContentData_i : in std_logic_vector(31 downto 0);
118 3 magro732
 
119 7 magro732
      readFrameEmpty_o : out std_logic;
120
      readFrame_i : in std_logic;
121
      readFrameRestart_i : in std_logic;
122
      readFrameAborted_o : out std_logic;
123
      readContentEmpty_o : out std_logic;
124
      readContent_i : in std_logic;
125
      readContentEnd_o : out std_logic;
126
      readContentData_o : out std_logic_vector(31 downto 0));
127 3 magro732
  end component;
128
 
129
begin
130
 
131
  -----------------------------------------------------------------------------
132
  -- Outbound frame buffers.
133
  -----------------------------------------------------------------------------
134
  OutboundPacketBuffer: PacketBufferContinous
135 7 magro732
    generic map(
136
      SIZE_ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH,
137
      CONTENT_ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH)
138 3 magro732
    port map(
139
      clk=>clk,
140
      areset_n=>areset_n,
141
      writeFrameFull_o=>outboundWriteFrameFull_o,
142
      writeFrame_i=>outboundWriteFrame_i, writeFrameAbort_i=>outboundWriteFrameAbort_i,
143
      writeContent_i=>outboundWriteContent_i, writeContentData_i=>outboundWriteContentData_i,
144
 
145
      readFrameEmpty_o=>outboundReadFrameEmpty_o,
146
      readFrame_i=>outboundReadFrame_i, readFrameRestart_i=>outboundReadFrameRestart_i,
147
      readFrameAborted_o=>outboundReadFrameAborted_o,
148
      readContentEmpty_o=>outboundReadContentEmpty_o,
149
      readContent_i=>outboundReadContent_i, readContentEnd_o=>outboundReadContentEnd_o,
150
      readContentData_o=>outboundReadContentData_o);
151
 
152
  -----------------------------------------------------------------------------
153
  -- Inbound frame buffers.
154
  -----------------------------------------------------------------------------
155
  InboundPacketBuffer: PacketBufferContinous
156 7 magro732
    generic map(
157
      SIZE_ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH,
158
      CONTENT_ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH)
159 3 magro732
    port map(
160
      clk=>clk,
161
      areset_n=>areset_n,
162
      writeFrameFull_o=>inboundWriteFrameFull_o,
163
      writeFrame_i=>inboundWriteFrame_i, writeFrameAbort_i=>inboundWriteFrameAbort_i,
164
      writeContent_i=>inboundWriteContent_i, writeContentData_i=>inboundWriteContentData_i,
165
 
166
      readFrameEmpty_o=>inboundReadFrameEmpty_o,
167
      readFrame_i=>inboundReadFrame_i, readFrameRestart_i=>inboundReadFrameRestart_i,
168
      readFrameAborted_o=>inboundReadFrameAborted_o,
169
      readContentEmpty_o=>inboundReadContentEmpty_o,
170
      readContent_i=>inboundReadContent_i, readContentEnd_o=>inboundReadContentEnd_o,
171
      readContentData_o=>inboundReadContentData_o);
172
 
173
end architecture;
174
 
175
 
176
 
177
 
178
-------------------------------------------------------------------------------
179
-- RioPacketBufferWindow
180
-------------------------------------------------------------------------------
181
 
182
library ieee;
183
use ieee.std_logic_1164.all;
184
use ieee.numeric_std.all;
185
use work.rio_common.all;
186
 
187
 
188
-------------------------------------------------------------------------------
189
-- Entity for RioPacketBufferWindow.
190
-------------------------------------------------------------------------------
191
entity RioPacketBufferWindow is
192 7 magro732
  generic(
193
    SIZE_ADDRESS_WIDTH : natural := 6;
194
    CONTENT_ADDRESS_WIDTH : natural := 8);
195 3 magro732
  port(
196
    clk : in std_logic;
197
    areset_n : in std_logic;
198
 
199
    inboundWriteFrameFull_o : out std_logic;
200
    inboundWriteFrame_i : in std_logic;
201
    inboundWriteFrameAbort_i : in std_logic;
202
    inboundWriteContent_i : in std_logic;
203
    inboundWriteContentData_i : in std_logic_vector(31 downto 0);
204
    inboundReadFrameEmpty_o : out std_logic;
205
    inboundReadFrame_i : in std_logic;
206
    inboundReadFrameRestart_i : in std_logic;
207
    inboundReadFrameAborted_o : out std_logic;
208
    inboundReadContentEmpty_o : out std_logic;
209
    inboundReadContent_i : in std_logic;
210
    inboundReadContentEnd_o : out std_logic;
211
    inboundReadContentData_o : out std_logic_vector(31 downto 0);
212
 
213
    outboundWriteFrameFull_o : out std_logic;
214
    outboundWriteFrame_i : in std_logic;
215
    outboundWriteFrameAbort_i : in std_logic;
216
    outboundWriteContent_i : in std_logic;
217
    outboundWriteContentData_i : in std_logic_vector(31 downto 0);
218
    outboundReadFrameEmpty_o : out std_logic;
219
    outboundReadFrame_i : in std_logic;
220
    outboundReadFrameRestart_i : in std_logic;
221
    outboundReadFrameAborted_o : out std_logic;
222
    outboundReadWindowEmpty_o : out std_logic;
223
    outboundReadWindowReset_i : in std_logic;
224
    outboundReadWindowNext_i : in std_logic;
225
    outboundReadContentEmpty_o : out std_logic;
226
    outboundReadContent_i : in std_logic;
227
    outboundReadContentEnd_o : out std_logic;
228
    outboundReadContentData_o : out std_logic_vector(31 downto 0));
229
end entity;
230
 
231
 
232
-------------------------------------------------------------------------------
233
-- Architecture for RioPacketBufferWindow.
234
-------------------------------------------------------------------------------
235
architecture RioPacketBufferWindowImpl of RioPacketBufferWindow is
236
 
237
  component PacketBufferContinous is
238 7 magro732
    generic(
239
      SIZE_ADDRESS_WIDTH : natural;
240
      CONTENT_ADDRESS_WIDTH : natural);
241
    port(
242
      clk : in std_logic;
243
      areset_n : in std_logic;
244 3 magro732
 
245 7 magro732
      writeFrameFull_o : out std_logic;
246
      writeFrame_i : in std_logic;
247
      writeFrameAbort_i : in std_logic;
248
      writeContent_i : in std_logic;
249
      writeContentData_i : in std_logic_vector(31 downto 0);
250 3 magro732
 
251 7 magro732
      readFrameEmpty_o : out std_logic;
252
      readFrame_i : in std_logic;
253
      readFrameRestart_i : in std_logic;
254
      readFrameAborted_o : out std_logic;
255
 
256
      readContentEmpty_o : out std_logic;
257
      readContent_i : in std_logic;
258
      readContentEnd_o : out std_logic;
259
      readContentData_o : out std_logic_vector(31 downto 0));
260 3 magro732
  end component;
261
 
262
  component PacketBufferContinousWindow is
263 7 magro732
    generic(
264
      SIZE_ADDRESS_WIDTH : natural;
265
      CONTENT_ADDRESS_WIDTH : natural);
266
    port(
267
      clk : in std_logic;
268
      areset_n : in std_logic;
269 3 magro732
 
270 7 magro732
      writeFrameFull_o : out std_logic;
271
      writeFrame_i : in std_logic;
272
      writeFrameAbort_i : in std_logic;
273
      writeContent_i : in std_logic;
274
      writeContentData_i : in std_logic_vector(31 downto 0);
275 3 magro732
 
276 7 magro732
      readFrameEmpty_o : out std_logic;
277
      readFrame_i : in std_logic;
278
      readFrameRestart_i : in std_logic;
279
      readFrameAborted_o : out std_logic;
280
 
281
      readWindowEmpty_o : out std_logic;
282
      readWindowReset_i : in std_logic;
283
      readWindowNext_i : in std_logic;
284
 
285
      readContentEmpty_o : out std_logic;
286
      readContent_i : in std_logic;
287
      readContentEnd_o : out std_logic;
288
      readContentData_o : out std_logic_vector(31 downto 0));
289 3 magro732
  end component;
290
 
291
begin
292
 
293
  -----------------------------------------------------------------------------
294
  -- Outbound frame buffers.
295
  -----------------------------------------------------------------------------
296
  OutboundPacketBuffer: PacketBufferContinousWindow
297 7 magro732
    generic map(
298
      SIZE_ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH,
299
      CONTENT_ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH)
300 3 magro732
    port map(
301
      clk=>clk,
302
      areset_n=>areset_n,
303
      writeFrameFull_o=>outboundWriteFrameFull_o,
304
      writeFrame_i=>outboundWriteFrame_i, writeFrameAbort_i=>outboundWriteFrameAbort_i,
305
      writeContent_i=>outboundWriteContent_i, writeContentData_i=>outboundWriteContentData_i,
306
 
307
      readFrameEmpty_o=>outboundReadFrameEmpty_o,
308
      readFrame_i=>outboundReadFrame_i, readFrameRestart_i=>outboundReadFrameRestart_i,
309
      readFrameAborted_o=>outboundReadFrameAborted_o,
310
      readWindowEmpty_o=>outboundReadWindowEmpty_o,
311
      readWindowReset_i=>outboundReadWindowReset_i,
312
      readWindowNext_i=>outboundReadWindowNext_i,
313
      readContentEmpty_o=>outboundReadContentEmpty_o,
314
      readContent_i=>outboundReadContent_i, readContentEnd_o=>outboundReadContentEnd_o,
315
      readContentData_o=>outboundReadContentData_o);
316
 
317
  -----------------------------------------------------------------------------
318
  -- Inbound frame buffers.
319
  -----------------------------------------------------------------------------
320
  InboundPacketBuffer: PacketBufferContinous
321 7 magro732
    generic map(
322
      SIZE_ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH,
323
      CONTENT_ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH)
324 3 magro732
    port map(
325
      clk=>clk,
326
      areset_n=>areset_n,
327
      writeFrameFull_o=>inboundWriteFrameFull_o,
328
      writeFrame_i=>inboundWriteFrame_i, writeFrameAbort_i=>inboundWriteFrameAbort_i,
329
      writeContent_i=>inboundWriteContent_i, writeContentData_i=>inboundWriteContentData_i,
330
 
331
      readFrameEmpty_o=>inboundReadFrameEmpty_o,
332
      readFrame_i=>inboundReadFrame_i, readFrameRestart_i=>inboundReadFrameRestart_i,
333
      readFrameAborted_o=>inboundReadFrameAborted_o,
334
      readContentEmpty_o=>inboundReadContentEmpty_o,
335
      readContent_i=>inboundReadContent_i, readContentEnd_o=>inboundReadContentEnd_o,
336
      readContentData_o=>inboundReadContentData_o);
337
 
338
end architecture;
339
 
340
 
341
 
342
 
343
-------------------------------------------------------------------------------
344
-- PacketBufferContinous
345
-- This component stores data in chuncks and stores the size of them. The full
346
-- memory can be used, except for one word, or a specified (using generic)
347
-- maximum number of frames.
348
-------------------------------------------------------------------------------
349
 
350
library ieee;
351
use ieee.std_logic_1164.all;
352
use ieee.numeric_std.all;
353
 
354
 
355
-------------------------------------------------------------------------------
356
-- Entity for PacketBufferContinous.
357
-------------------------------------------------------------------------------
358
entity PacketBufferContinous is
359
  generic(
360 7 magro732
    SIZE_ADDRESS_WIDTH : natural;
361
    CONTENT_ADDRESS_WIDTH : natural);
362 3 magro732
  port(
363
    clk : in std_logic;
364
    areset_n : in std_logic;
365
 
366
    writeFrameFull_o : out std_logic;
367
    writeFrame_i : in std_logic;
368
    writeFrameAbort_i : in std_logic;
369
    writeContent_i : in std_logic;
370
    writeContentData_i : in std_logic_vector(31 downto 0);
371
 
372
    readFrameEmpty_o : out std_logic;
373
    readFrame_i : in std_logic;
374
    readFrameRestart_i : in std_logic;
375
    readFrameAborted_o : out std_logic;
376
 
377
    readContentEmpty_o : out std_logic;
378
    readContent_i : in std_logic;
379
    readContentEnd_o : out std_logic;
380
    readContentData_o : out std_logic_vector(31 downto 0));
381
end entity;
382
 
383
 
384
-------------------------------------------------------------------------------
385
-- Architecture for PacketBufferContinous.
386
-------------------------------------------------------------------------------
387
architecture PacketBufferContinousImpl of PacketBufferContinous is
388
 
389
  component MemorySimpleDualPortAsync is
390
    generic(
391
      ADDRESS_WIDTH : natural := 1;
392
      DATA_WIDTH : natural := 1);
393
    port(
394
      clkA_i : in std_logic;
395
      enableA_i : in std_logic;
396
      addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
397
      dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
398
 
399
      addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
400
      dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
401
  end component;
402
 
403
  component MemorySimpleDualPort is
404
    generic(
405
      ADDRESS_WIDTH : natural := 1;
406
      DATA_WIDTH : natural := 1);
407
    port(
408
      clkA_i : in std_logic;
409
      enableA_i : in std_logic;
410
      addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
411
      dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
412
 
413
      clkB_i : in std_logic;
414
      enableB_i : in std_logic;
415
      addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
416
      dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
417
  end component;
418
 
419
  -- The number of available word positions left in the memory.
420
  signal available : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
421
 
422
  -- The position to place new frames.
423
  signal backIndex, backIndexNext : unsigned(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
424
 
425
  -- The position to remove old frames.
426
  signal frontIndex, frontIndexNext : unsigned(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
427
 
428
  -- The size of the current frame.
429
  signal readFrameEnd_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
430
 
431
  -- The start of unread content.
432
  signal memoryStart_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
433
 
434
  -- The current reading position.
435
  signal memoryRead_p, memoryReadNext_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
436
 
437
  -- The end of unread content.
438
  signal memoryEnd_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
439
 
440
  -- The current writing position.
441
  signal memoryWrite_p, memoryWriteNext_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
442
 
443
  -- Memory output signal containing the position of a frame.
444
  signal framePositionReadData : std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
445
begin
446
 
447
  -----------------------------------------------------------------------------
448
  -- Internal signal assignments.
449
  -----------------------------------------------------------------------------
450
 
451
  available <= not (memoryEnd_p - memoryStart_p);
452
 
453
  backIndexNext <= backIndex + 1;
454
  frontIndexNext <= frontIndex + 1;
455
 
456
  memoryWriteNext_p <= memoryWrite_p + 1;
457
  memoryReadNext_p <= memoryRead_p + 1;
458
 
459
  -----------------------------------------------------------------------------
460
  -- Writer logic.
461
  -----------------------------------------------------------------------------
462
 
463
  writeFrameFull_o <= '1' when ((backIndexNext = frontIndex) or
464
                                (available <= 68)) else '0';
465
 
466
  Writer: process(clk, areset_n)
467
  begin
468
    if (areset_n = '0') then
469
      backIndex <= (others=>'0');
470
 
471
      memoryEnd_p <= (others=>'0');
472
      memoryWrite_p <= (others=>'0');
473
    elsif (clk'event and clk = '1') then
474
 
475
      if (writeFrameAbort_i = '1') then
476
        memoryWrite_p <= memoryEnd_p;
477
      elsif (writeContent_i = '1') then
478
        memoryWrite_p <= memoryWriteNext_p;
479
      end if;
480
 
481
      if(writeFrame_i = '1') then
482
        memoryEnd_p <= memoryWrite_p;
483
        backIndex <= backIndexNext;
484
      end if;
485
 
486
    end if;
487
  end process;
488
 
489
  -----------------------------------------------------------------------------
490
  -- Frame cancellation logic.
491
  -----------------------------------------------------------------------------
492
 
493
  process(clk, areset_n)
494
  begin
495
    if (areset_n = '0') then
496
      readFrameAborted_o <= '0';
497
    elsif (clk'event and clk = '1') then
498
 
499
      if ((frontIndex = backIndex) and
500
          ((writeFrameAbort_i = '1') and (readFrameRestart_i = '0'))) then
501
        readFrameAborted_o <= '1';
502
      elsif ((writeFrameAbort_i = '0') and (readFrameRestart_i = '1')) then
503
        readFrameAborted_o <= '0';
504
      end if;
505
 
506
    end if;
507
  end process;
508
 
509
  -----------------------------------------------------------------------------
510
  -- Reader logic.
511
  -----------------------------------------------------------------------------
512
 
513
  readFrameEmpty_o <= '1' when (frontIndex = backIndex) else '0';
514
  readContentEmpty_o <= '1' when ((frontIndex = backIndex) and
515
                                  (memoryWrite_p = memoryRead_p)) else '0';
516
 
517
  Reader: process(clk, areset_n)
518
  begin
519
    if (areset_n = '0') then
520
      frontIndex <= (others=>'0');
521
 
522
      memoryStart_p <= (others=>'0');
523
      memoryRead_p <= (others=>'0');
524
 
525
      readContentEnd_o <= '0';
526
    elsif (clk'event and clk = '1') then
527
 
528
      -- REMARK: Break apart into registers to avoid priority ladder???
529
      if(readFrameRestart_i = '1') then
530
        memoryRead_p <= memoryStart_p;
531
      elsif(readContent_i = '1') then
532
        if(memoryRead_p = readFrameEnd_p) then
533
          readContentEnd_o <= '1';
534
        else
535
          readContentEnd_o <= '0';
536
          memoryRead_p <= memoryReadNext_p;
537
        end if;
538
      elsif(readFrame_i = '1') then
539
        memoryStart_p <= readFrameEnd_p;
540
        frontIndex <= frontIndexNext;
541
        memoryRead_p <= readFrameEnd_p;
542
      end if;
543
 
544
    end if;
545
  end process;
546
 
547
  -----------------------------------------------------------------------------
548
  -- Frame positioning memory signals.
549
  -----------------------------------------------------------------------------
550
 
551
  readFrameEnd_p <= unsigned(framePositionReadData);
552
 
553
  -- Memory to keep frame starting/ending positions in.
554
  FramePosition: MemorySimpleDualPortAsync
555
    generic map(ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH, DATA_WIDTH=>CONTENT_ADDRESS_WIDTH)
556
    port map(
557
      clkA_i=>clk, enableA_i=>writeFrame_i,
558
      addressA_i=>std_logic_vector(backIndex), dataA_i=>std_logic_vector(memoryWrite_p),
559
      addressB_i=>std_logic_vector(frontIndex), dataB_o=>framePositionReadData);
560
 
561
  -----------------------------------------------------------------------------
562
  -- Frame content memory signals.
563
  -----------------------------------------------------------------------------
564
 
565
  -- Memory to keep frame content in.
566
  -- REMARK: Use paritybits here as well to make sure the frame data does not
567
  -- become corrupt???
568
  FrameContent: MemorySimpleDualPort
569
    generic map(ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH, DATA_WIDTH=>32)
570
    port map(
571
      clkA_i=>clk, enableA_i=>writeContent_i,
572
      addressA_i=>std_logic_vector(memoryWrite_p), dataA_i=>writeContentData_i,
573
      clkB_i=>clk, enableB_i=>readContent_i,
574
      addressB_i=>std_logic_vector(memoryRead_p), dataB_o=>readContentData_o);
575
 
576
end architecture;
577
 
578
 
579
 
580
-------------------------------------------------------------------------------
581
-- PacketBufferContinousWindow
582
-- This component stores data in chuncks and stores the size of them. The full
583
-- memory can be used, except for one word, or a specified (using generic)
584
-- maximum number of frames.
585
-------------------------------------------------------------------------------
586
 
587
library ieee;
588
use ieee.std_logic_1164.all;
589
use ieee.numeric_std.all;
590
 
591
 
592
-------------------------------------------------------------------------------
593
-- Entity for PacketBufferContinousWindow.
594
-------------------------------------------------------------------------------
595
entity PacketBufferContinousWindow is
596
  generic(
597 7 magro732
    SIZE_ADDRESS_WIDTH : natural;
598
    CONTENT_ADDRESS_WIDTH : natural);
599 3 magro732
  port(
600
    clk : in std_logic;
601
    areset_n : in std_logic;
602
 
603
    writeFrameFull_o : out std_logic;
604
    writeFrame_i : in std_logic;
605
    writeFrameAbort_i : in std_logic;
606
    writeContent_i : in std_logic;
607
    writeContentData_i : in std_logic_vector(31 downto 0);
608
 
609
    readFrameEmpty_o : out std_logic;
610
    readFrame_i : in std_logic;
611
    readFrameRestart_i : in std_logic;
612
    readFrameAborted_o : out std_logic;
613
 
614
    readWindowEmpty_o : out std_logic;
615
    readWindowReset_i : in std_logic;
616
    readWindowNext_i : in std_logic;
617
 
618
    readContentEmpty_o : out std_logic;
619
    readContent_i : in std_logic;
620
    readContentEnd_o : out std_logic;
621
    readContentData_o : out std_logic_vector(31 downto 0));
622
end entity;
623
 
624
 
625
-------------------------------------------------------------------------------
626
-- Architecture for PacketBufferContinousWindow.
627
-------------------------------------------------------------------------------
628
architecture PacketBufferContinousWindowImpl of PacketBufferContinousWindow is
629
 
630
  component MemorySimpleDualPortAsync is
631
    generic(
632
      ADDRESS_WIDTH : natural := 1;
633
      DATA_WIDTH : natural := 1);
634
    port(
635
      clkA_i : in std_logic;
636
      enableA_i : in std_logic;
637
      addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
638
      dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
639
 
640
      addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
641
      dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
642
  end component;
643
 
644
  component MemorySimpleDualPort is
645
    generic(
646
      ADDRESS_WIDTH : natural := 1;
647
      DATA_WIDTH : natural := 1);
648
    port(
649
      clkA_i : in std_logic;
650
      enableA_i : in std_logic;
651
      addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
652
      dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
653
 
654
      clkB_i : in std_logic;
655
      enableB_i : in std_logic;
656
      addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
657
      dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
658
  end component;
659
 
660
  -- The number of available word positions left in the memory.
661
  signal available : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
662
 
663
  signal backIndex, backIndexNext : unsigned(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
664
  signal frontIndex, frontIndexNext : unsigned(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
665
  signal windowIndex, windowIndexNext : unsigned(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
666
 
667
  -- The size of the current frame.
668
  signal readFrameEnd_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
669
 
670
  -- The start of unread content.
671
  signal memoryStart_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
672
 
673
  -- The start of unread window content.
674
  signal memoryStartWindow_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
675
 
676
  -- The current reading position.
677
  signal memoryRead_p, memoryReadNext_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
678
 
679
  -- The end of unread content.
680
  signal memoryEnd_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
681
 
682
  -- The current writing position.
683
  signal memoryWrite_p, memoryWriteNext_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
684
 
685
  signal framePositionReadAddress : std_logic_vector(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
686
  signal framePositionReadData : std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
687
begin
688
 
689
  -----------------------------------------------------------------------------
690
  -- Internal signal assignments.
691
  -----------------------------------------------------------------------------
692
 
693
  available <= not (memoryEnd_p - memoryStart_p);
694
 
695
  backIndexNext <= backIndex + 1;
696
  frontIndexNext <= frontIndex + 1;
697
  windowIndexNext <= windowIndex + 1;
698
 
699
  memoryWriteNext_p <= memoryWrite_p + 1;
700
  memoryReadNext_p <= memoryRead_p + 1;
701
 
702
  -----------------------------------------------------------------------------
703
  -- Writer logic.
704
  -----------------------------------------------------------------------------
705
 
706
  writeFrameFull_o <= '1' when ((backIndexNext = frontIndex) or
707
                                (available <= 68)) else '0';
708
 
709
  Writer: process(clk, areset_n)
710
  begin
711
    if (areset_n = '0') then
712
      backIndex <= (others=>'0');
713
 
714
      memoryEnd_p <= (others=>'0');
715
      memoryWrite_p <= (others=>'0');
716
    elsif (clk'event and clk = '1') then
717
 
718
      if (writeFrameAbort_i = '1') then
719
        memoryWrite_p <= memoryEnd_p;
720
      elsif (writeContent_i = '1') then
721
        memoryWrite_p <= memoryWriteNext_p;
722
      end if;
723
 
724
      if(writeFrame_i = '1') then
725
        memoryEnd_p <= memoryWrite_p;
726
        backIndex <= backIndexNext;
727
      end if;
728
 
729
    end if;
730
  end process;
731
 
732
  -----------------------------------------------------------------------------
733
  -- Frame cancellation logic.
734
  -----------------------------------------------------------------------------
735
 
736
  process(clk, areset_n)
737
  begin
738
    if (areset_n = '0') then
739
      readFrameAborted_o <= '0';
740
    elsif (clk'event and clk = '1') then
741
 
742
      if ((windowIndex = backIndex) and
743
          ((writeFrameAbort_i = '1') and (readFrameRestart_i = '0'))) then
744
        readFrameAborted_o <= '1';
745
      elsif ((writeFrameAbort_i = '0') and (readFrameRestart_i = '1')) then
746
        readFrameAborted_o <= '0';
747
      end if;
748
 
749
    end if;
750
  end process;
751
 
752
  -----------------------------------------------------------------------------
753
  -- Reader logic.
754
  -----------------------------------------------------------------------------
755
 
756
  readFrameEmpty_o <= '1' when (frontIndex = backIndex) else '0';
757
  readWindowEmpty_o <= '1' when (windowIndex = backIndex) else '0';
758
  readContentEmpty_o <= '1' when ((windowIndex = backIndex) and
759
                                  (memoryWrite_p = memoryRead_p)) else '0';
760
 
761
  Reader: process(clk, areset_n)
762
  begin
763
    if (areset_n = '0') then
764
      frontIndex <= (others=>'0');
765
      windowIndex <= (others=>'0');
766
 
767
      memoryStart_p <= (others=>'0');
768
      memoryStartWindow_p <= (others=>'0');
769
      memoryRead_p <= (others=>'0');
770
 
771
      readContentEnd_o <= '0';
772
    elsif (clk'event and clk = '1') then
773
 
774
      -- REMARK: Break apart into registers to avoid priority ladder???
775
      if(readFrameRestart_i = '1') then
776
        memoryRead_p <= memoryStartWindow_p;
777
      elsif(readContent_i = '1') then
778 16 magro732
        if(memoryReadNext_p = readFrameEnd_p) then
779 3 magro732
          readContentEnd_o <= '1';
780
        else
781
          readContentEnd_o <= '0';
782
          memoryRead_p <= memoryReadNext_p;
783
        end if;
784
      elsif(readFrame_i = '1') then
785
        memoryStart_p <= readFrameEnd_p;
786
        frontIndex <= frontIndexNext;
787
      elsif(readWindowReset_i = '1') then
788
        memoryStartWindow_p <= memoryStart_p;
789
        windowIndex <= frontIndex;
790
        memoryRead_p <= memoryStart_p;
791
      elsif(readWindowNext_i = '1') then
792
        memoryStartWindow_p <= readFrameEnd_p;
793
        windowIndex <= windowIndexNext;
794
        memoryRead_p <= readFrameEnd_p;
795
      end if;
796
 
797
    end if;
798
  end process;
799
 
800
  -----------------------------------------------------------------------------
801
  -- Frame positioning memory signals.
802
  -----------------------------------------------------------------------------
803
 
804
  -- Assign the address from both frontIndex and windowIndex to be able to
805
  -- share the memory between the two different types of accesses. This assumes
806
  -- that the window is not accessed at the same time as the other signal.
807
  framePositionReadAddress <= std_logic_vector(frontIndex) when (readFrame_i = '1') else
808
                              std_logic_vector(windowIndex);
809
  readFrameEnd_p <= unsigned(framePositionReadData);
810
 
811
  -- Memory to keep frame starting/ending positions in.
812
  FramePosition: MemorySimpleDualPortAsync
813
    generic map(ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH, DATA_WIDTH=>CONTENT_ADDRESS_WIDTH)
814
    port map(
815
      clkA_i=>clk, enableA_i=>writeFrame_i,
816
      addressA_i=>std_logic_vector(backIndex), dataA_i=>std_logic_vector(memoryWrite_p),
817
      addressB_i=>framePositionReadAddress, dataB_o=>framePositionReadData);
818
 
819
  -----------------------------------------------------------------------------
820
  -- Frame content memory signals.
821
  -----------------------------------------------------------------------------
822
 
823
  -- Memory to keep frame content in.
824
  -- REMARK: Use paritybits here as well to make sure the frame data does not
825
  -- become corrupt???
826
  FrameContent: MemorySimpleDualPort
827
    generic map(ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH, DATA_WIDTH=>32)
828
    port map(
829
      clkA_i=>clk, enableA_i=>writeContent_i,
830
      addressA_i=>std_logic_vector(memoryWrite_p), dataA_i=>writeContentData_i,
831
      clkB_i=>clk, enableB_i=>readContent_i,
832
      addressB_i=>std_logic_vector(memoryRead_p), dataB_o=>readContentData_o);
833
 
834
end architecture;

powered by: WebSVN 2.1.0

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