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

Subversion Repositories rio

[/] [rio/] [trunk/] [rtl/] [vhdl/] [RioPacketBuffer.vhd] - Blame information for rev 4

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

powered by: WebSVN 2.1.0

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