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

Subversion Repositories rio

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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 33 magro732
-------------------------------------------------------------------------------
2 36 magro732
-- 
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 48 magro732
-- Contains a platform to build endpoints on. It handles CRC insertion/removal
10
-- and unpacks the deviceId in a packet into a fixed 32-bit to make the parsing
11
-- of packets in higher layers easier. It also discards packets that does not
12
-- have a handler.
13 36 magro732
-- 
14
-- To Do:
15 48 magro732
-- - 8-bit deviceId has not been implemented, fix either as seperate
16
--   architecture or an architecture with combined 8- and 16-bit support.
17 46 magro732
-- - Egress; Place packets in different queues depending on the packet priority?
18 36 magro732
-- 
19
-- Author(s): 
20
-- - Magnus Rosenius, magro732@opencores.org 
21
-- 
22
-------------------------------------------------------------------------------
23
-- 
24
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
25
-- 
26
-- This source file may be used and distributed without 
27
-- restriction provided that this copyright statement is not 
28
-- removed from the file and that any derivative work contains 
29
-- the original copyright notice and the associated disclaimer. 
30
-- 
31
-- This source file is free software; you can redistribute it 
32
-- and/or modify it under the terms of the GNU Lesser General 
33
-- Public License as published by the Free Software Foundation; 
34
-- either version 2.1 of the License, or (at your option) any 
35
-- later version. 
36
-- 
37
-- This source is distributed in the hope that it will be 
38
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
39
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
40
-- PURPOSE. See the GNU Lesser General Public License for more 
41
-- details. 
42
-- 
43
-- You should have received a copy of the GNU Lesser General 
44
-- Public License along with this source; if not, download it 
45
-- from http://www.opencores.org/lgpl.shtml 
46
-- 
47
-------------------------------------------------------------------------------
48
 
49 47 magro732
 
50 36 magro732
-------------------------------------------------------------------------------
51 33 magro732
-- RioLogicalCommon.
52
-------------------------------------------------------------------------------
53
-- Ingress:
54 48 magro732
-- * Removes in-the-middle CRC. The trailing CRC is not removed since it is not
55
--   possible to know in which half-word it is placed without knowing how the
56
--   packet should be parsed.
57
-- * Forwards packets to logical-layer handlers depending on ftype. The
58
--   ftype-field is output as address.
59
-- * Outputs header and deviceIDs in seperate accesses to facilitate supporting
60
--   different deviceId sizes. All fields are right-justified.
61
-- * stall_i is used to stop the flow of data. The flow will continue when
62
--   stall_i is deasserted. The stall_i signals should not be registered. If
63
--   there is no handler for a packet, stall_i will not go high and the packet
64
--   will be automatically discarded.
65 33 magro732
-- Egress:
66 35 magro732
-- * Adds in-the-middle and trailing CRC.
67 48 magro732
-- * Receives packets from a configurable number of logical-layer handlers.
68
--   This enables more complex endpoints with several independent
69
--   funtionalities.
70
-- * Receives header and deviceId in seperate accesses to facilitate
71
--   supporting different deviceId sizes. All fields are right-justified. The
72
--   size of the deviceId is indicated by the TT-field in the header.
73
-- * The adr_i-input signal on the egress side is used to indicate if the last
74
--   word contains one or two half-words. This is used to know where to insert
75
--   the trailing CRC. It should be set at the start of the frame. If all
76
--   frames always have the CRC in the same place it is ok to set this signal
77
--   constant.
78
-- Examples of how to write a handler for a packet can be found in
79
-- RioLogicalPackets.vhd.
80 33 magro732
-------------------------------------------------------------------------------
81 36 magro732
library ieee;
82
use ieee.std_logic_1164.all;
83
use ieee.numeric_std.all;
84
use work.rio_common.all;
85
 
86
 
87 38 magro732
-------------------------------------------------------------------------------
88 47 magro732
-- Entity for RioLogicalCommon.
89 38 magro732
-------------------------------------------------------------------------------
90 36 magro732
entity RioLogicalCommon is
91 45 magro732
  generic(
92 48 magro732
    PORTS : natural := 1);
