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

Subversion Repositories rio

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

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

Line No. Rev Author Line
1 33 magro732
-------------------------------------------------------------------------------
2 36 magro732
-- 
3
-- RapidIO IP Library Core
4
-- 
5
-- This file is part of the RapidIO IP library project
6
-- http://www.opencores.org/cores/rio/
7
-- 
8
-- Description
9
-- Contains a platform to build endpoints on.
10
-- 
11
-- To Do:
12
-- -
13
-- 
14
-- Author(s): 
15
-- - Magnus Rosenius, magro732@opencores.org 
16
-- 
17
-------------------------------------------------------------------------------
18
-- 
19
-- Copyright (C) 2013 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 33 magro732
-- RioLogicalCommon.
46
-------------------------------------------------------------------------------
47
-- Ingress:
48 35 magro732
-- * Removes in-the-middle and trailing CRC.
49 33 magro732
-- * Forwards packets to logical-layer handlers depending on ftype and
50
--   transaction (output as address).
51
-- * Outputs header and deviceIDs in seperate accesses to facilitate 8- and
52
--   16-bit deviceAddress support. All fields are right-justified.
53
-- Egress:
54 35 magro732
-- * Adds in-the-middle and trailing CRC.
55 33 magro732
-- * Receives packets from logical-layer handlers.
56 35 magro732
-- * Receives header and deviceIDs in seperate accesses to facilitate 8- and
57
--   16-bit deviceAddress support. All fields are right-justified.
58 33 magro732
-------------------------------------------------------------------------------
59
-- REMARK: Egress; Places packets in different queues depending on the packet priority?
60
-- REMARK: Use inputOutput/message/maintenance/gsm/...-strobes instead?
61
-- REMARK: If the deviceId:s are removed, it will work for both 8/16-bit deviceIds.
62
--          case (ftype) is
63
--            when x"1" =>
64
--              -- Intervention-request class.
65
--              gsmStb_o <= '1';
66
--            when x"2" =>
67
--              -- Request-class.
68
--              if ((transaction = "0100") or
69
--                  (transaction = "1100") or (transaction = "1101") or
70
--                  (transaction = "1110") or (transaction = "1111")) then
71
--                inputOutputStb_o <= '1';
72
--              else
73
--                gsmStb_o <= '1';
74
--              end if;
75
--            when x"5" =>
76
--              -- Write-class.
77
--              if ((transaction = "0100") or (transaction = "0101") or 
78
--                  (transaction = "1100") or (transaction = "1101") or
79
--                  (transaction = "1110")) then
80
--                inputOutputStb_o <= '1';
81
--              elsif ((transaction = "0000") or (transaction = "0001")) then
82
--                gsmStb_o <= '1';
83
--              end if;
84
--            when x"6" =>
85
--              -- Streaming-Write class.
86
--              inputOutputStb_o <= '1';
87
--            when x"7" =>
88
--              -- Flow-control class.
89
--              flowControlStb_o <= '1';
90
--            when x"8" =>
91
--              -- Maintenance class.
92
--              maintenanceStb_o <= '1';
93
--            when x"9" =>
94
--              -- Data-Streaming class.
95
--              dataStreamingStb_o <= '1';
96
--            when x"a" =>
97
--              -- Doorbell class.
98
--              -- REMARK: Make this belong to input/output since the packets
99
--              -- and their responses look the same?
100
--              messagePassingStb_o <= '1';
101
--            when x"b" =>
102
--              -- Message class.
103
--              messagePassingStb_o <= '1';
104
--            when x"d" =>
105
--              -- Response class.
106
--              -- REMARK: Seperate strobe for this???
107
--              if ((transaction = "0000") or (transaction = "1000")) then
108
--                -- REMARK: Doorbell-response going in here as well... *sigh*
109
--                -- REMARK: GSM-responses going in here as well...
110
--                responseStb_o <= '1';
111
--              elsif (transaction = "0001") then
112
--                messagePassing <= '1';
113
--              end if;
114
--            when others =>
115
--              -- Unsupported ftype.
116
--              -- REMARK: Discard this packet.
117
--          end case;
118
 
119
-- tt=00
120
-- 0: header(15:0);dest(7:0);src(7:0);
121
-- 1: transaction(3:0)
122
-- shifter: 32 (32 empty)
123
-- tt=01
124
-- 0: header(15:0);dest(15:0);
125
-- 1: src(15:0);transaction(3:0)
126
-- shifter: 16 (48 empty)
127
 
128 36 magro732
 
129
library ieee;
130
use ieee.std_logic_1164.all;
131
use ieee.numeric_std.all;
132
use work.rio_common.all;
133
 
134
 
135
entity RioLogicalCommon is
136
  port(
137
    clk : in std_logic;
138
    areset_n : in std_logic;
139
    enable : in std_logic;
140
 
141
    readFrameEmpty_i : in std_logic;
142
    readFrame_o : out std_logic;
143
    readContent_o : out std_logic;
144
    readContentEnd_i : in std_logic;
145
    readContentData_i : in std_logic_vector(31 downto 0);
146
    writeFrameFull_i : in std_logic;
147
    writeFrame_o : out std_logic;
148
    writeFrameAbort_o : out std_logic;
149
    writeContent_o : out std_logic;
150
    writeContentData_o : out std_logic_vector(31 downto 0);
151
 
152
    masterCyc_o : out std_logic;
153
    masterStb_o : out std_logic;
154
    masterAdr_o : out std_logic_vector(7 downto 0);
155
    masterDat_o : out std_logic_vector(31 downto 0);
156
    masterAck_i : in std_logic;
157
    slaveCyc_i : in std_logic;
158
    slaveStb_i : in std_logic;
159
    slaveDat_i : in std_logic_vector(31 downto 0);
160
    slaveAck_o : out std_logic;
161
 
162
    configStb_o : out std_logic;
163
    configWe_o : out std_logic;
164
    configAdr_o : out std_logic_vector(23 downto 0);
165
    configSel_o : out std_logic_vector(7 downto 0);
166
    configDat_o : out std_logic_vector(63 downto 0);
167
    configDat_i : in std_logic_vector(63 downto 0);
168
    configAck_i : in std_logic);
169
end entity;
170
 
171
 
172
architecture RioLogicalCommon of RioLogicalCommon is
173
 
174
  component RioLogicalCommonIngress is
175
    port(
176
      clk : in std_logic;
177
      areset_n : in std_logic;
178
 
179
      readFrameEmpty_i : in std_logic;
180
      readFrame_o : out std_logic;
181
      readContent_o : out std_logic;
182
      readContentEnd_i : in std_logic;
183
      readContentData_i : in std_logic_vector(31 downto 0);
184
 
185
      masterCyc_o : out std_logic;
186
      masterStb_o : out std_logic;
187
      masterAdr_o : out std_logic_vector(7 downto 0);
188
      masterDat_o : out std_logic_vector(31 downto 0);
189
      masterAck_i : in std_logic);
190
  end component;
191
 
192
  component RioLogicalCommonEgress is
193
    port(
194
      clk : in std_logic;
195
      areset_n : in std_logic;
196
 
197
      writeFrameFull_i : in std_logic;
198
      writeFrame_o : out std_logic;
199
      writeFrameAbort_o : out std_logic;
200
      writeContent_o : out std_logic;
201
      writeContentData_o : out std_logic_vector(31 downto 0);
202
 
203
      slaveCyc_i : in std_logic;
204
      slaveStb_i : in std_logic;
205
      slaveDat_i : in std_logic_vector(31 downto 0);
206
      slaveAck_o : out std_logic);
207
  end component;
208
 
209
  component RioLogicalMaintenance is
210
    port(
211
      clk : in std_logic;
212
      areset_n : in std_logic;
213
      enable : in std_logic;
214
 
215
      configStb_o : out std_logic;
216
      configWe_o : out std_logic;
217
      configAdr_o : out std_logic_vector(23 downto 0);
218
      configDat_o : out std_logic_vector(63 downto 0);
219
      configSel_o : out std_logic_vector(7 downto 0);
220
      configDat_i : in std_logic_vector(63 downto 0);
221
      configAck_i : in std_logic;
222
 
223
      slaveCyc_i : in std_logic;
224
      slaveStb_i : in std_logic;
225
      slaveAdr_i : in std_logic_vector(7 downto 0);
226
      slaveDat_i : in std_logic_vector(31 downto 0);
227
      slaveAck_o : out std_logic;
228
 
229
      masterCyc_o : out std_logic;
230
      masterStb_o : out std_logic;
231
      masterDat_o : out std_logic_vector(31 downto 0);
232
      masterAck_i : in std_logic);
233
  end component;
234
 
235
begin
236
 
237
  masterCyc_o <= masterCyc;
238
  masterStb_o <= masterStb;
239
  masterDat_o <= masterDat;
240
  masterAck_i <= masterAck;
241
 
242
  slaveCyc_i <= slaveCyc;
243
  slaveStb_i <= slaveStb;
