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

Subversion Repositories rio

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 46 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 parsers and generators.
10
-- 
11
-- To Do:
12 51 magro732
-- - Add support for all Request-class packets.
13
-- - Add support for all Write-class packets.
14
-- - Add support for Doorbell-class packets.
15
-- - Add support for Message-class packets.
16 46 magro732
-- 
17
-- Author(s): 
18
-- - Magnus Rosenius, magro732@opencores.org 
19
-- 
20
-------------------------------------------------------------------------------
21
-- 
22
-- Copyright (C) 2014 Authors and OPENCORES.ORG 
23
-- 
24
-- This source file may be used and distributed without 
25
-- restriction provided that this copyright statement is not 
26
-- removed from the file and that any derivative work contains 
27
-- the original copyright notice and the associated disclaimer. 
28
-- 
29
-- This source file is free software; you can redistribute it 
30
-- and/or modify it under the terms of the GNU Lesser General 
31
-- Public License as published by the Free Software Foundation; 
32
-- either version 2.1 of the License, or (at your option) any 
33
-- later version. 
34
-- 
35
-- This source is distributed in the hope that it will be 
36
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
37
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
38
-- PURPOSE. See the GNU Lesser General Public License for more 
39
-- details. 
40
-- 
41
-- You should have received a copy of the GNU Lesser General 
42
-- Public License along with this source; if not, download it 
43
-- from http://www.opencores.org/lgpl.shtml 
44
-- 
45
-------------------------------------------------------------------------------
46
 
47
 
48
-------------------------------------------------------------------------------
49
-- MaintenanceInbound
50
-------------------------------------------------------------------------------
51
library ieee;
52
use ieee.std_logic_1164.all;
53
use ieee.numeric_std.all;
54
use work.rio_common.all;
55
 
56
 
57
-------------------------------------------------------------------------------
58
-- Entity for MaintenanceInbound.
59
-------------------------------------------------------------------------------
60
entity MaintenanceInbound is
61 48 magro732
  generic(
62
    ENABLE_READ_REQUEST : boolean := true;
63
    ENABLE_WRITE_REQUEST : boolean := true;
64
    ENABLE_READ_RESPONSE : boolean := true;
65
    ENABLE_WRITE_RESPONSE : boolean := true;
66
    ENABLE_PORT_WRITE : boolean := true);
67 46 magro732
  port(
68
    clk : in std_logic;
69
    areset_n : in std_logic;
70
    enable : in std_logic;
71
 
72
    readRequestReady_o : out std_logic;
73
    writeRequestReady_o : out std_logic;
74
    readResponseReady_o : out std_logic;
75
    writeResponseReady_o : out std_logic;
76
    portWriteReady_o : out std_logic;
77
    vc_o : out std_logic;
78
    crf_o : out std_logic;
79
    prio_o : out std_logic_vector(1 downto 0);
80
    tt_o : out std_logic_vector(1 downto 0);
81
    dstid_o : out std_logic_vector(31 downto 0);
82
    srcid_o : out std_logic_vector(31 downto 0);
83 47 magro732
    size_o : out std_logic_vector(3 downto 0);
84
    status_o : out std_logic_vector(3 downto 0);
85 46 magro732
    tid_o : out std_logic_vector(7 downto 0);
86
    hop_o : out std_logic_vector(7 downto 0);
87
    offset_o : out std_logic_vector(20 downto 0);
88
    wdptr_o : out std_logic;
89 47 magro732
    payloadLength_o : out std_logic_vector(2 downto 0);
90
    payloadIndex_i : in std_logic_vector(2 downto 0);
91
    payload_o : out std_logic_vector(63 downto 0);
92 46 magro732
    done_i : in std_logic;
93
 
94
    inboundStb_i : in std_logic;
95 48 magro732
    inboundAdr_i : in std_logic_vector(3 downto 0);
96 46 magro732
    inboundDat_i : in std_logic_vector(31 downto 0);
97 48 magro732
    inboundStall_o : out std_logic);
98 46 magro732
end entity;
99
 
100
 
101
-------------------------------------------------------------------------------
102
-- Architecture for MaintenanceInbound.
103
-------------------------------------------------------------------------------
104
architecture MaintenanceInbound of MaintenanceInbound is
105
 
106 48 magro732
  signal busy : std_ulogic;
107
  signal transaction : std_logic_vector(3 downto 0);
108
  signal payloadIndex : unsigned(2 downto 0);
109
  signal packetIndex : natural range 0 to 21;
110
  signal packetData : std_logic_vector(47 downto 0);
111 46 magro732
 
112 47 magro732
  signal readRequestComplete : std_logic;
113
  signal writeRequestComplete : std_logic;
114
  signal readResponseComplete : std_logic;
115
  signal writeResponseComplete : std_logic;
116 48 magro732
  signal portWriteComplete : std_logic;
117 46 magro732
 
118
  signal memoryWrite : std_logic;
119 47 magro732
  signal memoryAddress : std_logic_vector(2 downto 0);
120
  signal memoryDataIn : std_logic_vector(63 downto 0);
121 46 magro732
 
122
begin
123
 
124 48 magro732
  readRequestReady_o <= readRequestComplete and busy;
125
  writeRequestReady_o <= writeRequestComplete and busy;
126
  readResponseReady_o <= readResponseComplete and busy;
127
  writeResponseReady_o <= writeResponseComplete and busy;
128
  portWriteReady_o <= portWriteComplete and busy;
129 46 magro732
 
130 48 magro732
  payloadLength_o <= std_logic_vector(payloadIndex);
131
 
132
  inboundStall_o <= busy when ((inboundStb_i = '1') and (inboundAdr_i = x"8")) else '0';
133
 
134 46 magro732
  MaintenanceRequest: process(clk, areset_n)
135
  begin
136
    if (areset_n = '0') then
137 47 magro732
      readRequestComplete <= '0';
138
      writeRequestComplete <= '0';
139
      readResponseComplete <= '0';
140
      writeResponseComplete <= '0';
141 48 magro732
      portWriteComplete <= '0';
142 46 magro732
 
143
      vc_o <= '0';
144
      crf_o <= '0';
145
      prio_o <= "00";
146
      tt_o <= "00";
147
      dstid_o <= (others=>'0');
148
      srcid_o <= (others=>'0');
149 47 magro732
      status_o <= (others=>'0');
150 46 magro732
      tid_o <= (others=>'0');
151
      hop_o <= (others=>'0');
152
      offset_o <= (others=>'0');
153
 
154 48 magro732
      wdptr_o <= '0';
155
      size_o <= (others=>'0');
156
 
157
      busy <= '0';
158
      transaction <= "0000";
159
      payloadIndex <= "000";
160 46 magro732
 
161
      packetIndex <= 0;
162
      memoryWrite <= '0';