93 36 magro732
  port(
94
    clk : in std_logic;
95
    areset_n : in std_logic;
96
    enable : in std_logic;
97
 
98
    readFrameEmpty_i : in std_logic;
99
    readFrame_o : out std_logic;
100
    readContent_o : out std_logic;
101
    readContentEnd_i : in std_logic;
102
    readContentData_i : in std_logic_vector(31 downto 0);
103 39 magro732
 
104 36 magro732
    writeFrameFull_i : in std_logic;
105
    writeFrame_o : out std_logic;
106
    writeFrameAbort_o : out std_logic;
107
    writeContent_o : out std_logic;
108
    writeContentData_o : out std_logic_vector(31 downto 0);
109
 
110 45 magro732
    inboundStb_o : out std_logic;
111 48 magro732
    inboundAdr_o : out std_logic_vector(3 downto 0);
112 45 magro732
    inboundDat_o : out std_logic_vector(31 downto 0);
113 48 magro732
    inboundStall_i : in std_logic;
114 39 magro732
 
115 45 magro732
    outboundStb_i : in std_logic_vector(PORTS-1 downto 0);
116 48 magro732
    outboundAdr_i : in std_logic_vector(PORTS-1 downto 0);
117 45 magro732
    outboundDat_i : in std_logic_vector(32*PORTS-1 downto 0);
118 48 magro732
    outboundStall_o : out std_logic_vector(PORTS-1 downto 0));
119 36 magro732
end entity;
120
 
121
 
122 38 magro732
-------------------------------------------------------------------------------
123 47 magro732
-- Architecture for RioLogicalCommon.
124 38 magro732
-------------------------------------------------------------------------------
125 36 magro732
architecture RioLogicalCommon of RioLogicalCommon is
126
 
127 45 magro732
  component RioLogicalCommonInterconnect is
128
    generic(
129
      WIDTH : natural);
130
    port(
131
      clk : in std_logic;
132
      areset_n : in std_logic;
133
 
134
      stb_i : in std_logic_vector(WIDTH-1 downto 0);
135 48 magro732
      adr_i : in std_logic_vector(WIDTH-1 downto 0);
136
      data_i : in std_logic_vector(32*WIDTH-1 downto 0);
137
      stall_o : out std_logic_vector(WIDTH-1 downto 0);
138 45 magro732
 
139
      stb_o : out std_logic;
140 48 magro732
      adr_o : out std_logic;
141
      data_o : out std_logic_vector(31 downto 0);
142
      stall_i : in std_logic);
143 45 magro732
  end component;
144
 
145 36 magro732
  component RioLogicalCommonIngress is
146
    port(
147
      clk : in std_logic;
148
      areset_n : in std_logic;
149
 
150
      readFrameEmpty_i : in std_logic;
151
      readFrame_o : out std_logic;
152
      readContent_o : out std_logic;
153
      readContentEnd_i : in std_logic;
154
      readContentData_i : in std_logic_vector(31 downto 0);
155
 
156 48 magro732
      stb_o : out std_logic;
157
      adr_o : out std_logic_vector(3 downto 0);
158
      dat_o : out std_logic_vector(31 downto 0);
159
      stall_i : in std_logic);
160 36 magro732
  end component;
161
 
162
  component RioLogicalCommonEgress is
163
    port(
164
      clk : in std_logic;
165
      areset_n : in std_logic;
166
 
167
      writeFrameFull_i : in std_logic;
168
      writeFrame_o : out std_logic;
169
      writeFrameAbort_o : out std_logic;
170
      writeContent_o : out std_logic;
171
      writeContentData_o : out std_logic_vector(31 downto 0);
172
 
173 48 magro732
      stb_i : in std_logic;
174
      adr_i : in std_logic;
175
      dat_i : in std_logic_vector(31 downto 0);
176
      stall_o : out std_logic);
177 36 magro732
  end component;
178
 
179 45 magro732
  signal outboundStb : std_logic;
180 48 magro732
  signal outboundAdr : std_logic;
181 45 magro732
  signal outboundDat : std_logic_vector(31 downto 0);
182 48 magro732
  signal outboundStall : std_logic;
183 45 magro732
 
184 36 magro732
begin
185
 
186 38 magro732
  Ingress: RioLogicalCommonIngress
187
    port map(
188
      clk=>clk, areset_n=>areset_n,
189
      readFrameEmpty_i=>readFrameEmpty_i,
190
      readFrame_o=>readFrame_o,
191
      readContent_o=>readContent_o,
192
      readContentEnd_i=>readContentEnd_i,
193
      readContentData_i=>readContentData_i,
194 48 magro732
      stb_o=>inboundStb_o,
195
      adr_o=>inboundAdr_o,
196
      dat_o=>inboundDat_o,
197
      stall_i=>inboundStall_i);