244
  slaveAdr_i <= slaveAdr;
245
  slaveDat_i <= slaveDat;
246
  slaveAck_o <= slaveAck or maintenanceAck;
247
 
248
  LogicalMaintenance: RioLogicalMaintenance
249
    port map(
250
      clk=>clk, areset_n=>areset_n, enable=>enable,
251
      configStb_o=>configStb_o,
252
      configWe_o=>configWe_o,
253
      configAdr_o=>configAdr_o,
254
      configDat_o=>configDat_o,
255
      configSel_o=>configSel_o,
256
      configDat_i=>configDat_i,
257
      configAck_i=>configAck_i,
258
      slaveCyc_i=>slaveCyc,
259
      slaveStb_i=>slaveStb,
260
      slaveAdr_i=>slaveAdr,
261
      slaveDat_i=>slaveDat,
262
      slaveAck_o=>maintenanceAck,
263
      masterCyc_o=>masterCyc,
264
      masterStb_o=>masterStb,
265
      masterDat_o=>masterDat,
266
      masterAck_i=>masterAck);
267
 
268
  -- REMARK: Add interconnect for master signals...
269
 
270
  Ingress: RioLogicalCommonIngress
271
    port map(
272
      clk=>clk, areset_n=>areset_n,
273
      readFrameEmpty_i=>readFrameEmpty_i,
274
      readFrame_o=>readFrame_o,
275
      readContent_o=>readContent_o,
276
      readContentEnd_i=>readContentEnd_i,
277
      readContentData_i=>readContentData_i,
278
      masterCyc_o=>masterCyc,
279
      masterStb_o=>masterStb,
280
      masterAdr_o=>masterAdr,
281
      masterDat_o=>masterDat,
282
      masterAck_i=>masterAck);
283
 
284
  Egress: RioLogicalCommonEgress
285
    port map(
286
      clk=>clk, areset_n=>areset_n,
287
      writeFrameFull_i=>writeFrameFull_i,
288
      writeFrame_o=>writeFrame_o,
289
      writeFrameAbort_o=>writeFrameAbort_o,
290
      writeContent_o=>writeContent_o,
291
      writeContentData_o=>writeContentData_o,
292
      slaveCyc_i=>slaveCyc,
293
      slaveStb_i=>slaveStb,
294
      slaveDat_i=>slaveDat,
295
      slaveAck_o=>slaveAck);
296
 
297
end architecture;
298
 
299
 
300
 
301 34 magro732
-------------------------------------------------------------------------------
302
-- RioLogicalCommonIngress.
303
-------------------------------------------------------------------------------
304 35 magro732
-- REMARK: Check the destination address to see if it matches the one configured???
305 36 magro732
-- REMARK: Remove the acknowledge on all accesses on the master bus.
306
-- REMARK: Add component declarations to riocommon.vhd.
307 33 magro732
library ieee;
308 34 magro732
use ieee.std_logic_1164.all;
309 33 magro732
use ieee.numeric_std.all;
310
use work.rio_common.all;
311
 
312
-------------------------------------------------------------------------------
313
-- Entity for RioLogicalCommonIngress.
314
-------------------------------------------------------------------------------
315
entity RioLogicalCommonIngress is
316
  port(
317
    clk : in std_logic;
318
    areset_n : in std_logic;
319
 
320
    readFrameEmpty_i : in std_logic;
321
    readFrame_o : out std_logic;
322
    readContent_o : out std_logic;
323
    readContentEnd_i : in std_logic;
324
    readContentData_i : in std_logic_vector(31 downto 0);
325
 
326
    masterCyc_o : out std_logic;
327
    masterStb_o : out std_logic;
328 35 magro732
    masterAdr_o : out std_logic_vector(7 downto 0);
329
    masterDat_o : out std_logic_vector(31 downto 0);
330 33 magro732
    masterAck_i : in std_logic);
331
end entity;
332
 
333
 
334
-------------------------------------------------------------------------------
335
-- 
336
-------------------------------------------------------------------------------
337
architecture RioLogicalCommonIngress of RioLogicalCommonIngress is
338 36 magro732
  type StateType is (IDLE,
339
                     WAIT_HEADER_0, HEADER_0, HEADER_1,
340
                     SEND_HEADER, SEND_DESTINATION, SEND_SOURCE,
341
                     FORWARD_SHORT, FORWARD_CRC, FORWARD_LONG, FORWARD_LAST,
342
                     END_PACKET);
343
  signal state : StateType;
344 33 magro732
 
345 36 magro732
  signal packetPosition : natural range 0 to 32;
346
  signal packetContent : std_logic_vector(63 downto 0);
347
 
348
  signal tt : std_logic_vector(1 downto 0);
349
  signal ftype : std_logic_vector(3 downto 0);
350
  signal transaction : std_logic_vector(3 downto 0);
351
 
352 33 magro732
begin
353
 
354
  process(clk, areset_n)
355
  begin
356
    if (areset_n = '0') then
357 36 magro732
      state <= IDLE;
358
      packetPosition <= 0;
359
      packetContent <= (others=>'0');
360
      tt <= "00";
361
      ftype <= "0000";
362
      transaction <= "0000";
