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 48

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

powered by: WebSVN 2.1.0

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