198 38 magro732
 
199 45 magro732
  EgressInterconnect: RioLogicalCommonInterconnect
200
    generic map(WIDTH=>PORTS)
201
    port map(
202
      clk=>clk, areset_n=>areset_n,
203 48 magro732
      stb_i=>outboundStb_i,
204
      adr_i=>outboundAdr_i,
205
      data_i=>outboundDat_i,
206
      stall_o=>outboundStall_o,
207
      stb_o=>outboundStb,
208
      adr_o=>outboundAdr,
209
      data_o=>outboundDat,
210
      stall_i=>outboundStall);
211 45 magro732
 
212 36 magro732
  Egress: RioLogicalCommonEgress
213
    port map(
214
      clk=>clk, areset_n=>areset_n,
215
      writeFrameFull_i=>writeFrameFull_i,
216
      writeFrame_o=>writeFrame_o,
217
      writeFrameAbort_o=>writeFrameAbort_o,
218
      writeContent_o=>writeContent_o,
219
      writeContentData_o=>writeContentData_o,
220 48 magro732
      stb_i=>outboundStb,
221
      adr_i=>outboundAdr,
222
      dat_i=>outboundDat,
223
      stall_o=>outboundStall);
224 36 magro732
 
225
end architecture;
226
 
227
 
228
 
229 34 magro732
-------------------------------------------------------------------------------
230
-- RioLogicalCommonIngress.
231
-------------------------------------------------------------------------------
232 33 magro732
library ieee;
233 34 magro732
use ieee.std_logic_1164.all;
234 33 magro732
use ieee.numeric_std.all;
235
use work.rio_common.all;
236
 
237 47 magro732
 
238 33 magro732
-------------------------------------------------------------------------------
239
-- Entity for RioLogicalCommonIngress.
240
-------------------------------------------------------------------------------
241
entity RioLogicalCommonIngress is
242
  port(
243
    clk : in std_logic;
244
    areset_n : in std_logic;
245
 
246
    readFrameEmpty_i : in std_logic;
247
    readFrame_o : out std_logic;
248
    readContent_o : out std_logic;
249
    readContentEnd_i : in std_logic;
250
    readContentData_i : in std_logic_vector(31 downto 0);
251
 
252 48 magro732
    stb_o : out std_logic;
253
    adr_o : out std_logic_vector(3 downto 0);
254
    dat_o : out std_logic_vector(31 downto 0);
255
    stall_i : in std_logic);
256 33 magro732
end entity;
257
 
258
 
259
-------------------------------------------------------------------------------
260 48 magro732
-- Architecture for RioLogicalCommonIngress16.
261
-- Only 16-bit deviceId are supported.
262 33 magro732
-------------------------------------------------------------------------------
263 48 magro732
architecture RioLogicalCommonIngress16 of RioLogicalCommonIngress is
264 33 magro732
 
265 48 magro732
  signal packetPosition : natural range 0 to 74;
266
 
267
  signal loadValue, loadValue16 : std_logic_vector(63 downto 0);
268 36 magro732
  signal packetContent : std_logic_vector(63 downto 0);
269
 
270
  signal tt : std_logic_vector(1 downto 0);
271
  signal ftype : std_logic_vector(3 downto 0);
272 48 magro732
 
273
  signal readContent : std_logic;
274
  signal readFrame : std_logic;
275 36 magro732
 
276 33 magro732
begin
277 48 magro732
  readContent_o <= readContent;
278
  readFrame_o <= readFrame;
279
 
280
  adr_o <= ftype;
281
  dat_o <= packetContent(63 downto 32);
282 33 magro732
 
283 48 magro732
  loadValue16 <=
284
    (x"0000" & packetContent(31 downto 16) & readContentData_i) when (packetPosition = 4) else
285
    (x"0000" & packetContent(31 downto 0) & x"0000") when (packetPosition = 5) else
286
    (packetContent(31 downto 16) & readContentData_i & x"0000") when (packetPosition < 24) else
287
    (packetContent(31 downto 16) & readContentData_i(15 downto 0) & x"00000000") when (packetPosition = 24) else
288
    (readContentData_i & x"00000000");
289
  loadValue <= loadValue16 when (tt = "01") else (x"0000" & readContentData_i & x"0000");