163
      memoryAddress <= (others=>'0');
164
      memoryDataIn <= (others=>'0');
165
    elsif (clk'event and clk = '1') then
166 48 magro732
      if (enable = '1') then
167
        if (busy = '0') then
168 46 magro732
          ---------------------------------------------------------------------
169
          -- This state waits for a new maintenance packet, receives it
170
          -- and parses it.
171
          ---------------------------------------------------------------------
172 48 magro732
          if (inboundStb_i = '1') and (inboundAdr_i = x"8") then
173
            -- New inbound packet content.
174
 
175
            case (packetIndex) is
176
 
177
              when 0 =>
178
                -- x"0000" & ackid & vc & crf & prio & tt & ftype
179
                vc_o <= inboundDat_i(9);
180
                crf_o <= inboundDat_i(8);
181
                prio_o <= inboundDat_i(7 downto 6);
182
                tt_o <= inboundDat_i(5 downto 4);
183
                packetIndex <= packetIndex + 1;
184
 
185
              when 1 =>
186
                -- dstid
187
                dstid_o <= inboundDat_i;
188
                packetIndex <= packetIndex + 1;
189
 
190
              when 2 =>
191
                -- srcid
192
                srcid_o <= inboundDat_i;
193
                packetIndex <= packetIndex + 1;
194
 
195
              when 3 =>
196
                -- READ-REQUEST:   transaction & rdsize & srcTID & hop & config_offset(20:13)
197
                -- WRITE-REQUEST:  transaction & wrsize & srcTID & hop & config_offset(20:13)
198
                -- READ-RESPONSE:  transaction & status & srcTID & hop & reserved(7:0)
199
                -- WRITE-RESPONSE: transaction & status & srcTID & hop & reserved(7:0)
200
                -- PORT-WRITE:     transaction & status & reserved(7:0) & hop & reserved(7:0)
201
                transaction <= inboundDat_i(31 downto 28);
202
                size_o <= inboundDat_i(27 downto 24);
203
                status_o <= inboundDat_i(27 downto 24);
204
                tid_o <= inboundDat_i(23 downto 16);
205
                hop_o <= inboundDat_i(15 downto 8);
206
                offset_o(20 downto 13) <= inboundDat_i(7 downto 0);
207
 
208
                packetIndex <= packetIndex + 1;
209
 
210
              when 4 =>
211
                -- NO-PAYLOAD:   config_offset(12:0) & wdptr & rsrv(1:0) & crc(15:0)
212
                -- WITH-PAYLOAD: config_offset(12:0) & wdptr & rsrv(1:0) & double-word0(63:48)
213
                offset_o(12 downto 0) <= inboundDat_i(31 downto 19);
214
                wdptr_o <= inboundDat_i(18);
215
                packetData(47 downto 32) <= inboundDat_i(15 downto 0);
216
 
217
                if (ENABLE_READ_REQUEST and (transaction = TTYPE_MAINTENANCE_READ_REQUEST)) then
218
                  readRequestComplete <= '1';
219
                elsif (ENABLE_WRITE_RESPONSE and (transaction = TTYPE_MAINTENANCE_WRITE_RESPONSE)) then
220
                  writeResponseComplete <= '1';
221 46 magro732
                end if;
222 48 magro732
 
223
                packetIndex <= packetIndex + 1;
224
 
225
              when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 =>
226
                -- double-word(47:16)
227
                packetData(31 downto 0) <= inboundDat_i;
228
                memoryWrite <= '0';
229
                packetIndex <= packetIndex + 1;
230
 
231
              when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 =>
232
                -- double-word(15:0) & double-word(63:48)
233
                packetData(47 downto 32) <= inboundDat_i(15 downto 0);
234
                payloadIndex <= payloadIndex + 1;
235
 
236
                memoryWrite <= '1';
237
                memoryAddress <= std_logic_vector(payloadIndex);
238
                memoryDataIn <= packetData & inboundDat_i(31 downto 16);
239
 
240
                if (ENABLE_WRITE_REQUEST and (transaction = TTYPE_MAINTENANCE_WRITE_REQUEST)) then
241
                  writeRequestComplete <= '1';
242
                elsif (ENABLE_READ_RESPONSE and (transaction = TTYPE_MAINTENANCE_READ_RESPONSE)) then
243
                  readResponseComplete <= '1';
244
                elsif (ENABLE_PORT_WRITE and (transaction = TTYPE_MAINTENANCE_PORT_WRITE)) then
245
                  -- REMARK: Do this when 2 double words has been received?
246
                  portWriteComplete <= '1';
247
                end if;
248
 
249
                packetIndex <= packetIndex + 1;
250
 
251
              when others =>
252
                -- There should be no more content in a maintenance packet.
253
                -- Discard.
254
                report "MaintenanceClass: Received unexpected packet content." severity warning;
255
 
256
            end case;
257 46 magro732
          else
258 48 magro732
            -- No incoming packet content.
259
 
260
            -- Make sure there is no write access anymore.
261
            memoryWrite <= '0';
262
 
263
            -- Check if a packet has been completed.
264 47 magro732
            if ((readRequestComplete = '1') or (writeRequestComplete = '1') or
265 48 magro732
                (readResponseComplete = '1') or (writeResponseComplete = '1') or
266
                (portWriteComplete = '1')) then
267
              -- Packet completed.
268
              busy <= '1';
269 47 magro732
            else
270 48 magro732
              -- No packet completed.
271 47 magro732
              packetIndex <= 0;
272 48 magro732
              payloadIndex <= (others=>'0');
273 46 magro732
            end if;
274
          end if;
275 48 magro732
        else
276 46 magro732
          ---------------------------------------------------------------------
277 48 magro732
          -- Stall any incoming maintenance packet until the current has been
278
          -- processed and wait for the handler of the packet to signal that it
279
          -- has been processed.
280 46 magro732
          ---------------------------------------------------------------------
281
          if (done_i = '1') then
282 48 magro732
            busy <= '0';
283 47 magro732
            packetIndex <= 0;
284 48 magro732
            payloadIndex <= (others=>'0');
285 47 magro732
 
286
            readRequestComplete <= '0';
287
            writeRequestComplete <= '0';
288
            readResponseComplete <= '0';
289
            writeResponseComplete <= '0';
290 48 magro732
            portWriteComplete <= '0';
291 46 magro732
          end if;
292 48 magro732
        end if;
293
      end if;
294
    end if;
295
  end process;
296
 
297
  -----------------------------------------------------------------------------
298
  -- Payload content memory.
299
  -----------------------------------------------------------------------------
300
  PayloadMemory: MemorySimpleDualPort
301
    generic map(ADDRESS_WIDTH=>3, DATA_WIDTH=>64)
302
    port map(clkA_i=>clk,
303
             enableA_i=>memoryWrite,
304
             addressA_i=>memoryAddress,
305
             dataA_i=>memoryDataIn,
306
             clkB_i=>clk,
307
             enableB_i=>enable,
308
             addressB_i=>payloadIndex_i,
309
             dataB_o=>payload_o);
310
 
311
end architecture;
312
 
313
 
314
 
315
-------------------------------------------------------------------------------
316
-- RequestClassInbound.
317
-------------------------------------------------------------------------------
318
-- REMARK: Extended addresses are not supported yet...
319
library ieee;
320
use ieee.std_logic_1164.all;
321
use ieee.numeric_std.all;
322
use work.rio_common.all;
323
 
324
 
325
-------------------------------------------------------------------------------
326
-- 
327
-------------------------------------------------------------------------------
328
entity RequestClassInbound is
329
  generic(
330
    EXTENDED_ADDRESS : natural range 0 to 2 := 0);
331
  port(
332
    clk : in std_logic;
333
    areset_n : in std_logic;
334
    enable : in std_logic;
335
 
336
    nreadReady_o : out std_logic;
337
 
338
    vc_o : out std_logic;
339
    crf_o : out std_logic;
340
    prio_o : out std_logic_vector(1 downto 0);
341
    tt_o : out std_logic_vector(1 downto 0);
342
    dstId_o : out std_logic_vector(31 downto 0);
343
    srcId_o : out std_logic_vector(31 downto 0);
344
    tid_o : out std_logic_vector(7 downto 0);
345
    address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
346
    length_o : out std_logic_vector(4 downto 0);
347
    select_o : out std_logic_vector(7 downto 0);
348
    done_i : in std_logic;
349
 
350
    inboundStb_i : in std_logic;
351
    inboundAdr_i : in std_logic_vector(3 downto 0);
352
    inboundDat_i : in std_logic_vector(31 downto 0);
353
    inboundStall_o : out std_logic);
354
end entity;
355
 
356
 
357
-------------------------------------------------------------------------------
358
-- 
359
-------------------------------------------------------------------------------
360
architecture RequestClassInbound of RequestClassInbound is
361
  signal busy : std_logic;
362
  signal transaction : std_logic_vector(3 downto 0);
363
  signal complete : std_logic;
364
  signal packetIndex : natural range 0 to 69;
365
 
366
  signal rdsize : std_logic_vector(3 downto 0);
367
  signal wdptr : std_logic;
368
 
369
begin
370
 
371
  nreadReady_o <= complete and busy;
372
 
373
  inboundStall_o <= busy when ((inboundStb_i = '1') and (inboundAdr_i = x"2")) else '0';
374
 
375
  RequestClass: process(clk, areset_n)
376
  begin
377
    if (areset_n = '0') then
378
      complete <= '0';
379
      transaction <= "0000";
380
 
381
      vc_o <= '0';
382
      crf_o <= '0';
383
      prio_o <= "00";
384
      tt_o <= "00";
385
      dstId_o <= (others=>'0');
386
      srcId_o <= (others=>'0');
387
      tid_o <= (others=>'0');
388
      address_o <= (others=>'0');
389
 
390
      rdsize <= (others=>'0');
391
      wdptr <= '0';
392
 
393
      busy <= '0';
394
      packetIndex <= 0;
395
    elsif (clk'event and clk = '1') then
396
      if (enable = '1') then
397
        if (busy = '0') then
398 46 magro732
          ---------------------------------------------------------------------
399 48 magro732
          -- This state waits for a new REQUEST class packet, receives it
400
          -- and parses it.
401 46 magro732
          ---------------------------------------------------------------------
402 48 magro732
          if ((inboundStb_i = '1') and (inboundAdr_i = x"2")) then
403
            -- New inbound packet content.
404
 
405
            case (packetIndex) is
406
 
407
              when 0 =>
408
                -- x"0000" & ackid & vc & crf & prio & tt & ftype
409
                vc_o <= inboundDat_i(9);
410
                crf_o <= inboundDat_i(8);
411
                prio_o <= inboundDat_i(7 downto 6);
412
                tt_o <= inboundDat_i(5 downto 4);
413
                packetIndex <= packetIndex + 1;
414
 
415
              when 1 =>
416
                -- dstid
417
                dstId_o <= inboundDat_i;
418
                packetIndex <= packetIndex + 1;
419
 
420
              when 2 =>
421
                -- srcid
422
                srcId_o <= inboundDat_i;
423
                packetIndex <= packetIndex + 1;
424
 
425
              when 3 =>
426
                -- transaction(3:0) & rdsize(3:0) & srcTID(7:0) & address(28:13)
427
                transaction <= inboundDat_i(31 downto 28);
428
                rdsize <= inboundDat_i(27 downto 24);
429
                tid_o <= inboundDat_i(23 downto 16);
430
                address_o(28 downto 13) <= inboundDat_i(15 downto 0);
431
                packetIndex <= packetIndex + 1;
432
 
433
              when 4 =>
434
                -- address(12:0) & wdptr & xamsbs(1:0) & crc(15:0)
435
                address_o(12 downto 0) <= inboundDat_i(31 downto 19);
436
                wdptr <= inboundDat_i(18);
437
                address_o(30 downto 29) <= inboundDat_i(17 downto 16);
438
                packetIndex <= packetIndex + 1;
439
 
440
                if (transaction = TTYPE_NREAD_TRANSACTION) then
441
                  -- An NREAD packet has been completed.
442
                  complete <= '1';
443
                end if;
444
 
445
              when others =>
446
                -- There should be no more content in a REQUEST.
447
                -- Discard.
448
                report "RequestClass: Received unexpected packet content." severity warning;
449
 
450
            end case;
451
          else
452
            -- No incoming packet content.
453
            busy <= complete;
454
          end if;
455
        else
456
          ---------------------------------------------------------------------
457
          -- Stall any incoming REQUEST packet until the current has been
458
          -- processed and wait for the handler of the packet to signal that it
459
          -- has been processed.
460
          ---------------------------------------------------------------------
461
          if (done_i = '1') then
462
            busy <= '0';
463
            packetIndex <= 0;
464
            complete <= '0';
465
          end if;
466
        end if;
467
      end if;
468
    end if;
469
  end process;
470 46 magro732
 
471 48 magro732
  -----------------------------------------------------------------------------
472
  -- Transformation of rdsize and wdptr into length of access and byte lanes.
473
  -----------------------------------------------------------------------------
474
 
475
  process(clk, areset_n)
476
  begin
477
    if (areset_n = '0') then
478
      length_o <= "00000";
479
      select_o <= (others=>'0');
480
    elsif (clk'event and clk = '1') then
481
      if (complete = '1') then
482
        if (wdptr = '0') then
483
          case rdsize is
484
            when "0000" =>
485
              length_o <= "00001";
486
              select_o <= "10000000";
487
            when "0001" =>
488
              length_o <= "00001";
489
              select_o <= "01000000";
490
            when "0010" =>
491
              length_o <= "00001";
492
              select_o <= "00100000";
493
            when "0011" =>
494
              length_o <= "00001";
495
              select_o <= "00010000";
496
            when "0100" =>
497
              length_o <= "00001";
498
              select_o <= "11000000";
499
            when "0101" =>
500
              length_o <= "00001";
501
              select_o <= "11100000";
502
            when "0110" =>
503
              length_o <= "00001";
504
              select_o <= "00110000";
505
            when "0111" =>
506
              length_o <= "00001";
507
              select_o <= "11111000";
508
            when "1000" =>
509
              length_o <= "00001";
510
              select_o <= "11110000";
511
            when "1001" =>
512
              length_o <= "00001";
513
              select_o <= "11111100";
514
            when "1010" =>
515
              length_o <= "00001";
516
              select_o <= "11111110";
517
            when "1011" =>
518
              length_o <= "00001";
519
              select_o <= "11111111";
520
            when "1100" =>
521
              length_o <= "00100";
522
              select_o <= "11111111";
523
            when "1101" =>
524
              length_o <= "01100";
525
              select_o <= "11111111";
526
            when "1110" =>
527
              length_o <= "10100";
528
              select_o <= "11111111";
529
            when others =>
530
              length_o <= "11100";
531
              select_o <= "11111111";
532
          end case;
533
        else
534
          case rdsize is
535
            when "0000" =>
536
              length_o <= "00001";
537
              select_o <= "00001000";
538
            when "0001" =>
539
              length_o <= "00001";
540
              select_o <= "00000100";
541
            when "0010" =>
542
              length_o <= "00001";
543
              select_o <= "00000010";
544
            when "0011" =>
545
              length_o <= "00001";
546
              select_o <= "00000001";
547
            when "0100" =>
548
              length_o <= "00001";
549
              select_o <= "00001100";
550
            when "0101" =>
551
              length_o <= "00001";
552
              select_o <= "00000111";
553
            when "0110" =>
554
              length_o <= "00001";
555
              select_o <= "00000011";
556
            when "0111" =>
557
              length_o <= "00001";
558
              select_o <= "00011111";
559
            when "1000" =>
560
              length_o <= "00001";
561
              select_o <= "00001111";
562
            when "1001" =>
563
              length_o <= "00001";
564
              select_o <= "00111111";
565
            when "1010" =>
566
              length_o <= "00001";
567
              select_o <= "01111111";
568
            when "1011" =>
569
              length_o <= "00010";
570
              select_o <= "11111111";
571
            when "1100" =>
572
              length_o <= "01000";
573
              select_o <= "11111111";
574
            when "1101" =>
575
              length_o <= "10000";
576
              select_o <= "11111111";
577
            when "1110" =>
578
              length_o <= "11000";
579
              select_o <= "11111111";
580
            when others =>
581
              length_o <= "00000";
582
              select_o <= "11111111";
583
          end case;
584
        end if;
585
      end if;
586 46 magro732
    end if;
587
  end process;
588
 
589 48 magro732
end architecture;
590
 
591
 
592
 
593
-------------------------------------------------------------------------------
594
-- 
595
-------------------------------------------------------------------------------
596
library ieee;
597
use ieee.std_logic_1164.all;
598
use ieee.numeric_std.all;
599
use work.rio_common.all;
600
 
601
 
602
-------------------------------------------------------------------------------
603
-- 
604
-------------------------------------------------------------------------------
605
-- REMARK: Add support for extended addresses...
606
-- length_o is the actual size of the access. A 32 double-word access has length=0.
607
entity WriteClassInbound is
608
  generic(
609
    ENABLE_NWRITE : boolean := true;
610
    ENABLE_NWRITER : boolean := true;
611
    EXTENDED_ADDRESS : natural range 0 to 2 := 0);
612
  port(
613
    clk : in std_logic;
614
    areset_n : in std_logic;
615
    enable : in std_logic;
616
 
617
    nwriteReady_o : out std_logic;
618
    nwriterReady_o : out std_logic;
619
 
620
    vc_o : out std_logic;
621
    crf_o : out std_logic;
622
    prio_o : out std_logic_vector(1 downto 0);
623
    tt_o : out std_logic_vector(1 downto 0);
624
    dstId_o : out std_logic_vector(31 downto 0);
625
    srcId_o : out std_logic_vector(31 downto 0);
626
    tid_o : out std_logic_vector(7 downto 0);
627
    address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
628
    length_o : out std_logic_vector(4 downto 0);
629
    select_o : out std_logic_vector(7 downto 0);
630
    payloadIndex_i : in std_logic_vector(4 downto 0);
631
    payload_o : out std_logic_vector(63 downto 0);
632
    done_i : in std_logic;
633
 
634
    inboundStb_i : in std_logic;
635
    inboundAdr_i : in std_logic_vector(3 downto 0);
636
    inboundDat_i : in std_logic_vector(31 downto 0);
637
    inboundStall_o : out std_logic);
638
end entity;
639
 
640
 
641
-------------------------------------------------------------------------------
642
-- 
643
-------------------------------------------------------------------------------
644
architecture WriteClassInbound of WriteClassInbound is
645
 
646
  signal busy : std_logic;
647
  signal transaction : std_logic_vector(3 downto 0);
648
  signal payloadIndex : unsigned(4 downto 0);
649
  signal packetIndex : natural range 0 to 69;
650
  signal doubleWord : std_logic_vector(63 downto 16);
651
 
652
  signal nwriteComplete : std_logic;
653
  signal nwriterComplete : std_logic;
654
 
655
  signal wdptr : std_logic;
656
  signal wrsize : std_logic_vector(3 downto 0);
657
 
658
  signal memoryWrite : std_logic;
659
  signal memoryAddress : std_logic_vector(4 downto 0);
660
  signal memoryDataIn : std_logic_vector(63 downto 0);
661
 
662
begin
663
 
664
  nwriteReady_o <= nwriteComplete and busy;
665
  nwriterReady_o <= nwriterComplete and busy;
666
 
667
  inboundStall_o <= busy when ((inboundStb_i = '1') and (inboundAdr_i = x"5")) else '0';
668
 
669
  WriteClass: process(clk, areset_n)
670
  begin
671
    if (areset_n = '0') then
672
      nwriteComplete <= '0';
673
      nwriterComplete <= '0';
674
 
675
      vc_o <= '0';
676
      crf_o <= '0';
677
      prio_o <= "00";
678
      tt_o <= "00";
679
      dstId_o <= (others=>'0');
680
      srcId_o <= (others=>'0');
681
      tid_o <= (others=>'0');
682
      address_o <= (others=>'0');
683
 
684
      busy <= '0';
685
      transaction <= "0000";
686
      payloadIndex <= (others=>'0');
687
      packetIndex <= 0;
688
      doubleWord <= (others=>'0');
689
 
690
      wdptr <= '0';
691
      wrsize <= (others=>'0');
692
 
693
      memoryWrite <= '0';
694
      memoryAddress <= (others=>'0');
695
      memoryDataIn <= (others=>'0');
696
    elsif (clk'event and clk = '1') then
697
      if (enable = '1') then
698
        if (busy = '0') then
699
          ---------------------------------------------------------------------
700
          -- This state waits for a new maintenance packet, receives it
701
          -- and parses it.
702
          ---------------------------------------------------------------------
703
          if ((inboundStb_i = '1') and (inboundAdr_i = x"5")) then
704
            -- New inbound packet content.
705
 
706
            case (packetIndex) is
707
 
708
              when 0 =>
709
                -- x"0000" & ackid & vc & crf & prio & tt & ftype
710
                vc_o <= inboundDat_i(9);
711
                crf_o <= inboundDat_i(8);
712
                prio_o <= inboundDat_i(7 downto 6);
713
                tt_o <= inboundDat_i(5 downto 4);
714
                packetIndex <= packetIndex + 1;
715
 
716
              when 1 =>
717
                -- destId
718
                dstId_o <= inboundDat_i;
719
                packetIndex <= packetIndex + 1;
720
 
721
              when 2 =>
722
                -- srcId
723
                srcId_o <= inboundDat_i;
724
                packetIndex <= packetIndex + 1;
725
 
726
              when 3 =>
727
                -- transaction & wrsize & srcTID & address(28:13)
728
                transaction <= inboundDat_i(31 downto 28);
729
                wrsize <= inboundDat_i(27 downto 24);
730
                tid_o <= inboundDat_i(23 downto 16);
731
                address_o(28 downto 13) <= inboundDat_i(15 downto 0);
732
                packetIndex <= packetIndex + 1;
733
 
734
              when 4 =>
735
                -- address(12:0) & wdptr & xamsbs(1:0) & double-word(63:48)
736
                address_o(12 downto 0) <= inboundDat_i(31 downto 19);
737
                wdptr <= inboundDat_i(18);
738
                address_o(30 downto 29) <= inboundDat_i(17 downto 16);
739
                doubleWord(63 downto 48) <= inboundDat_i(15 downto 0);
740
                packetIndex <= packetIndex + 1;
741
 
742
              when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31  | 33 | 35 |
743
                37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 59 | 61 | 63 | 65 | 67 =>
744
                -- double-word(47:16)
745
                doubleWord(47 downto 16) <= inboundDat_i;
746
                memoryWrite <= '0';
747
                packetIndex <= packetIndex + 1;
748
 
749
              when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32  | 34 |
750
                36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 | 68 =>
751
                -- double-word(15:0) & double-word(63:48)
752
                doubleWord(63 downto 48) <= inboundDat_i(15 downto 0);
753
                payloadIndex <= payloadIndex + 1;
754
 
755
                memoryWrite <= '1';
756
                memoryAddress <= std_logic_vector(payloadIndex);
757
                memoryDataIn <= doubleWord(63 downto 16) & inboundDat_i(31 downto 16);
758
 
759
                if (ENABLE_NWRITE and (transaction = TTYPE_NWRITE_TRANSACTION)) then
760
                  nwriteComplete <= '1';
761
                elsif (ENABLE_NWRITER and (transaction = TTYPE_NWRITER_TRANSACTION)) then
762
                  nwriterComplete <= '1';
763
                end if;
764
 
765
                packetIndex <= packetIndex + 1;
766
 
767
              when others =>
768
                -- There should be no more content in an NWRITE/NWRITER request.
769
                -- Discard.
770
                report "WriteClass: Received unexpected packet content." severity warning;
771
 
772
            end case;
773
          else
774
            -- No incoming packet content.
775
 
776
            -- Make sure there is no write access anymore.
777
            memoryWrite <= '0';
778
 
779
            -- Check if a packet has been completed.
780
            if (nwriteComplete = '1') or (nwriteRComplete = '1') then
781
              -- Packet completed.
782
              busy <= '1';
783
            else
784
              -- No packet completed.
785
              packetIndex <= 0;
786
              payloadIndex <= (others=>'0');
787
            end if;
788
          end if;
789
        else
790
          ---------------------------------------------------------------------
791
          -- Stall any incoming write packet until the current has been
792
          -- processed and wait for the handler of the packet to signal that it
793
          -- has been processed.
794
          ---------------------------------------------------------------------
795
          if (done_i = '1') then
796
            busy <= '0';
797
            packetIndex <= 0;
798
            payloadIndex <= (others=>'0');
799
 
800
            nwriteComplete <= '0';
801
            nwriterComplete <= '0';
802
          end if;
803
        end if;
804
      end if;
805
    end if;
806
  end process;
807
 
808 46 magro732
  -----------------------------------------------------------------------------
809 48 magro732
  -- Transformation of wrsize and wdptr into length of access and byte lanes.
810 46 magro732
  -----------------------------------------------------------------------------
811
 
812
  process(clk, areset_n)
813
  begin
814
    if (areset_n = '0') then
815 48 magro732
      length_o <= "00000";
816
      select_o <= (others=>'0');
817 46 magro732
    elsif (clk'event and clk = '1') then
818 48 magro732
      if ((nwriteComplete = '1') or (nwriterComplete = '1')) then
819
        if (wdptr = '0') then
820
          case wrsize is
821
            when "0000" =>
822
              length_o <= "00001";
823
              select_o <= "10000000";
824
            when "0001" =>
825
              length_o <= "00001";
826
              select_o <= "01000000";
827
            when "0010" =>
828
              length_o <= "00001";
829
              select_o <= "00100000";
830
            when "0011" =>
831
              length_o <= "00001";
832
              select_o <= "00010000";
833
            when "0100" =>
834
              length_o <= "00001";
835
              select_o <= "11000000";
836
            when "0101" =>
837
              length_o <= "00001";
838
              select_o <= "11100000";
839
            when "0110" =>
840
              length_o <= "00001";
841
              select_o <= "00110000";
842
            when "0111" =>
843
              length_o <= "00001";
844
              select_o <= "11111000";
845
            when "1000" =>
846
              length_o <= "00001";
847
              select_o <= "11110000";
848
            when "1001" =>
849
              length_o <= "00001";
850
              select_o <= "11111100";
851
            when "1010" =>
852
              length_o <= "00001";
853
              select_o <= "11111110";
854
            when "1011" =>
855
              length_o <= "00001";
856
              select_o <= "11111111";
857
            when others =>
858
              length_o <= std_logic_vector(payloadIndex);
859
              select_o <= "11111111";
860
          end case;
861
        else
862
          case wrsize is
863
            when "0000" =>
864
              length_o <= "00001";
865
              select_o <= "00001000";
866
            when "0001" =>
867
              length_o <= "00001";
868
              select_o <= "00000100";
869
            when "0010" =>
870
              length_o <= "00001";
871
              select_o <= "00000010";
872
            when "0011" =>
873
              length_o <= "00001";
874
              select_o <= "00000001";
875
            when "0100" =>
876
              length_o <= "00001";
877
              select_o <= "00001100";
878
            when "0101" =>
879
              length_o <= "00001";
880
              select_o <= "00000111";
881
            when "0110" =>
882
              length_o <= "00001";
883
              select_o <= "00000011";
884
            when "0111" =>
885
              length_o <= "00001";
886
              select_o <= "00011111";
887
            when "1000" =>
888
              length_o <= "00001";
889
              select_o <= "00001111";
890
            when "1001" =>
891
              length_o <= "00001";
892
              select_o <= "00111111";
893
            when "1010" =>
894
              length_o <= "00001";
895
              select_o <= "01111111";
896
            when others =>
897
              length_o <= std_logic_vector(payloadIndex);
898
              select_o <= "11111111";
899
          end case;
900
        end if;
901 46 magro732
      end if;
902
    end if;
903
  end process;
904
 
905
  -----------------------------------------------------------------------------
906
  -- Payload content memory.
907
  -----------------------------------------------------------------------------
908 48 magro732
 
909 46 magro732
  PayloadMemory: MemorySimpleDualPort
910 48 magro732
    generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>64)
911 46 magro732
    port map(clkA_i=>clk,
912
             enableA_i=>memoryWrite,
913
             addressA_i=>memoryAddress,
914
             dataA_i=>memoryDataIn,
915
             clkB_i=>clk,
916 48 magro732
             enableB_i=>'1',
917 46 magro732
             addressB_i=>payloadIndex_i,
918
             dataB_o=>payload_o);
919
 
920
end architecture;
921
 
922
 
923 48 magro732
 
924 46 magro732
-------------------------------------------------------------------------------
925
-- MaintenanceOutbound.
926
-------------------------------------------------------------------------------
927
library ieee;
928
use ieee.std_logic_1164.all;
929
use ieee.numeric_std.all;
930
use work.rio_common.all;
931
 
932
-------------------------------------------------------------------------------
933
-- Entity for MaintenanceOutbound.
934
-------------------------------------------------------------------------------
935
entity MaintenanceOutbound is
936
  port(
937
    clk : in std_logic;
938
    areset_n : in std_logic;
939
    enable : in std_logic;
940
 
941
    readRequestReady_i : in std_logic;
942
    writeRequestReady_i : in std_logic;
943
    readResponseReady_i : in std_logic;
944
    writeResponseReady_i : in std_logic;
945
    portWriteReady_i : in std_logic;
946 48 magro732
 
947 46 magro732
    vc_i : in std_logic;
948
    crf_i : in std_logic;
949
    prio_i : in std_logic_vector(1 downto 0);
950
    tt_i : in std_logic_vector(1 downto 0);
951
    dstid_i : in std_logic_vector(31 downto 0);
952
    srcid_i : in std_logic_vector(31 downto 0);
953 47 magro732
    size_i : in std_logic_vector(3 downto 0);
954 46 magro732
    status_i : in std_logic_vector(3 downto 0);
955
    tid_i : in std_logic_vector(7 downto 0);
956
    hop_i : in std_logic_vector(7 downto 0);
957 47 magro732
    offset_i : in std_logic_vector(20 downto 0);
958 46 magro732
    wdptr_i : in std_logic;
959 47 magro732
    payloadLength_i : in std_logic_vector(2 downto 0);
960
    payloadIndex_o : out std_logic_vector(2 downto 0);
961
    payload_i : in std_logic_vector(63 downto 0);
962 46 magro732
    done_o : out std_logic;
963
 
964
    outboundStb_o : out std_logic;
965 48 magro732
    outboundAdr_o : out std_logic;
966 46 magro732
    outboundDat_o : out std_logic_vector(31 downto 0);
967 48 magro732
    outboundStall_i : in std_logic);
968 46 magro732
end entity;
969
 
970
 
971
-------------------------------------------------------------------------------
972
-- Architecture for MaintenanceOutbound.
973
-------------------------------------------------------------------------------
974 48 magro732
-- REMARK: use the same variable for status and size internally...
975 46 magro732
architecture MaintenanceOutbound of MaintenanceOutbound is
976 48 magro732
  type StateType is (WAIT_PACKET, SEND_PACKET, WAIT_COMPLETE);
977 46 magro732
  signal state : StateType;
978 47 magro732
  signal packetIndex : natural range 0 to 21;
979
 
980
  signal payloadIndex : std_logic_vector(2 downto 0);
981 48 magro732
  signal payload : std_logic_vector(47 downto 0);
982 46 magro732
 
983
begin
984
 
985 48 magro732
  payloadIndex_o <= payloadIndex;
986 46 magro732
 
987 48 magro732
  outboundAdr_o <= '1';
988 46 magro732
 
989
  MaintenanceResponse: process(clk, areset_n)
990
  begin
991
    if (areset_n = '0') then
992
      state <= WAIT_PACKET;
993
      packetIndex <= 0;
994
 
995
      payload <= (others=>'0');
996
      payloadIndex <= (others=>'0');
997
 
998
      outboundStb_o <= '0';
999 48 magro732
      outboundDat_o <= (others=>'0');
1000 46 magro732
      done_o <= '0';
1001
    elsif (clk'event and clk = '1') then
1002
      if (enable = '1') then
1003
        case state is
1004
          when WAIT_PACKET =>
1005
            -------------------------------------------------------------------
1006
            -- 
1007
            -------------------------------------------------------------------
1008 48 magro732
            outboundStb_o <= '0';
1009 47 magro732
            payloadIndex <= (others=>'0');
1010 48 magro732
            if ((readRequestReady_i = '1') or (writeRequestReady_i = '1') or
1011
                (readResponseReady_i = '1') or (writeResponseReady_i = '1') or
1012
                (portWriteReady_i = '1')) then
1013
              state <= SEND_PACKET;
1014 46 magro732
            end if;
1015
 
1016 48 magro732
            -- unused(31:16) | ackId(15:10) | vc(9) | crf(8) | prio(7:6) | tt(5:4) | ftype(3:0).
1017
            outboundDat_o <= x"0000" & "000000" & vc_i & crf_i & prio_i & tt_i & x"8";
1018
            packetIndex <= 1;
1019
 
1020
          when SEND_PACKET =>
1021
            -------------------------------------------------------------------
1022 47 magro732
            -- 
1023 48 magro732
            -------------------------------------------------------------------
1024
            outboundStb_o <= '1';
1025
            if (outboundStall_i = '0') then
1026 47 magro732
              case (packetIndex) is
1027
 
1028
                when 1 =>
1029
                  -- dstid
1030
                  outboundDat_o <= dstid_i;
1031
                  packetIndex <= packetIndex + 1;
1032 48 magro732
 
1033 47 magro732
                when 2 =>
1034
                  -- srcid 
1035
                  outboundDat_o <= srcid_i;
1036
                  packetIndex <= packetIndex + 1;
1037 48 magro732
 
1038 47 magro732
                when 3 =>
1039
                  -- transaction & size & srcTID & hop & config_offset(20:13)
1040 48 magro732
                  -- transaction & status & targetTID & hop & reserved(20:13)
1041
                  -- transaction & status & reserved(7:0) & hop & reserved(20:13)
1042
                  if (readRequestReady_i = '1') then
1043
                    outboundDat_o <= TTYPE_MAINTENANCE_READ_REQUEST & size_i & tid_i & hop_i & offset_i(20 downto 13);
1044
                  elsif (writeRequestReady_i = '1') then
1045
                    outboundDat_o <= TTYPE_MAINTENANCE_WRITE_REQUEST & size_i & tid_i & hop_i & offset_i(20 downto 13);
1046
                  elsif (readResponseReady_i = '1') then
1047
                    outboundDat_o <= TTYPE_MAINTENANCE_READ_RESPONSE & status_i & tid_i & hop_i & x"00";
1048
                  elsif (writeResponseReady_i = '1') then
1049
                    outboundDat_o <= TTYPE_MAINTENANCE_WRITE_RESPONSE & status_i & tid_i & hop_i & x"00";
1050
                  elsif (portWriteReady_i = '1') then
1051
                    outboundDat_o <= TTYPE_MAINTENANCE_PORT_WRITE & status_i & x"00" & hop_i & x"00";
1052
                  end if;
1053
 
1054 47 magro732
                  packetIndex <= packetIndex + 1;
1055 48 magro732
 
1056 47 magro732
                when 4 =>
1057 48 magro732
                  -- READ-REQUEST:   config_offset(12:0) & wdptr & rsrv & crc(15:0)
1058
                  -- WRITE-REQUEST:  config_offset(12:0) & wdptr & rsrv & double-wordN(63:48)
1059
                  -- READ-RESPONSE:  reserved(15:0) & double-wordN(63:48)
1060
                  -- WRITE-RESPONSE: reserved(15:0) & crc(15:0)
1061
                  -- PORT-WRITE:     reserved(15:0) & crc(15:0)
1062
                  if (readRequestReady_i = '1') then
1063
                    outboundDat_o <= offset_i(12 downto 0) & wdptr_i & "00" & payload_i(63 downto 48);
1064
                    state <= WAIT_COMPLETE;
1065
                  elsif (writeRequestReady_i = '1') then
1066
                    outboundDat_o <= offset_i(12 downto 0) & wdptr_i & "00" & payload_i(63 downto 48);
1067
                  elsif (readResponseReady_i = '1') then
1068
                    outboundDat_o <= x"0000" & payload_i(63 downto 48);
1069
                  elsif (writeResponseReady_i = '1') then
1070
                    outboundDat_o <= x"0000" & payload_i(63 downto 48);
1071
                    state <= WAIT_COMPLETE;
1072
                  elsif (portWriteReady_i = '1') then
1073
                    outboundDat_o <= x"0000" & payload_i(63 downto 48);
1074
                  end if;
1075
 
1076
                  payload <= payload_i(47 downto 0);
1077
                  payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
1078
 
1079 47 magro732
                  packetIndex <= packetIndex + 1;
1080 48 magro732
 
1081 47 magro732
                when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 =>
1082
                  -- double-wordN(47:16)
1083 48 magro732
                  outboundDat_o <= payload(47 downto 16);
1084 47 magro732
                  packetIndex <= packetIndex + 1;
1085 48 magro732
 
1086 47 magro732
                when 6 | 8 | 10 | 12 | 14 | 16 | 18 =>
1087
                  -- double-wordN(15:0) & double-wordN(63:48)
1088 48 magro732
                  outboundDat_o <= payload(15 downto 0) & payload_i(63 downto 48);
1089
 
1090
                  payload <= payload_i(47 downto 0);
1091
                  payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
1092 47 magro732
                  if (payloadIndex = payloadLength_i) then
1093
                    state <= WAIT_COMPLETE;
1094
                  end if;
1095 48 magro732
 
1096
                  packetIndex <= packetIndex + 1;
1097
 
1098 47 magro732
                when others =>
1099
                  -- double-wordN(15:0) & double-wordN(63:48)
1100 48 magro732
                  outboundDat_o <= payload(15 downto 0) & x"0000";
1101 47 magro732
                  state <= WAIT_COMPLETE;
1102 48 magro732
 
1103 47 magro732
              end case;
1104
            end if;
1105 48 magro732
 
1106
          when WAIT_COMPLETE =>
1107
            -------------------------------------------------------------------
1108
            -- 
1109
            -------------------------------------------------------------------
1110
            outboundStb_o <= '0';
1111
            if ((readRequestReady_i = '0') and (writeRequestReady_i = '0') and
1112
                (readResponseReady_i = '0') and (writeResponseReady_i = '0') and
1113
                (portWriteReady_i = '0')) then
1114
              state <= WAIT_PACKET;
1115
              done_o <= '0';
1116
            else
1117
              done_o <= '1';
1118
            end if;
1119 47 magro732
 
1120 48 magro732
          when others =>
1121 46 magro732
            ---------------------------------------------------------------------
1122
            -- 
1123
            ---------------------------------------------------------------------
1124 48 magro732
            state <= WAIT_PACKET;
1125
 
1126
        end case;
1127
      end if;
1128
    end if;
1129
  end process;
1130
 
1131
end architecture;
1132
 
1133
 
1134
 
1135
-------------------------------------------------------------------------------
1136
-- ResponseClassOutbound
1137
-------------------------------------------------------------------------------
1138
library ieee;
1139
use ieee.std_logic_1164.all;
1140
use ieee.numeric_std.all;
1141
use work.rio_common.all;
1142
 
1143
-------------------------------------------------------------------------------
1144
-- 
1145
-------------------------------------------------------------------------------
1146
entity ResponseClassOutbound is
1147
  port(
1148
    clk : in std_logic;
1149
    areset_n : in std_logic;
1150
    enable : in std_logic;
1151
 
1152
    doneNoPayloadReady_i : in std_logic;
1153
    doneWithPayloadReady_i :  in std_logic;
1154
    errorReady_i : in std_logic;
1155
 
1156
    vc_i : in std_logic;
1157
    crf_i : in std_logic;
1158
    prio_i : in std_logic_vector(1 downto 0);
1159
    tt_i : in std_logic_vector(1 downto 0);
1160
    dstid_i : in std_logic_vector(31 downto 0);
1161
    srcid_i : in std_logic_vector(31 downto 0);
1162
    tid_i : in std_logic_vector(7 downto 0);
1163
    payloadLength_i : in std_logic_vector(4 downto 0);
1164
    payloadIndex_o : out std_logic_vector(4 downto 0);
1165
    payload_i : in std_logic_vector(63 downto 0);
1166
    done_o : out std_logic;
1167
 
1168
    outboundStb_o : out std_logic;
1169
    outboundAdr_o : out std_logic;
1170
    outboundDat_o : out std_logic_vector(31 downto 0);
1171
    outboundStall_i : in std_logic);
1172
end entity;
1173
 
1174
 
1175
-------------------------------------------------------------------------------
1176
-- 
1177
-------------------------------------------------------------------------------
1178
architecture ResponseClassOutbound of ResponseClassOutbound is
1179
  type StateType is (WAIT_PACKET, SEND_PACKET, WAIT_COMPLETE);
1180
  signal state : StateType;
1181
  signal packetIndex : natural range 0 to 68;
1182
 
1183
  signal payloadIndex : std_logic_vector(4 downto 0);
1184
  signal payload : std_logic_vector(47 downto 0);
1185
 
1186
begin
1187
 
1188
  payloadIndex_o <= payloadIndex;
1189
 
1190
  outboundAdr_o <= '1';
1191
 
1192
  Response: process(clk, areset_n)
1193
  begin
1194
    if (areset_n = '0') then
1195
      state <= WAIT_PACKET;
1196
      packetIndex <= 0;
1197
 
1198
      payloadIndex <= (others=>'0');
1199
      payload <= (others=>'0');
1200
 
1201
      outboundStb_o <= '0';
1202
      outboundDat_o <= (others=>'0');
1203
 
1204
      done_o <= '0';
1205
    elsif (clk'event and clk = '1') then
1206
      if (enable = '1') then
1207
        case state is
1208
          when WAIT_PACKET =>
1209
            -------------------------------------------------------------------
1210
            -- 
1211
            -------------------------------------------------------------------
1212
            outboundStb_o <= '0';
1213
            payloadIndex <= (others=>'0');
1214
            if ((doneNoPayloadReady_i = '1') or
1215
                (doneWithPayloadReady_i = '1') or
1216
                (errorReady_i = '1')) then
1217
              state <= SEND_PACKET;
1218
            end if;
1219
 
1220
            outboundDat_o <= x"0000" & "000000" & vc_i & crf_i & prio_i & tt_i & x"d";
1221
            packetIndex <= 1;
1222
 
1223
          when SEND_PACKET =>
1224
            ---------------------------------------------------------------------
1225
            -- 
1226
            ---------------------------------------------------------------------
1227
            outboundStb_o <= '1';
1228
            if (outboundStall_i = '0') then
1229 46 magro732
              case (packetIndex) is
1230
                when 1 =>
1231 47 magro732
                  -- dstid
1232 48 magro732
                  outboundDat_o <= dstId_i;
1233 46 magro732
                  packetIndex <= packetIndex + 1;
1234 48 magro732
 
1235 46 magro732
                when 2 =>
1236 47 magro732
                  -- srcid 
1237 48 magro732
                  outboundDat_o <= srcId_i;
1238 46 magro732
                  packetIndex <= packetIndex + 1;
1239 48 magro732
 
1240 46 magro732
                when 3 =>
1241 48 magro732
                  -- transaction & status & targetTID & double-word0(63:48)
1242
                  if (doneNoPayloadReady_i = '1') then
1243
                    outboundDat_o <= TTYPE_RESPONSE_NO_PAYLOAD & "0000" & tid_i & x"0000";
1244
                    state <= WAIT_COMPLETE;
1245
                  elsif (doneWithPayloadReady_i = '1') then
1246
                    outboundDat_o <= TTYPE_RESPONSE_WITH_PAYLOAD & "0000" & tid_i & payload_i(63 downto 48);
1247
                  elsif (errorReady_i = '1') then
1248
                    outboundDat_o <= TTYPE_RESPONSE_NO_PAYLOAD & "0111" & tid_i & x"0000";
1249
                    state <= WAIT_COMPLETE;
1250
                  end if;
1251
 
1252
                  payload <= payload_i(47 downto 0);
1253
                  payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
1254
 
1255 46 magro732
                  packetIndex <= packetIndex + 1;
1256 48 magro732
 
1257
                when 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 |
1258
                  36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 =>
1259 46 magro732
                  -- double-wordN(47:16)
1260 48 magro732
                  outboundDat_o <= payload(47 downto 16);
1261 46 magro732
                  packetIndex <= packetIndex + 1;
1262 48 magro732
 
1263
                when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 33 | 35 |
1264
                  37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 59 | 61 | 63 | 65 | 67 =>
1265 46 magro732
                  -- double-wordN(15:0) & double-wordN(63:48)
1266 48 magro732
                  outboundDat_o <= payload(15 downto 0) & payload_i(63 downto 48);
1267 47 magro732
 
1268 48 magro732
                  payload <= payload_i(47 downto 0);
1269
                  payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
1270 47 magro732
                  if (payloadIndex = payloadLength_i) then
1271 46 magro732
                    state <= WAIT_COMPLETE;
1272
                  end if;
1273 48 magro732
 
1274
                  packetIndex <= packetIndex + 1;
1275
 
1276 46 magro732
                when others =>
1277 48 magro732
                  -- Unallowed response length.
1278
                  -- Dont do anything.
1279
 
1280 46 magro732
              end case;
1281
            end if;
1282
 
1283
          when WAIT_COMPLETE =>
1284
            -------------------------------------------------------------------
1285
            -- 
1286
            -------------------------------------------------------------------
1287 48 magro732
            outboundStb_o <= '0';
1288
            if ((doneNoPayloadReady_i = '0') and (doneWithPayloadReady_i = '0') and
1289
                (errorReady_i = '0')) then
1290 46 magro732
              state <= WAIT_PACKET;
1291
              done_o <= '0';
1292
            else
1293
              done_o <= '1';
1294
            end if;
1295
 
1296
          when others =>
1297
            ---------------------------------------------------------------------
1298
            -- 
1299
            ---------------------------------------------------------------------
1300
            state <= WAIT_PACKET;
1301
 
1302
        end case;
1303
      end if;
1304
    end if;
1305
  end process;
1306
 
1307
end architecture;

powered by: WebSVN 2.1.0

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