363 33 magro732
    elsif (clk'event and clk = '1') then
364
      readContent_o <= '0';
365
 
366
      case state is
367
        when IDLE =>
368
          ---------------------------------------------------------------------
369
          -- 
370
          ---------------------------------------------------------------------
371
          packetPosition <= 0;
372
          if (readFrameEmpty_i = '0') then
373
            readContent_o <= '1';
374
            state <= WAIT_HEADER_0;
375
          end if;
376
 
377
        when WAIT_HEADER_0 =>
378
          ---------------------------------------------------------------------
379
          -- 
380
          ---------------------------------------------------------------------
381
          readContent_o <= '1';
382
          state <= HEADER_0;
383
 
384
        when HEADER_0 =>
385
          ---------------------------------------------------------------------
386
          -- 
387
          ---------------------------------------------------------------------
388
          packetContent <= packetContent(31 downto 0) & readContentData_i;
389
          packetPosition <= packetPosition + 1;
390
          readContent_o <= '1';
391
 
392
          tt <= readContentData_i(21 downto 20);
393
          ftype <= readContentData_i(19 downto 16);
394
 
395
          state <= HEADER_1;
396
 
397
        when HEADER_1 =>
398
          ---------------------------------------------------------------------
399
          -- 
400
          ---------------------------------------------------------------------
401
          packetContent <= packetContent(31 downto 0) & readContentData_i;
402
          packetPosition <= packetPosition + 1;
403
 
404
          if (tt = "00") then
405
            transaction <= readContentData_i(31 downto 28);
406
          elsif (tt = "01") then
407
            transaction <= readContentData_i(15 downto 12);
408
          end if;
409
 
410
          state <= SEND_HEADER;
411
 
412
        when SEND_HEADER =>
413
          ---------------------------------------------------------------------
414
          -- 
415
          ---------------------------------------------------------------------
416
          masterStb_o <= '1';
417 35 magro732
          masterAdr_o <= ftype & transaction;
418
          masterDat_o <= x"0000" & packetContent(63 downto 48);
419 33 magro732
          packetContent <= packetContent(47 downto 0) & x"0000";
420
 
421
          state <= SEND_DESTINATION;
422
 
423
        when SEND_DESTINATION =>
424
          ---------------------------------------------------------------------
425
          -- 
426
          ---------------------------------------------------------------------
427
          if (masterAck_i = '1') then
428
            if (tt = "00") then
429 35 magro732
              masterDat_o <= x"000000" & packetContent(63 downto 56);
430 33 magro732
              packetContent <= packetContent(55 downto 0) & x"00";
431
            elsif (tt = "01") then
432 35 magro732
              masterDat_o <= x"0000" & packetContent(63 downto 48);
433 33 magro732
              packetContent <= packetContent(31 downto 0) & readContentData_i;
434
              readContent_o <= '1';
435
            end if;
436
 
437
            state <= SEND_SOURCE;
438
          end if;
439
 
440
        when SEND_SOURCE =>
441
          ---------------------------------------------------------------------
442
          -- 
443
          ---------------------------------------------------------------------
444
          if (masterAck_i = '1') then
445
            if (tt = "00") then
446 35 magro732
              masterDat_o <= x"000000" & packetContent(63 downto 56);
447 33 magro732
              packetContent <= packetContent(55 downto 0) & x"00";
448
            elsif (tt = "01") then
449 35 magro732
              masterDat_o <= x"0000" & packetContent(63 downto 48);
450 33 magro732
              packetContent <= packetContent(47 downto 0) & x"0000";
451
            end if;
452
 
453 36 magro732
            state <= FORWARD_SHORT;
454 33 magro732
          end if;
455
 
456 36 magro732
        when FORWARD_SHORT =>
457 33 magro732
          ---------------------------------------------------------------------
458
          -- 
459
          ---------------------------------------------------------------------
460
          if (masterAck_i = '1') then
461 35 magro732
            masterDat_o <= packetContent(63 downto 32);
462 33 magro732
 
463
            packetPosition <= packetPosition + 1;
464 36 magro732
            packetContent <=
465
              packetContent(31 downto 0) & readContentData_i;
466
 
467
            if (readContentEnd_i = '0') then
468
              if (packetPosition = 20) then
469
                state <= FORWARD_CRC;
470
              end if;
471
 
472
              readContent_o <= '1';
473
            else
474
              readFrame_o <= '1';
475
              state <= FORWARD_LAST;
476
            end if;
477
          end if;
478 33 magro732
 
479 36 magro732
        when FORWARD_CRC =>
480
          ---------------------------------------------------------------------
481
          -- 
482
          ---------------------------------------------------------------------
483
          if (masterAck_i = '1') then
484
            masterDat_o <= packetContent(63 downto 32);
485
 
486
            packetPosition <= packetPosition + 1;
487
            packetContent <=
488
              packetContent(31 downto 0) & readContentData_i(15 downto 0) & x"0000";
489
 
490
            if (readContentEnd_i = '0') then
491
              readContent_o <= '1';
492
              state <= FORWARD_LONG;
493 33 magro732
            else
494 36 magro732
              readFrame_o <= '1';
495
              state <= FORWARD_LAST;
496 33 magro732
            end if;
497 36 magro732
          end if;
498
 
499
        when FORWARD_LONG =>
500
          ---------------------------------------------------------------------
501
          -- 
502
          ---------------------------------------------------------------------
503
          if (masterAck_i = '1') then
504
            masterDat_o <= packetContent(63 downto 32);
505
 
506
            packetPosition <= packetPosition + 1;
507
            packetContent <=
508
              packetContent(15 downto 0) & readContentData_i & x"0000";
509 33 magro732
 
510
            if (readContentEnd_i = '0') then
511
              readContent_o <= '1';
512
            else
513
              readFrame_o <= '1';
514
              state <= FORWARD_LAST;
515
            end if;
516
          end if;
517
 
518
        when FORWARD_LAST =>
519
          ---------------------------------------------------------------------
520
          -- 
521
          ---------------------------------------------------------------------
522 35 magro732
          -- REMARK: The last always contain the CRC?
523 33 magro732
          if (masterAck_i = '1') then
524 35 magro732
            masterDat_o <= packetContent(63 downto 32);
525 33 magro732
            state <= END_PACKET;
526
          end if;
527
 
528
        when END_PACKET =>
529
          ---------------------------------------------------------------------
530
          -- 
531
          ---------------------------------------------------------------------
532
          if (masterAck_i = '1') then
533
            state <= IDLE;
534
          end if;
535
 
536
        when others =>
537
          ---------------------------------------------------------------------
538
          -- 
539
          ---------------------------------------------------------------------
540
          state <= IDLE;
541
      end case;
542
    end if;
543
  end process;
544
 
545
end architecture;
546
 
547
 
548 34 magro732
-------------------------------------------------------------------------------
549
-- RioLogicalCommonEgress.
550
-- Only 8-bit and 16-bit deviceId are supported. The first write must contain
551
-- the 16-bit header, the second write must contain the destination address and
552
-- the third must contain the source address.
553 36 magro732
-- CRC is calculated during the transfer and is inserted at byte 81 and 82 and
554 34 magro732
-- appended to the packet when it ends.
555
-------------------------------------------------------------------------------
556
library ieee;
557
use ieee.std_logic_1164.all;
558
use ieee.numeric_std.all;
559
use work.rio_common.all;
560 33 magro732
 
561 34 magro732
-------------------------------------------------------------------------------
562
-- Entity for RioLogicalCommonEgress.
563
-------------------------------------------------------------------------------
564
entity RioLogicalCommonEgress is
565
  port(
566
    clk : in std_logic;
567
    areset_n : in std_logic;
568 33 magro732
 
569 34 magro732
    writeFrameFull_i : in std_logic;
570
    writeFrame_o : out std_logic;
571
    writeFrameAbort_o : out std_logic;
572
    writeContent_o : out std_logic;
573
    writeContentData_o : out std_logic_vector(31 downto 0);
574
 
575
    slaveCyc_i : in std_logic;
576
    slaveStb_i : in std_logic;
577
    slaveDat_i : in std_logic_vector(31 downto 0);
578
    slaveAck_o : out std_logic);
579
end entity;
580
 
581
 
582 33 magro732
-------------------------------------------------------------------------------
583 34 magro732
-- Architecture for RioLogicalCommonEgress.
584
-------------------------------------------------------------------------------
585
architecture RioLogicalCommonEgress of RioLogicalCommonEgress is
586
 
587
  component Crc16CITT is
588
    port(
589
      d_i : in  std_logic_vector(15 downto 0);
590
      crc_i : in  std_logic_vector(15 downto 0);
591
      crc_o : out std_logic_vector(15 downto 0));
592
  end component;
593
 
594 36 magro732
  type StateType is (IDLE,
595
                     HEADER_GET, HEADER_ACK,
596
                     DESTINATION_GET, DESTINATION_ACK,
597
                     SOURCE_GET, SOURCE_ACK,
598
                     CONTENT_GET, CONTENT_ACK,
599
                     CRC_APPEND, SEND_FRAME,
600
                     RESTART_FRAME, WAIT_UPDATE);
601
  signal state : StateType;
602
  signal packetPosition : natural range 0 to 31;
603
  signal halfWordPending : std_logic;
604
  signal halfWord : std_logic_vector(15 downto 0);
605
 
606
  signal header : std_logic_vector(15 downto 0);
607
  signal tt : std_logic_vector(1 downto 0);
608
  signal dstAddr : std_logic_vector(31 downto 0);
609
  signal srcAddr : std_logic_vector(31 downto 0);
610
 
611 34 magro732
  signal crc16Current, crc16Temp, crc16Next: std_logic_vector(15 downto 0);
612
 
613
begin
614
 
615
  process(clk, areset_n)
616
  begin
617
    if (areset_n = '0') then
618 36 magro732
      state <= IDLE;
619 34 magro732
      crc16Current <= x"0000";
620
      writeContentData <= (others=>'0');
621
    elsif (clk'event and clk = '1') then
622
      writeContent_o <= '0';
623
      writeFrame_o <= '0';
624
 
625
      case state is
626
        when IDLE =>
627
          ---------------------------------------------------------------------
628
          -- 
629
          ---------------------------------------------------------------------
630 35 magro732
          packetPosition <= 0;
631 34 magro732
          if (writeFrameFull_i = '0') then
632
            state <= HEADER_GET;
633
            crc16Current <= x"ffff";
634
          end if;
635
 
636 36 magro732
        when HEADER_GET =>
637 34 magro732
          ---------------------------------------------------------------------
638
          -- 
639
          ---------------------------------------------------------------------
640
          if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then
641
            -- REMARK: Only support the header in one position?
642
            if (slaveSelect_i = "1100") then
643
              header <= slaveData_i(31 downto 16);
644
              tt <= slaveData_i(21 downto 20);
645
            elsif (slaveSelect_i = "0110") then
646
              header <= slaveData_i(23 downto 8);
647
              tt <= slaveData_i(13 downto 12);
648
            elsif (slaveSelect_i = "0011") then
649
              header <= slaveData_i(15 downto 0);
650
              tt <= slaveData_i(5 downto 4);
651
            else
652 35 magro732
              -- REMARK: Not supported.
653 34 magro732
            end if;
654
 
655
            slaveAck_o <= '1';
656
 
657
            state <= HEADER_ACK;
658
          else
659
            state <= RESTART_FRAME;
660
          end if;
661
 
662
        when HEADER_ACK =>
663
          ---------------------------------------------------------------------
664
          -- 
665
          ---------------------------------------------------------------------
666
          slaveAck_o <= '0';
667
          state <= DESTINATION_GET;
668
 
669
        when DESTINATION_GET =>
670
          ---------------------------------------------------------------------
671
          -- 
672
          ---------------------------------------------------------------------
673
 
674
          if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then
675
            -- REMARK: Only support the destination in one position?
676
            if (slaveSelect_i = "1000") and (tt = "00") then
677
              dstAddr <= slaveData_i(31 downto 24);
678
            elsif (slaveSelect_i = "0100") and (tt = "00") then
679
              dstAddr <= slaveData_i(23 downto 16);
680
            elsif (slaveSelect_i = "0010") and (tt = "00") then
681
              dstAddr <= slaveData_i(15 downto 8);
682
            elsif (slaveSelect_i = "0001") and (tt = "00") then
683
              dstAddr <= slaveData_i(7 downto 0);
684
            elsif (slaveSelect_i = "1100") and (tt = "01") then
685
              writeContent_o <= '1';
686
              writeContentData <= header & slaveData_i(31 downto 16);
687
              packetPosition <= packetPosition + 1;
688
            elsif (slaveSelect_i = "0110") and (tt = "01") then
689
              writeContent_o <= '1';
690
              writeContentData <= header & slaveData_i(24 downto 8);
691
              packetPosition <= packetPosition + 1;
692
            elsif (slaveSelect_i = "0011") and (tt = "01") then
693
              writeContent_o <= '1';
694
              writeContentData <= header & slaveData_i(15 downto 0);
695
              packetPosition <= packetPosition + 1;
696
            else
697
              -- REMARK: Not supported.
698
            end if;
699
 
700
            slaveAck_o <= '1';
701
 
702
            state <= DESTINATION_ACK;
703
          else
704
            state <= RESTART_FRAME;
705
          end if;
706
 
707
        when DESTINATION_ACK =>
708
          ---------------------------------------------------------------------
709
          -- 
710
          ---------------------------------------------------------------------
711
          slaveAck_o <= '0';
712
          state <= SOURCE_GET;
713
 
714
        when SOURCE_GET =>
715
          ---------------------------------------------------------------------
716
          -- 
717
          ---------------------------------------------------------------------
718
 
719
          if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then
720
            -- REMARK: Only support the source in one position?
721
            if (slaveSelect_i = "1000") and (tt = "00") then
722
              halfWordPending <= '0';
723
              writeContent_o <= '1';
724
              writeContentData <= header & dstAddr & slaveData_i(31 downto 24);
725
              packetPosition <= packetPosition + 1;
726
            elsif (slaveSelect_i = "0100") and (tt = "00") then
727
              halfWordPending <= '0';
728
              writeContent_o <= '1';
729
              writeContentData <= header & dstAddr & slaveData_i(23 downto 16);
730
              packetPosition <= packetPosition + 1;
731
            elsif (slaveSelect_i = "0010") and (tt = "00") then
732
              halfWordPending <= '0';
733
              writeContent_o <= '1';
734
              writeContentData <= header & dstAddr & slaveData_i(15 downto 8);
735
              packetPosition <= packetPosition + 1;
736
            elsif (slaveSelect_i = "0001") and (tt = "00") then
737
              halfWordPending <= '0';
738
              writeContent_o <= '1';
739
              writeContentData <= header & dstAddr & slaveData_i(7 downto 0);
740
              packetPosition <= packetPosition + 1;
741
            elsif (slaveSelect_i = "1100") and (tt = "01") then
742
              halfWordPending <= '1';
743
              halfWord <= slaveData_i(31 downto 16);
744
            elsif (slaveSelect_i = "0110") and (tt = "01") then
745
              halfWordPending <= '1';
746
              halfWord <= slaveData_i(24 downto 8);
747
            elsif (slaveSelect_i = "0011") and (tt = "01") then
748
              halfWordPending <= '1';
749
              halfWord <= slaveData_i(15 downto 0);
750
            else
751
              -- REMARK: Not supported.
752
            end if;
753
 
754
            slaveAck_o <= '1';
755
 
756
            state <= SOURCE_ACK;
757
          else
758
            state <= RESTART_FRAME;
759
          end if;
760
 
761
        when SOURCE_ACK =>
762
          ---------------------------------------------------------------------
763
          -- 
764
          ---------------------------------------------------------------------
765
          slaveAck_o <= '0';
766
 
767
          if (tt = "00") then
768
            crcCurrent <= crcNext;
769
          end if;
770
 
771
          state <= CONTENT_GET;
772
 
773
        when CONTENT_GET =>
774
          ---------------------------------------------------------------------
775
          -- 
776
          ---------------------------------------------------------------------
777
          if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then
778
            -- REMARK: Only support full writes? Not possible with the last
779
            -- access though.
780
            if (slaveSelect_i = "1111") then
781
              if (halfWordPending = '0') then
782
                writeContent_o <= '1';
783
                writeContentData <= slaveData_i;
784
                packetPosition <= packetPosition + 1;
785
              else
786
                writeContent_o <= '1';
787
                writeContentData <= halfWord & slaveData_i(31 downto 16);
788
                packetPosition <= packetPosition + 1;
789
                halfWord <= slaveData_i(15 downto 0);
790
              end if;
791
            elsif (slaveSelect_i = "1100") then
792
              if (halfWordPending = '0') then
793
                halfWordPending <= '1';
794
                halfWord <= slaveData_i(31 downto 16);
795
              else
796
                writeContent_o <= '1';
797
                writeContentData <= halfWord & slaveData_i(31 downto 16);
798
                packetPosition <= packetPosition + 1;
799
                halfWordPending <= '0';
800
              end if;
801
            elsif (slaveSelect_i = "0011") then
802
              if (halfWordPending = '0') then
803
                halfWordPending <= '1';
804
                halfWord <= slaveData_i(15 downto 0);
805
              else
806
                writeContent_o <= '1';
807
                writeContentData <= halfWord & slaveData_i(15 downto 0);
808
                packetPosition <= packetPosition + 1;
809
                halfWordPending <= '0';
810
              end if;
811
            end if;
812
 
813
            slaveAck_o <= '1';
814
 
815
            state <= CONTENT_ACK;
816
          else
817
            state <= CRC_APPEND;
818
          end if;
819
 
820
        when CONTENT_ACK =>
821
          ---------------------------------------------------------------------
822
          -- 
823
          ---------------------------------------------------------------------
824
          slaveAck_o <= '0';
825
 
826
          crc16Current <= crc16Next;
827
 
828
          if (packetPosition = 20) then
829
            if (halfWordPending = '0') then
830
              halfWordPending <= '1';
831
              halfWord <= crc16Next;
832
            else
833
              -- REMARK: The current CRC has to be updated when this is written.
834
              writeContent_o <= '1';
835
              writeContentData <= halfWord & crc16Next;
836
              packetPosition <= packetPosition + 1;
837
              halfWordPending <= '0';
838
              halfWord <= crc16Next;
839
            end if;
840
          end if;
841
 
842
          state <= CONTENT_GET;
843
 
844
        when CRC_APPEND =>
845
          ---------------------------------------------------------------------
846
          -- 
847
          ---------------------------------------------------------------------
848
          if (halfWordPending = '0') then
849
            writeContent_o <= '1';
850
            writeContentData <= crc16Current & x"0000";
851
            packetPosition <= packetPosition + 1;
852
          else
853
            writeContent_o <= '1';
854
            writeContentData <= halfWord & crc16Current;
855
            packetPosition <= packetPosition + 1;
856
          end if;
857
 
858
          state <= SEND_FRAME;
859
 
860
        when SEND_FRAME =>
861
          ---------------------------------------------------------------------
862
          -- 
863
          ---------------------------------------------------------------------
864
          writeFrame_o <= '1';
865
          state <= WAIT_UPDATE;
866
 
867
        when RESTART_FRAME =>
868
          ---------------------------------------------------------------------
869
          -- 
870
          ---------------------------------------------------------------------
871
          writeFrameAbort_o <= '1';
872
          state <= WAIT_UPDATE;
873
 
874
        when WAIT_UPDATE =>
875
          ---------------------------------------------------------------------
876
          -- 
877
          ---------------------------------------------------------------------
878
          state <= IDLE;
879
 
880
        when others =>
881
          ---------------------------------------------------------------------
882
          -- 
883
          ---------------------------------------------------------------------
884
      end case;
885
    end if;
886
  end process;
887
 
888
  -----------------------------------------------------------------------------
889
  -- Packet CRC calculation.
890
  -----------------------------------------------------------------------------
891
 
892
  Crc16High: Crc16CITT
893
    port map(
894
      d_i=>writeContentData(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp);
895
  Crc16Low: Crc16CITT
896
    port map(
897
      d_i=>writeContentData(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next);
898
 
899
end architecture;
900
 
901
 
902
 
903
 
904
 
905
-------------------------------------------------------------------------------
906 36 magro732
-- RioLogicalMaintenance
907
-- This logical layer module handles ingress maintenance requests and converts
908
-- them into accesses on a Wishbone compatible bus accessing the configuration
909
-- space.
910 33 magro732
-- Addresses: 0x80 (maint read request) and 0x81 (maint write request).
911
-------------------------------------------------------------------------------
912
library ieee;
913
use ieee.std_logic_1164.all;
914 34 magro732
use ieee.numeric_std.all;
915 33 magro732
use work.rio_common.all;
916
 
917 35 magro732
 
918 33 magro732
-------------------------------------------------------------------------------
919 36 magro732
-- Entity for RioLogicalMaintenance.
920 33 magro732
-------------------------------------------------------------------------------
921 36 magro732
entity RioLogicalMaintenance is
922 33 magro732
  port(
923
    clk : in std_logic;
924
    areset_n : in std_logic;
925 36 magro732
    enable : in std_logic;
926 33 magro732
 
927 35 magro732
    configStb_o : out std_logic;
928
    configWe_o : out std_logic;
929
    configAdr_o : out std_logic_vector(23 downto 0);
930
    configDat_o : out std_logic_vector(63 downto 0);
931
    configSel_o : out std_logic_vector(7 downto 0);
932
    configDat_i : in std_logic_vector(63 downto 0);
933
    configAck_i : in std_logic;
934
 
935 33 magro732
    slaveCyc_i : in std_logic;
936
    slaveStb_i : in std_logic;
937 34 magro732
    slaveAdr_i : in std_logic_vector(7 downto 0);
938
    slaveDat_i : in std_logic_vector(31 downto 0);
939
    slaveAck_o : out std_logic;
940
 
941
    masterCyc_o : out std_logic;
942
    masterStb_o : out std_logic;
943
    masterDat_o : out std_logic_vector(31 downto 0);
944
    masterAck_i : in std_logic);
945 33 magro732
end entity;
946
 
947 35 magro732
 
948
-------------------------------------------------------------------------------
949
-- 
950
-------------------------------------------------------------------------------
951 36 magro732
architecture RioLogicalMaintenance of RioLogicalMaintenance is
952
 
953
  component MaintenanceRequestInbound is
954 35 magro732
    port(
955 36 magro732
      clk : in std_logic;
956
      areset_n : in std_logic;
957
      enable : in std_logic;
958
 
959
      requestReadReady_o : out std_logic;
960
      requestWriteReady_o : out std_logic;
961
      requestVc_o : out std_logic;
962
      requestCrf_o : out std_logic;
963
      requestPrio_o : out std_logic_vector(1 downto 0);
964
      requestTt_o : out std_logic_vector(1 downto 0);
965
      requestDstId_o : out std_logic_vector(31 downto 0);
966
      requestSrcId_o : out std_logic_vector(31 downto 0);
967
      requestTid_o : out std_logic_vector(7 downto 0);
968
      requestOffset_o : out std_logic_vector(21 downto 0);
969
      requestPayloadSelect_o : out std_logic_vector(7 downto 0);
970
      requestPayloadLength_o : out std_logic_vector(3 downto 0);
971
      requestPayloadIndex_i : in std_logic_vector(4 downto 0);
972
      requestPayload_o : out std_logic_vector(63 downto 0);
973
      requestDone_i : in std_logic;
974
 
975
      slaveCyc_i : in std_logic;
976
      slaveStb_i : in std_logic;
977
      slaveAdr_i : in std_logic_vector(7 downto 0);
978
      slaveDat_i : in std_logic_vector(31 downto 0);
979
      slaveAck_o : out std_logic);
980 35 magro732
  end component;
981 36 magro732
 
982
  component MaintenanceResponseOutbound is
983
    port(
984
      clk : in std_logic;
985
      areset_n : in std_logic;
986
      enable : in std_logic;
987
 
988
      responseReadReady_i : in std_logic;
989
      responseWriteReady_i : in std_logic;
990
      responseVc_i : in std_logic;
991
      responseCrf_i : in std_logic;
992
      responsePrio_i : in std_logic_vector(1 downto 0);
993
      responseTt_i : in std_logic_vector(1 downto 0);
994
      responseDstId_i : in std_logic_vector(31 downto 0);
995
      responseSrcId_i : in std_logic_vector(31 downto 0);
996
      responseTid_i : in std_logic_vector(7 downto 0);
997
      responsePayloadLength_i : in std_logic_vector(3 downto 0);
998
      responsePayloadWrite_i : in std_logic;
999
      responsePayloadIndex_i : in std_logic_vector(4 downto 0);
1000
      responsePayload_i : in std_logic_vector(63 downto 0);
1001
      responseDone_o : out std_logic;
1002
 
1003
      masterCyc_o : out std_logic;
1004
      masterStb_o : out std_logic;
1005
      masterAdr_o : out std_logic_vector(7 downto 0);
1006
      masterDat_o : out std_logic_vector(31 downto 0);
1007
      masterAck_i : in std_logic);
1008
  end component;
1009
 
1010
  type StateType is (IDLE,
1011
                     CONFIG_READ, CONFIG_READ_RESPONSE,
1012
                     CONFIG_WRITE, CONFIG_WRITE_RESPONSE);
1013
  signal state : StateType;
1014
 
1015
  signal vc : std_logic;
1016
  signal crf : std_logic;
1017
  signal prio : std_logic_vector(1 downto 0);
1018
  signal tt : std_logic_vector(1 downto 0);
1019
  signal dstId : std_logic_vector(31 downto 0);
1020
  signal srcId : std_logic_vector(31 downto 0);
1021
  signal tid : std_logic_vector(7 downto 0);
1022
 
1023
  signal requestReadReady : std_logic;
1024
  signal requestWriteReady : std_logic;
1025
  signal requestOffset : std_logic_vector(21 downto 0);
1026
  signal requestPayloadLength : std_logic_vector(3 downto 0);
1027
  signal requestPayloadIndex : std_logic_vector(4 downto 0);
1028
  signal requestDone : std_logic;
1029 33 magro732
 
1030 36 magro732
  signal responseReadReady : std_logic;
1031
  signal responseWriteRead : std_logic;
1032
  signal responsePayloadLength : std_logic_vector(3 downto 0);
1033
  signal responsePayloadWrite : std_logic;
1034
  signal responsePayloadIndex : std_logic_vector(4 downto 0);
1035
  signal responseDone : std_logic;
1036
 
1037 33 magro732
begin
1038
 
1039 36 magro732
  -----------------------------------------------------------------------------
1040
  -- 
1041
  -----------------------------------------------------------------------------
1042
  Maintenance: process(clk, areset_n)
1043 33 magro732
  begin
1044
    if (areset_n = '0') then
1045
 
1046
    elsif (clk'event and clk = '1') then
1047 35 magro732
      case state is
1048 36 magro732
        when IDLE =>
1049 35 magro732
          ---------------------------------------------------------------------
1050
          -- 
1051
          ---------------------------------------------------------------------
1052 36 magro732
          if (requestReadReady = '1') then
1053
            configStb_o <= '1';
1054
            configWe_o <= '0';
1055
            configAdr_o <= requestOffset;
1056
            responsePayloadIndex <= (others=>'0');
1057
            state <= CONFIG_READ;
1058
          elsif (requestWriteReady = '1') then
1059
            configStb_o <= '1';
1060
            configWe_o <= '1';
1061
            configAdr_o <= requestOffset;
1062
            requestPayloadIndex <= (others=>'0');
1063
            state <= CONFIG_WRITE;
1064
          end if;
1065 35 magro732
 
1066
        when CONFIG_READ =>
1067
          ---------------------------------------------------------------------
1068
          -- 
1069
          ---------------------------------------------------------------------
1070
          if (configAck_i = '1') then
1071 36 magro732
            responsePayloadWrite <= '1';
1072
            responsePayloadIndex <= responsePayloadIndex + 1;
1073 35 magro732
 
1074 36 magro732
            if (responsePayloadIndex /= requestPayloadLength) then
1075 35 magro732
              configAdr_o <= configAdr_o + 1;
1076
            else
1077 36 magro732
              requestDone <= '1';
1078 35 magro732
              configStb_o <= '0';
1079
              state <= CONFIG_READ_RESPONSE;
1080
            end if;
1081
          end if;
1082
 
1083
        when CONFIG_READ_RESPONSE =>
1084
          ---------------------------------------------------------------------
1085
          -- 
1086
          ---------------------------------------------------------------------
1087 36 magro732
          responseReadReady <= '1';
1088
          if (responseDone = '1') then
1089
            state <= IDLE;
1090
          end if;
1091 35 magro732
 
1092 36 magro732
        when CONFIG_WRITE =>
1093 35 magro732
          ---------------------------------------------------------------------
1094
          -- 
1095
          ---------------------------------------------------------------------
1096 36 magro732
          if (configAck_i = '1') then
1097
            if (responsePayloadIndex /= requestPayloadLength) then
1098
              configAdr_o <= configAdr_o + 1;
1099
              requestIndex <= requestIndex + 1;
1100
            else
1101
              requestDone <= '1';
1102
              configStb_o <= '0';
1103
              state <= CONFIG_READ_RESPONSE;
1104
            end if;
1105 33 magro732
          end if;
1106 35 magro732
 
1107 36 magro732
        when CONFIG_WRITE_RESPONSE =>
1108 35 magro732
          ---------------------------------------------------------------------
1109
          -- 
1110
          ---------------------------------------------------------------------
1111 36 magro732
          responseReadReady <= '1';
1112
          if (responseDone = '1') then
1113
            state <= IDLE;
1114
          end if;
1115 35 magro732
 
1116
        when others =>
1117
 
1118
      end case;
1119 33 magro732
    end if;
1120
  end process;
1121
 
1122 35 magro732
  -----------------------------------------------------------------------------
1123 36 magro732
  -- Request packet handler.
1124 35 magro732
  -----------------------------------------------------------------------------
1125 36 magro732
  RequestInbound: MaintenanceRequestInbound
1126
    port map(
1127
      clk=>clk,
1128
      areset_n=>areset_n,
1129
      enable=>enable,
1130
      requestReadReady_o=>requestReadReady,
1131
      requestWriteReady_o=>requestWriteReady,
1132
      requestVc_o=>vc,
1133
      requestCrf_o=>crf,
1134
      requestPrio_o=>prio,
1135
      requestTt_o=>tt,
1136
      requestDstId_o=>dstId,
1137
      requestSrcId_o=>srcId,
1138
      requestTid_o=>requestTid,
1139
      requestOffset_o=>requestOffset,
1140
      requestPayloadSelect_o=>configSel_o,
1141
      requestPayloadLength_o=>requestPayloadLength,
1142
      requestPayloadIndex_i=>requestPayloadIndex,
1143
      requestPayload_o=>configDat_o,
1144
      requestDone_i=>requestDone,
1145
      slaveCyc_i=>slaveCyc_i,
1146
      slaveStb_i=>slaveStb_i,
1147
      slaveAdr_i=>slaveAdr_i,
1148
      slaveDat_i=>slaveDat_i,
1149
      slaveAck_o=>slaveAck_o);
1150 33 magro732
 
1151 36 magro732
  -----------------------------------------------------------------------------
1152
  -- Response packet handler.
1153
  -----------------------------------------------------------------------------
1154
  -- Note that the dstId and srcId is flipped since the response should be
1155
  -- returned to the source.
1156
  ResponseOutbound: MaintenanceResponseOutbound
1157
    port map(
1158
      clk=>clk, areset_n=>areset_n, enable=>enable,
1159
      responseReadReady_i=>responseReadReady,
1160
      responseWriteReady_i=>responseWriteReady,
1161
      responseVc_i=>vc,
1162
      responseCrf_i=>crf,
1163
      responsePrio_i=>prio,
1164
      responseTt_i=>tt,
1165
      responseDstId_i=>srcId,
1166
      responseSrcId_i=>dstId,
1167
      responseTid_i=>tid,
1168
      responsePayloadLength_i=>responsePayloadLength,
1169
      responsePayloadWrite_i=>responsePayloadWrite,
1170
      responsePayloadIndex_i=>responsePayloadIndex,
1171
      responsePayload_i=>configDat_i,
1172
      responseDone_o=>responseDone,
1173
      masterCyc_o=>masterCyc_o,
1174
      masterStb_o=>masterStb_o,
1175
      masterAdr_o=>masterAdr_o,
1176
      masterDat_o=>masterDat_o,
1177
      masterAck_i=>masterAck_i);
1178
 
1179 35 magro732
end architecture;
1180
 
1181
 
1182 36 magro732
-------------------------------------------------------------------------------
1183
-- 
1184
-------------------------------------------------------------------------------
1185
library ieee;
1186
use ieee.std_logic_1164.all;
1187
use ieee.numeric_std.all;
1188
use work.rio_common.all;
1189
 
1190
 
1191
-------------------------------------------------------------------------------
1192
-- 
1193
-------------------------------------------------------------------------------
1194
entity MaintenanceRequestInbound is
1195 35 magro732
  port(
1196
    clk : in std_logic;
1197
    areset_n : in std_logic;
1198 36 magro732
    enable : in std_logic;
1199 35 magro732
 
1200 36 magro732
    requestReadReady_o : out std_logic;
1201
    requestWriteReady_o : out std_logic;
1202
    requestVc_o : out std_logic;
1203
    requestCrf_o : out std_logic;
1204
    requestPrio_o : out std_logic_vector(1 downto 0);
1205
    requestTt_o : out std_logic_vector(1 downto 0);
1206
    requestDstId_o : out std_logic_vector(31 downto 0);
1207
    requestSrcId_o : out std_logic_vector(31 downto 0);
1208
    requestTid_o : out std_logic_vector(7 downto 0);
1209
    requestOffset_o : out std_logic_vector(21 downto 0);
1210
    requestPayloadSelect_o : out std_logic_vector(7 downto 0);
1211
    requestPayloadLength_o : out std_logic_vector(3 downto 0);
1212
    requestPayloadIndex_i : in std_logic_vector(4 downto 0);
1213
    requestPayload_o : out std_logic_vector(63 downto 0);
1214
    requestDone_i : in std_logic;
1215
 
1216 35 magro732
    slaveCyc_i : in std_logic;
1217
    slaveStb_i : in std_logic;
1218
    slaveAdr_i : in std_logic_vector(7 downto 0);
1219
    slaveDat_i : in std_logic_vector(31 downto 0);
1220 36 magro732
    slaveAck_o : out std_logic);
1221 35 magro732
end entity;
1222
 
1223
 
1224 36 magro732
-------------------------------------------------------------------------------
1225
-- 
1226
-------------------------------------------------------------------------------
1227
architecture MaintenanceRequestInbound of MaintenanceRequestInbound is
1228
  component MemorySimpleDualPort
1229
    generic(
1230
      ADDRESS_WIDTH : natural := 1;
1231
      DATA_WIDTH : natural := 1);
1232
    port(
1233
      clkA_i : in std_logic;
1234
      enableA_i : in std_logic;
1235
      addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
1236
      dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
1237
 
1238
      clkB_i : in std_logic;
1239
      enableB_i : in std_logic;
1240
      addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
1241
      dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
1242
  end component;
1243
 
1244
  type StateType is (RECEIVE_PACKET, READY);
1245
  signal state : StateType;
1246
 
1247
  signal slaveAck : std_logic;
1248
  signal maintReadComplete : std_logic;
1249
  signal maintWriteComplete : std_logic;
1250
 
1251
  signal packetIndex : natural range 0 to 33;
1252
  signal requstPayload : std_logic_vector(63 downto 0);
1253 35 magro732
 
1254
begin
1255
 
1256
  slaveAck_o <= slaveAck;
1257 36 magro732
 
1258
  requestReadReady_o <= maintReadComplete;
1259
  requestWriteReady_o <= maintWriteComplete;
1260
 
1261
  MaintenanceRequest: process(clk, areset_n)
1262 35 magro732
  begin
1263
    if (areset_n = '0') then
1264 36 magro732
      packetIndex <= 0;
1265 35 magro732
    elsif (clk'event and clk = '1') then
1266
      case state is
1267 36 magro732
        when RECEIVE_PACKET =>
1268 35 magro732
          ---------------------------------------------------------------------
1269 36 magro732
          -- This state waits for a new maintenance request packet, receives it
1270
          -- and parses it.
1271 35 magro732
          ---------------------------------------------------------------------
1272
          if (slaveCyc_i = '1') then
1273
            if (slaveAck = '0') then
1274
              if (slaveStb_i = '1') then
1275
                if (slaveAddress_i = x"80") then
1276 36 magro732
                  -------------------------------------------------------------
1277
                  -- Maintenance Read Request packet parser.
1278
                  -------------------------------------------------------------
1279 35 magro732
                  case (packetIndex) is
1280
                    when 0 =>
1281
                      -- x"0000" & ackid & vc & crf & prio & tt & ftype
1282 36 magro732
                      requestHeader_o <= slaveDat_i(15 downto 0);
1283 35 magro732
                      packetIndex <= packetIndex + 1;
1284
                    when 1 =>
1285
                      -- destid
1286 36 magro732
                      requestDstId_o <= slaveDat_i;
1287 35 magro732
                      packetIndex <= packetIndex + 1;
1288
                    when 2 =>
1289
                      -- srcid
1290 36 magro732
                      requestSrcId_o <= slaveDat_i;
1291 35 magro732
                      packetIndex <= packetIndex + 1;
1292
                    when 3 =>
1293
                      -- transaction & rdsize & srcTID & hop & config_offset(20:13)
1294
                      size <= slaveDat_i(27 downto 24);
1295 36 magro732
                      requestTid_o <= slaveDat_i(23 downto 16);
1296
                      requestOffset_o(20 downto 13) <= slaveDat_i(7 downto 0);
1297 35 magro732
                      packetIndex <= packetIndex + 1;
1298
                    when 4 =>
1299
                      -- config_offset(12:0) & wdptr & rsrv & crc(15:0)
1300 36 magro732
                      requestOffset_o(12 downto 0) <= slaveDat_i(31 downto 16);
1301 35 magro732
                      wdptr <= slaveDat_i(18);
1302
                      packetIndex <= packetIndex + 1;
1303
                      maintReadComplete <= '1';
1304
                    when others =>
1305
                      -- There should be no more content in a maintenance read request.
1306
                      -- Discard.
1307
                  end case;
1308 36 magro732
                elsif (slaveAddress_i = x"81") then
1309
                  -------------------------------------------------------------
1310
                  -- Maintenance Write Request packet parser.
1311
                  -------------------------------------------------------------
1312
                  case (packetIndex) is
1313
                    when 0 =>
1314
                      -- x"0000" & ackid & vc & crf & prio & tt & ftype
1315
                      requestHeader_o <= slaveDat_i(15 downto 0);
1316
                      packetIndex <= packetIndex + 1;
1317
                    when 1 =>
1318
                      -- destId
1319
                      requestDstId_o <= slaveDat_i;
1320
                      packetIndex <= packetIndex + 1;
1321
                    when 2 =>
1322
                      -- srcId
1323
                      requestSrcId_o <= slaveDat_i;
1324
                      packetIndex <= packetIndex + 1;
1325
                    when 3 =>
1326
                      -- transaction & wrsize & srcTID & hop & config_offset(20:13)
1327
                      size <= slaveDat_i(27 downto 24);
1328
                      requestTid_o <= slaveDat_i(23 downto 16);
1329
                      requestOffset_o(20 downto 13) <= slaveDat_i(7 downto 0);
1330
                      packetIndex <= packetIndex + 1;
1331
                    when 4 =>
1332
                      -- config_offset(12:0) & wdptr & rsrv & double-word(63:48)
1333
                      requestOffset_o(12 downto 0) <= slaveDat_i(31 downto 16);
1334
                      requestData(63 downto 48) <= slaveData_i(15 downto 0);
1335
                      wdptr <= slaveDat_i(18);
1336
                      packetIndex <= packetIndex + 1;
1337
                    when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 =>
1338
                      -- double-word(47:16)
1339
                      requestData(47 downto 16) <= slaveData_i;
1340
                      packetIndex <= packetIndex + 1;
1341
                    when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 =>
1342
                      -- double-word(15:0) & double-word(63:48)
1343
                      requestData(63 downto 48) <= slaveData_i(15 downto 0);
1344
                      packetIndex <= packetIndex + 1;
1345
 
1346
                      memoryEnable <= '1';
1347
                      memoryAddress <= memoryAddress + 1;
1348
                      memoryWrite <= '1';
1349
                      memoryDataIn <= requestData(63 downto 16) & slaveData_i(31 downto 16);
1350
                      maintWriteComplete <= '1';
1351
                    when others =>
1352
                      -- There should be no more content in a maintenance write request.
1353
                      -- Discard.
1354
                  end case;
1355 35 magro732
                end if;
1356
                slaveAck <= '1';
1357
              end if;
1358
            else
1359 36 magro732
              memoryEnable <= '0';
1360
              memoryWrite <= '0';
1361 35 magro732
              slaveAck <= '0';
1362
            end if;
1363
          else
1364 36 magro732
            if (maintReadComplete = '1') or (maintWriteComplete = '1') then
1365 35 magro732
              state <= READY;
1366
            end if;
1367
            packetIndex <= 0;
1368 36 magro732
            memoryAddress <= (others=>'0');
1369 35 magro732
          end if;
1370
 
1371
        when READY =>
1372
          ---------------------------------------------------------------------
1373 36 magro732
          -- Wait for the handler of the packet to signal that it has been
1374
          -- processed.
1375 35 magro732
          ---------------------------------------------------------------------
1376 36 magro732
          if (requestDone_i = '1') then
1377 35 magro732
            maintReadComplete <= '0';
1378 36 magro732
            maintWriteComplete <= '0';
1379 35 magro732
            state <= WAIT_PACKET;
1380
          end if;
1381
 
1382
        when others =>
1383
 
1384
      end case;
1385
    end if;
1386
  end process;
1387
 
1388 33 magro732
  -----------------------------------------------------------------------------
1389 36 magro732
  -- Transformation of rdsize/wrsize into length of access and byte lanes.
1390 33 magro732
  -----------------------------------------------------------------------------
1391 36 magro732
  requestPayloadLength_o <= doubleWords;
1392
  requestPayloadSelect_o <= byteLanes;
1393
 
1394
  -- REMARK: Make this a common component? Can be used in IO-accesses as well.
1395
  -- REMARK: Not all of these are allowed in a maintenance request.
1396 35 magro732
  process(wdptr, size)
1397 33 magro732
  begin
1398 36 magro732
    if (areset_n = '0') then
1399
      doubleWords <= (others=>'0');
1400
      byteLanes <= (others=>'0');
1401
    elsif (clk'event and clk = '1') then
1402
      if (maintReadComplete = '1') or (maintWriteComplete = '1') then
1403
        case (wdptr & size) is
1404
          when "00000" =>
1405
            doubleWords <= 1;
1406
            byteLanes <= "10000000";
1407
          when "00001" =>
1408
            doubleWords <= 1;
1409
            byteLanes <= "01000000";
1410
 
1411
          when "00010" =>
1412
            doubleWords <= 1;
1413
            byteLanes <= "00100000";
1414
          when "00011" =>
1415
            doubleWords <= 1;
1416
            byteLanes <= "00010000";
1417
 
1418
          when "10000" =>
1419
            doubleWords <= 1;
1420
            byteLanes <= "00001000";
1421
          when "10001" =>
1422
            doubleWords <= 1;
1423
            byteLanes <= "00000100";
1424
 
1425
          when "10010" =>
1426
            doubleWords <= 1;
1427
            byteLanes <= "00000010";
1428
          when "10011" =>
1429
            doubleWords <= 1;
1430
            byteLanes <= "00000001";
1431
 
1432
          when "00100" =>
1433
            doubleWords <= 1;
1434
            byteLanes <= "11000000";
1435
          when "00101" =>
1436
            doubleWords <= 1;
1437
            byteLanes <= "11100000";
1438
 
1439
          when "00110" =>
1440
            doubleWords <= 1;
1441
            byteLanes <= "00110000";
1442
          when "00111" =>
1443
            doubleWords <= 1;
1444
            byteLanes <= "11111000";
1445
 
1446
          when "10100" =>
1447
            doubleWords <= 1;
1448
            byteLanes <= "00001100";
1449
          when "10101" =>
1450
            doubleWords <= 1;
1451
            byteLanes <= "00000111";
1452
 
1453
          when "10110" =>
1454
            doubleWords <= 1;
1455
            byteLanes <= "00000011";
1456
          when "10111" =>
1457
            doubleWords <= 1;
1458
            byteLanes <= "00011111";
1459
 
1460
          when "01000" =>
1461
            doubleWords <= 1;
1462
            byteLanes <= "11110000";
1463
          when "11000" =>
1464
            doubleWords <= 1;
1465
            byteLanes <= "00001111";
1466
 
1467
          when "01001" =>
1468
            doubleWords <= 1;
1469
            byteLanes <= "11111100";
1470
          when "11001" =>
1471
            doubleWords <= 1;
1472
            byteLanes <= "00111111";
1473
 
1474
          when "01010" =>
1475
            doubleWords <= 1;
1476
            byteLanes <= "11111110";
1477
          when "11010" =>
1478
            doubleWords <= 1;
1479
            byteLanes <= "01111111";
1480
 
1481
          when "01011" =>
1482
            doubleWords <= 1;
1483
            byteLanes <= "11111111";
1484
          when "11011" =>
1485
            doubleWords <= 2;
1486
            byteLanes <= "11111111";
1487
 
1488
          when "01100" =>
1489
            doubleWords <= 4;
1490
            byteLanes <= "11111111";
1491
          when "11100" =>
1492
            doubleWords <= 8;
1493
            byteLanes <= "11111111";
1494
 
1495
          when "01101" =>
1496
            doubleWords <= 12;
1497
            byteLanes <= "11111111";
1498
          when "11101" =>
1499
            doubleWords <= 16;
1500
            byteLanes <= "11111111";
1501
 
1502
          when "01110" =>
1503
            doubleWords <= 20;
1504
            byteLanes <= "11111111";
1505
          when "11110" =>
1506
            doubleWords <= 24;
1507
            byteLanes <= "11111111";
1508
 
1509
          when "01111" =>
1510
            doubleWords <= 28;
1511
            byteLanes <= "11111111";
1512
          when "11111" =>
1513
            doubleWords <= 32;
1514
            byteLanes <= "11111111";
1515
        end case;
1516
      end if;
1517
    end if;
1518
  end process;
1519 35 magro732
 
1520 36 magro732
  -----------------------------------------------------------------------------
1521
  -- Payload content memory.
1522
  -----------------------------------------------------------------------------
1523
  PayloadMemory: MemorySimpleDualPort
1524
    generic map(ADDRESS_WIDTH=>3, DATA_WIDTH=>64)
1525
    port map(clkA_i=>clk,
1526
             enableA_i=>memoryWrite,
1527
             addressA_i=>memoryAddress,
1528
             dataA_i=>memoryDataIn,
1529
             clkB_i=>clk,
1530
             enableB_i=>enable,
1531
             addressB_i=>requestPayloadIndex_i,
1532
             dataB_o=>requestPayload_o);
1533
 
1534
end architecture;
1535
 
1536
 
1537
-------------------------------------------------------------------------------
1538
-- 
1539
-------------------------------------------------------------------------------
1540
library ieee;
1541
use ieee.std_logic_1164.all;
1542
use ieee.numeric_std.all;
1543
use work.rio_common.all;
1544
 
1545
-------------------------------------------------------------------------------
1546
-- 
1547
-------------------------------------------------------------------------------
1548
-- REMARK: Add handler for maintenance response with error also...
1549
entity MaintenanceResponseOutbound is
1550
  port(
1551
    clk : in std_logic;
1552
    areset_n : in std_logic;
1553
    enable : in std_logic;
1554
 
1555
    responseReadReady_i : in std_logic;
1556
    responseWriteReady_i : in std_logic;
1557
    responseVc_i : in std_logic;
1558
    responseCrf_i : in std_logic;
1559
    responsePrio_i : in std_logic_vector(1 downto 0);
1560
    responseTt_i : in std_logic_vector(1 downto 0);
1561
    responseDstId_i : in std_logic_vector(31 downto 0);
1562
    responseSrcId_i : in std_logic_vector(31 downto 0);
1563
    responseTid_i : in std_logic_vector(7 downto 0);
1564
    responsePayloadLength_i : in std_logic_vector(3 downto 0);
1565
    responsePayloadWrite_i : in std_logic;
1566
    responsePayloadIndex_i : in std_logic_vector(4 downto 0);
1567
    responsePayload_i : in std_logic_vector(63 downto 0);
1568
    responseDone_o : out std_logic;
1569
 
1570
    masterCyc_o : out std_logic;
1571
    masterStb_o : out std_logic;
1572
    masterAdr_o : out std_logic_vector(7 downto 0);
1573
    masterDat_o : out std_logic_vector(31 downto 0);
1574
    masterAck_i : in std_logic);
1575
end entity;
1576
 
1577
 
1578
-------------------------------------------------------------------------------
1579
-- 
1580
-------------------------------------------------------------------------------
1581
architecture MaintenanceResponseOutbound of MaintenanceResponseOutbound is
1582
  component MemorySimpleDualPort
1583
    generic(
1584
      ADDRESS_WIDTH : natural := 1;
1585
      DATA_WIDTH : natural := 1);
1586
    port(
1587
      clkA_i : in std_logic;
1588
      enableA_i : in std_logic;
1589
      addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
1590
      dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
1591
 
1592
      clkB_i : in std_logic;
1593
      enableB_i : in std_logic;
1594
      addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
1595
      dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
1596
  end component;
1597
 
1598
  type StateType is (WAIT_PACKET,
1599
                     READ_RESPONSE, WRITE_RESPONSE,
1600
                     RESPONSE_DONE);
1601
  signal state : StateType;
1602
 
1603
  signal packetIndex : natural range 0 to 33;
1604
  signal responseHeader : std_logic_vector(15 downto 0);
1605
  signal responsePayload : std_logic_vector(63 downto 0);
1606
 
1607
  signal memoryEnable : std_logic;
1608
  signal memoryAddress : std_logic_vector(4 downto 0);
1609
  signal memoryDataRead : std_logic_vector(63 downto 0);
1610
 
1611
begin
1612
 
1613
  responseHeader <=
1614
    x"0000" & "000000" & responseVc_i & responseCrf_i &
1615
    responsePrio_i & responseTt_i & x"8";
1616
 
1617
  slaveAck_o <= slaveAck;
1618
 
1619
  MaintenanceResponse: process(clk, areset_n)
1620
  begin
1621
    if (areset_n = '0') then
1622
 
1623
    elsif (clk'event and clk = '1') then
1624
      if (responseReadReady_i = '1') or (responseWriteReady_i = '1') then
1625
        case state is
1626
          when WAIT_PACKET =>
1627
            -------------------------------------------------------------------
1628
            -- 
1629
            -------------------------------------------------------------------
1630
            if (responseReadReady_i = '1') then
1631
              masterCyc_o <= '1';
1632
              masterStb_o <= '1';
1633
              masterDat_o <= responseHeader;
1634
              packetIndex <= 1;
1635
              memoryEnable <= '1';
1636
              state <= READ_RESPONSE;
1637
            elsif (responseWriteReady_i = '1') then
1638
              masterCyc_o <= '1';
1639
              masterStb_o <= '1';
1640
              masterDat_o <= responseHeader;
1641
              packetIndex <= 1;
1642
              state <= WRITE_RESPONSE;
1643
            end if;
1644
 
1645
          when READ_RESPONSE =>
1646
            ---------------------------------------------------------------------
1647
            -- 
1648
            ---------------------------------------------------------------------
1649
            if (masterAck_i = '1') then
1650
              if (packetIndex = responseLength_i) then
1651
                masterCyc_o <= '0';
1652
                masterStb_o <= '0';
1653
                state <= RESPONSE_DONE;
1654
              else
1655
                case (packetIndex) is
1656
                  when 1 =>
1657
                    -- destination
1658
                    masterDat_o <= responseDstId_i;
1659
                    packetIndex <= packetIndex + 1;
1660
                  when 2 =>
1661
                    -- source 
1662
                    masterDat_o <= responseSrcId_i;
1663
                    packetIndex <= packetIndex + 1;
1664
                  when 3 =>
1665
                    -- transaction & status & targetTID & hop & reserved(7:0)
1666
                    masterDat_o <= "0010" & "0000" & responseTid_i & x"ff" & x"00";
1667
                    responsePayload <= memoryDataRead;
1668
                    memoryAddress <= memoryAddress + 1;
1669
                    packetIndex <= packetIndex + 1;
1670
                  when 4 =>
1671
                    -- reserved(15:0) & double-wordN(63:48)
1672
                    masterDat_o <= x"0000" & responsePayload(63 downto 48);
1673
                    packetIndex <= packetIndex + 1;
1674
                  when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 33 =>
1675
                    -- double-wordN(47:16)
1676
                    masterDat_o <= responsePayload(47 downto 16);
1677
                    packetIndex <= packetIndex + 1;
1678
                  when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 =>
1679
                    -- double-wordN(15:0) & double-wordN(63:32)
1680
                    masterDat_o <= responsePayload(15 downto 0) & responsePayload_i(63 downto 48);
1681
                    responsePayload <= memoryDataRead;
1682
                    memoryAddress <= memoryAddress + 1;
1683
                    packetIndex <= packetIndex + 1;
1684
                  when others =>
1685
                    -- Unallowed response length.
1686
                    -- Dont do anything.
1687
                end case;
1688
              end if;
1689
            end if;
1690
 
1691
          when WRITE_RESPONSE =>
1692
            ---------------------------------------------------------------------
1693
            -- 
1694
            ---------------------------------------------------------------------
1695
            if (masterAck_i = '1') then
1696
              case (packetIndex) is
1697
                when 1 =>
1698
                  -- destination
1699
                  masterDat_o <= responseDstId_i;
1700
                  packetIndex <= packetIndex + 1;
1701
                when 2 =>
1702
                  -- source 
1703
                  masterDat_o <= responseSrcId_i;
1704
                  packetIndex <= packetIndex + 1;
1705
                when 3 =>
1706
                  -- transaction & status & targetTID & hop & reserved(7:0)
1707
                  masterDat_o <= "0010" & "0000" & responseTid_i & x"ff" & x"00";
1708
                  responsePayload <= memoryDataRead;
1709
                  packetIndex <= packetIndex + 1;
1710
                when 4 =>
1711
                  -- reserved(15:0) & crc(15:0)
1712
                  masterDat_o <= x"00000000";
1713
                  packetIndex <= packetIndex + 1;
1714
                when others =>
1715
                  -- Response packet has been completed.
1716
                  masterCyc_o <= '0';
1717
                  masterStb_o <= '0';
1718
                  state <= RESPONSE_DONE;
1719
              end case;
1720
            end if;
1721
 
1722
          when RESPONSE_DONE =>
1723
            ---------------------------------------------------------------------
1724
            -- 
1725
            ---------------------------------------------------------------------
1726
            memoryEnable <= '0';
1727
            if (responseRead_i = '0') and (responseWrite = '0') then
1728
              state <= WAIT_PACKET;
1729
              responseDone_o <= '0';
1730
            else
1731
              responseDone_o <= '1';
1732
            end if;
1733
 
1734
          when others =>
1735
            ---------------------------------------------------------------------
1736
            -- 
1737
            ---------------------------------------------------------------------
1738
            state <= WAIT_PACKET;
1739
 
1740
        end case;
1741
      end if;
1742
    end if;
1743 33 magro732
  end process;
1744 36 magro732
 
1745
  -----------------------------------------------------------------------------
1746
  -- Payload content memory.
1747
  -----------------------------------------------------------------------------
1748
  PayloadMemory: MemorySimpleDualPort
1749
    generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>64)
1750
    port map(clkA_i=>clk,
1751
             enableA_i=>responsePayloadWrite_i,
1752
             addressA_i=>responsePayloadIndex_i,
1753
             dataA_i=>responsePayload_i,
1754
             clkB_i=>clk,
1755
             enableB_i=>memoryEnable,
1756
             addressB_i=>memoryAddress,
1757
             dataB_o=>memoryDataRead);
1758
 
1759 33 magro732
end architecture;

powered by: WebSVN 2.1.0

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