290
  shifter: process(clk, areset_n)
291 33 magro732
  begin
292
    if (areset_n = '0') then
293 48 magro732
      packetContent <= (others=>'0');
294
    elsif (clk'event and clk = '1') then
295
      if ((stall_i = '0') and (readFrameEmpty_i = '0')) then
296
        packetContent <= loadValue;
297
      end if;
298
    end if;
299
  end process;
300
 
301
  packetCounter: process(clk, areset_n)
302
  begin
303
    if (areset_n = '0') then
304 36 magro732
      packetPosition <= 0;
305 48 magro732
    elsif (clk'event and clk = '1') then
306
      if (readFrame = '1') or (readFrameEmpty_i = '1') then
307
        packetPosition <= 0;
308
      elsif (stall_i = '0') then
309
        packetPosition <= packetPosition + 1;
310
      end if;
311
    end if;
312
  end process;
313
 
314
  headerRegister: process(clk, areset_n)
315
  begin
316
    if (areset_n = '0') then
317 36 magro732
      tt <= "00";
318
      ftype <= "0000";
319 48 magro732
    elsif (clk'event and clk = '1') then
320
      if (readFrame = '1') then
321
        tt <= "00";
322
        ftype <= "0000";
323
      elsif (stall_i = '0') and (packetPosition = 3) then
324
        tt <= readContentData_i(21 downto 20);
325
        ftype <= readContentData_i(19 downto 16);
326
      end if;
327
    end if;
328
  end process;
329 38 magro732
 
330 48 magro732
  controller: process(clk, areset_n)
331
  begin
332
    if (areset_n = '0') then
333
      readContent <= '0';
334
      readFrame <= '0';
335
      stb_o <= '0';
336 33 magro732
    elsif (clk'event and clk = '1') then
337 48 magro732
      if (stall_i = '0') then
338
        case packetPosition is
339
          when 0 =>
340
            readContent <= '0';
341
            readFrame <= '0';
342
            stb_o <= '0';
343
          when 1 =>
344
            readContent <= '1';
345
          when 2 =>
346
            readContent <= '1';
347
          when 3 =>
348
            readContent <= '0';
349
            stb_o <= '1';
350
          when others =>
351
            if (readFrame = '0') then
352
              stb_o <= not readContentEnd_i;
353
              readFrame <= readContentEnd_i;
354
              readContent <= not readContentEnd_i;
355 36 magro732
            else
356 48 magro732
              readFrame <= '0';
357 36 magro732
            end if;
358 48 magro732
        end case;
359
      end if;
360 33 magro732
    end if;
361
  end process;
362
 
363
end architecture;
364
 
365
 
366 47 magro732
 
367 34 magro732
-------------------------------------------------------------------------------
368
-- RioLogicalCommonEgress.
369
-------------------------------------------------------------------------------
370
library ieee;
371
use ieee.std_logic_1164.all;
372
use ieee.numeric_std.all;
373
use work.rio_common.all;
374 33 magro732
 
375 47 magro732
 
376 34 magro732
-------------------------------------------------------------------------------
377
-- Entity for RioLogicalCommonEgress.
378
-------------------------------------------------------------------------------
379
entity RioLogicalCommonEgress is
380
  port(
381
    clk : in std_logic;
382
    areset_n : in std_logic;
383 33 magro732
 
384 34 magro732
    writeFrameFull_i : in std_logic;
385
    writeFrame_o : out std_logic;
386
    writeFrameAbort_o : out std_logic;
387
    writeContent_o : out std_logic;
388
    writeContentData_o : out std_logic_vector(31 downto 0);
389
 
390 48 magro732
    stb_i : in std_logic;
391
    adr_i : in std_logic;
392
    dat_i : in std_logic_vector(31 downto 0);
393
    stall_o : out std_logic);
394 34 magro732
end entity;
395
 
396
 
397 33 magro732
-------------------------------------------------------------------------------
398 48 magro732
-- Architecture for RioLogicalCommonEgress16.
399
-- Only 16-bit deviceId are supported. The first write must contain
400
-- the 16-bit header, the second write must contain the destination address and
401
-- the third must contain the source address.
402
-- CRC is calculated during the transfer and is inserted at byte 81 and 82 and
403
-- appended to the packet when it ends.
404 34 magro732
-------------------------------------------------------------------------------
405 48 magro732
architecture RioLogicalCommonEgress16 of RioLogicalCommonEgress is
406 34 magro732
 
407 48 magro732
  signal stb, cycleEndCurrent, cycleEndNext : std_logic;
408 36 magro732
 
409 48 magro732
  signal packetPosition : natural range 0 to 72;
410 37 magro732
 
411 48 magro732
  signal loadValue : std_logic_vector(47 downto 0);
412
  signal packetContent : std_logic_vector(47 downto 0);
413
  signal packetContentReady : std_logic;
414
  signal packetContentOdd : std_logic;
415
  signal packetContentLong : std_logic;
416
  signal packetContentEnd : std_logic;
417
  signal packetContentPending : std_logic;
418
 
419 44 magro732
  signal writeContent : std_logic;
420 48 magro732
  signal writeFrame : std_logic;
421
  signal writeContentData : std_logic_vector(31 downto 0);
422 44 magro732
 
423 48 magro732
  signal crcCurrent, crcTemp, crcNext: std_logic_vector(15 downto 0);
424
 
425 34 magro732
begin
426
 
427 48 magro732
  -----------------------------------------------------------------------------
428
  -- Packet cycle end detection.
429
  -----------------------------------------------------------------------------
430
  stbDelayFF: process(clk, areset_n)
431 34 magro732
  begin
432
    if (areset_n = '0') then
433 48 magro732
      stb <= '0';
434 44 magro732
    elsif (clk'event and clk = '1') then
435 48 magro732
      if (writeFrame = '1') then
436
        stb <= '0';
437
      elsif (writeFrameFull_i = '0') then
438
        stb <= stb_i;
439 44 magro732
      end if;
440
    end if;
441
  end process;
442 48 magro732
  cycleEndNext <= (stb and (not stb_i));
443
  cycleEndFF: process(clk, areset_n)
444 44 magro732
  begin
445
    if (areset_n = '0') then
446 48 magro732
      cycleEndCurrent <= '0';
447
    elsif (clk'event and clk = '1') then
448
      if (writeFrame = '1') then
449
        cycleEndCurrent <= '0';
450
      elsif (cycleEndNext = '1') then
451
        cycleEndCurrent <= '1';
452
      end if;
453
    end if;
454
  end process;
455
  packetContentEnd <= cycleEndNext or cycleEndCurrent;
456
 
457
  -----------------------------------------------------------------------------
458
  -- Packet positioning.
459
  -----------------------------------------------------------------------------
460
  packetPositionCounter: process(clk, areset_n)
461
  begin
462
    if (areset_n = '0') then
463 44 magro732
      packetPosition <= 0;
464 48 magro732
    elsif (clk'event and clk = '1') then
465
      if (writeFrame = '1') then
466
        packetPosition <= 0;
467
      elsif (stb_i = '1') and (writeFrameFull_i = '0') then
468
        packetPosition <= packetPosition + 1;
469
      end if;
470
    end if;
471
  end process;
472 38 magro732
 
473 48 magro732
  -----------------------------------------------------------------------------
474
  -- Packet content creation.
475
  -----------------------------------------------------------------------------
476
  -- REMARK: The critical path is the crcNext through the loadValue-mux into
477
  -- packetContent. Register this path if possible.
478
  loadValue <=
479
    (packetContent(31 downto 0) & dat_i(15 downto 0)) when (packetContentReady = '0') else
480
    (packetContent(15 downto 0) & dat_i) when (packetContentLong = '0') else
481
    (crcNext & packetContent(15 downto 0) & x"0000") when (packetContentPending = '1') else
482
    (dat_i & x"0000");
483
  packetContentPlace: process(clk, areset_n)
484
  begin
485
    if (areset_n = '0') then
486
      packetContent <= (others=>'0');
487
    elsif (clk'event and clk = '1') then
488
      if (stb_i = '1') or (stb = '1') then
489
        packetContent <= loadValue;
490
      end if;
491
    end if;
492
  end process;
493 44 magro732
 
494 48 magro732
  -----------------------------------------------------------------------------
495
  -- Packet content generation controller.
496
  -----------------------------------------------------------------------------
497
  stall_o <= writeFrameFull_i when (packetContentReady = '0') else
498
             packetContentPending or packetContentEnd;
499
  controller: process(clk, areset_n)
500
  begin
501
    if (areset_n = '0') then
502
      packetContentReady <= '0';
503
      packetContentPending <= '0';
504
      packetContentLong <= '0';
505
      packetContentOdd <= '0';
506
    elsif (clk'event and clk = '1') then
507
      if (writeFrame = '1') then
508
        packetContentReady <= '0';
509
        packetContentPending <= '0';
510
        packetContentLong <= '0';
511
        packetContentOdd <= adr_i;
512
      elsif (stb_i = '1') and (writeFrameFull_i = '0') then
513
        packetContentOdd <= adr_i;
514
 
515
        case packetPosition is
516
          when 2 =>
517
            packetContentReady <= '1';
518
          when 21 =>
519
            packetContentPending <= '1';
520
            packetContentLong <= '1';
521
          when 22 =>
522
            packetContentPending <= '0';
523
            packetContentLong <= '1';
524
          when others =>
525
        end case;
526
      end if;
527
    end if;
528
  end process;
529 38 magro732
 
530 48 magro732
  -----------------------------------------------------------------------------
531
  -- CRC calculation and interface towards the packet queue.
532
  -----------------------------------------------------------------------------
533
  crcCalculation: process(clk, areset_n)
534
  begin
535
    if (areset_n = '0') then
536
      crcCurrent <= x"0000";
537 34 magro732
    elsif (clk'event and clk = '1') then
538 48 magro732
      if (packetContentReady = '0') then
539
        crcCurrent <= x"ffff";
540
      elsif (packetContentReady = '1') then
541
        crcCurrent <= crcNext;
542
      end if;
543
    end if;
544
  end process;
545
  Crc16High: Crc16CITT
546
    port map(
547
      d_i=>packetContent(47 downto 32), crc_i=>crcCurrent, crc_o=>crcTemp);
548
  Crc16Low: Crc16CITT
549
    port map(
550
      d_i=>packetContent(31 downto 16), crc_i=>crcTemp, crc_o=>crcNext);
551
 
552
  -----------------------------------------------------------------------------
553
  -- Frame buffer output interface.
554
  -----------------------------------------------------------------------------
555
  -- REMARK: This process needs to be optimized further. It is not part of the critical
556
  -- path though.
557
  writeFrameContent: process(clk, areset_n)
558
    variable flush : std_logic;
559
    variable appendCrc : std_ulogic;
560
    variable appendHigh : std_ulogic;
561
    variable endFrame : std_ulogic;
562
  begin
563
    if (areset_n = '0') then
564
      writeFrame <= '0';
565 44 magro732
      writeContent <= '0';
566 48 magro732
      writeContentData <= (others=>'0');
567
      flush := '0';
568
      appendCrc := '0';
569
      appendHigh := '0';
570
      endFrame := '0';
571
    elsif (clk'event and clk = '1') then
572
      if (writeFrame = '1') then
573
        writeFrame <= '0';
574
        writeContent <= '0';
575
        writeContentData <= (others=>'0');
576
        flush := '0';
577
        appendCrc := '0';
578
        appendHigh := '0';
579
        endFrame := '0';
580
      else
581
        if (flush = '1') then
582
          writeContent <= '1';
583
          writeContentData <= packetContent(47 downto 16);
584
          flush := '0';
585
        elsif (appendCrc = '1') then
586
          writeContent <= '1';
587
          if (appendHigh = '0') then
588
            writeContentData <= packetContent(47 downto 32) & crcTemp;
589 34 magro732
          else
590 48 magro732
            writeContentData <= crcCurrent & x"0000";
591 34 magro732
          end if;
592 48 magro732
          appendCrc := '0';
593
        elsif (endFrame = '1') then
594
          writeContent <= '0';
595
          writeFrame <= '1';
596
          endFrame := '0';
597
        elsif (packetContentPending = '1') and (packetContentEnd = '1') then
598
          writeContent <= '1';
599
          writeContentData <= packetContent(47 downto 16);
600
          flush := not packetContentOdd;
601
          appendCrc := '1';
602
          appendHigh := '1';
603
          endFrame := '1';
604
        elsif (packetContentEnd = '1') then
605
          if (packetContentLong = '0') then
606 44 magro732
            writeContent <= '1';
607 48 magro732
            writeContentData <= packetContent(47 downto 16);
608
            flush := '0';
609
            appendCrc := '1';
610
            appendHigh := packetContentOdd;
611
            endFrame := '1';
612 34 magro732
          else
613 48 magro732
            if (packetContentOdd = '1') then
614 44 magro732
              writeContent <= '1';
615 48 magro732
              writeContentData <= packetContent(47 downto 32) & crcTemp;
616
              flush := '0';
617
              appendCrc := '0';
618
              appendHigh := '0';
619
              endFrame := '1';
620
            else
621 44 magro732
              writeContent <= '1';
622 48 magro732
              writeContentData <= packetContent(47 downto 16);
623
              flush := '0';
624
              appendCrc := '1';
625
              appendHigh := '1';
626
              endFrame := '1';
627 44 magro732
            end if;
628 34 magro732
          end if;
629 48 magro732
        elsif (packetContentReady = '1') then
630
          writeContent <= '1';
631
          writeContentData <= packetContent(47 downto 16);
632
        else
633
          writeContent <= '0';
634
          writeFrame <= '0';
635
        end if;
636
      end if;
637 34 magro732
    end if;
638
  end process;
639 48 magro732
 
640
  writeContent_o <= writeContent;
641
  writeFrame_o <= writeFrame;
642
  writeFrameAbort_o <= '0';
643
  writeContentData_o <= writeContentData;
644
 
645 34 magro732
end architecture;
646 45 magro732
 
647
 
648
 
649 48 magro732
--------------------------------------------------------------------------------
650
-- RioLogicalCommonInterconnect.
651 45 magro732
-------------------------------------------------------------------------------
652
library ieee;
653
use ieee.std_logic_1164.all;
654
use ieee.numeric_std.all;
655
use work.rio_common.all;
656
 
657
 
658
-------------------------------------------------------------------------------
659 47 magro732
-- Entity for RioLogicalCommonInterconnect.
660 45 magro732
-------------------------------------------------------------------------------
661
entity RioLogicalCommonInterconnect is
662
  generic(
663
    WIDTH : natural);
664
  port(
665
    clk : in std_logic;
666
    areset_n : in std_logic;
667
 
668
    stb_i : in std_logic_vector(WIDTH-1 downto 0);
669 48 magro732
    adr_i : in std_logic_vector(WIDTH-1 downto 0);
670
    data_i : in std_logic_vector(32*WIDTH-1 downto 0);
671
    stall_o : out std_logic_vector(WIDTH-1 downto 0);
672 45 magro732
 
673
    stb_o : out std_logic;
674 48 magro732
    adr_o : out std_logic;
675
    data_o : out std_logic_vector(31 downto 0);
676
    stall_i : in std_logic);
677 45 magro732
end entity;
678
 
679
 
680
-------------------------------------------------------------------------------
681 47 magro732
-- Architecture for RioLogicalCommonInterconnect.
682 45 magro732
-------------------------------------------------------------------------------
683
architecture RioLogicalCommonInterconnectImpl of RioLogicalCommonInterconnect is
684 48 magro732
  signal activeCycle : std_logic := '0';
685
  signal selectedMaster : natural range 0 to WIDTH-1 := 0;
686 45 magro732
begin
687
 
688
  -----------------------------------------------------------------------------
689
  -- Arbitration.
690
  -----------------------------------------------------------------------------
691
  Arbiter: process(areset_n, clk)
692
  begin
693
    if (areset_n = '0') then
694
      activeCycle <= '0';
695
      selectedMaster <= 0;
696
    elsif (clk'event and clk = '1') then
697
      if (activeCycle = '0') then
698
        for i in 0 to WIDTH-1 loop
699
          if (stb_i(i) = '1') then
700
            activeCycle <= '1';
701
            selectedMaster <= i;
702
          end if;
703
        end loop;
704
      else
705
        if (stb_i(selectedMaster) = '0') then
706
          activeCycle <= '0';
707
        end if;
708
      end if;
709
    end if;
710
  end process;
711
 
712
  -----------------------------------------------------------------------------
713
  -- Interconnection.
714
  -----------------------------------------------------------------------------
715
  stb_o <= stb_i(selectedMaster) and activeCycle;
716 48 magro732
  adr_o <= adr_i(selectedMaster);
717
  data_o <= data_i(32*(selectedMaster+1)-1 downto 32*selectedMaster);
718 45 magro732
 
719
  Interconnect: for i in 0 to WIDTH-1 generate
720 48 magro732
    stall_o(i) <= stall_i when (selectedMaster = i) and (activeCycle = '1') else '1';
721 45 magro732
  end generate;
722
 
723
end architecture;
724
 
725
 

powered by: WebSVN 2.1.0

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