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

Subversion Repositories rio

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

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

Line No. Rev Author Line
1 39 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
-- 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
-- RioLogicalMaintenance
46
-- This logical layer module handles ingress maintenance requests and converts
47
-- them into accesses on a Wishbone compatible bus accessing the configuration
48
-- space.
49
-- Addresses: 0x80 (maint read request) and 0x81 (maint write request).
50
-------------------------------------------------------------------------------
51
library ieee;
52
use ieee.std_logic_1164.all;
53
use ieee.numeric_std.all;
54
use work.rio_common.all;
55
 
56
 
57
-------------------------------------------------------------------------------
58
-- Entity for RioLogicalMaintenance.
59
-------------------------------------------------------------------------------
60
entity RioLogicalMaintenance is
61
  port(
62
    clk : in std_logic;
63
    areset_n : in std_logic;
64
    enable : in std_logic;
65
 
66
    configStb_o : out std_logic;
67
    configWe_o : out std_logic;
68
    configAdr_o : out std_logic_vector(21 downto 0);
69
    configDat_o : out std_logic_vector(31 downto 0);
70
    configDat_i : in std_logic_vector(31 downto 0);
71
    configAck_i : in std_logic;
72
 
73
    slaveCyc_i : in std_logic;
74
    slaveStb_i : in std_logic;
75
    slaveAdr_i : in std_logic_vector(7 downto 0);
76
    slaveDat_i : in std_logic_vector(31 downto 0);
77
    slaveAck_o : out std_logic;
78
 
79
    masterCyc_o : out std_logic;
80
    masterStb_o : out std_logic;
81
    masterDat_o : out std_logic_vector(31 downto 0);
82
    masterAck_i : in std_logic);
83
end entity;
84
 
85
 
86
-------------------------------------------------------------------------------
87
-- 
88
-------------------------------------------------------------------------------
89
architecture RioLogicalMaintenance of RioLogicalMaintenance is
90
 
91
  component MaintenanceRequestInbound is
92
    port(
93
      clk : in std_logic;
94
      areset_n : in std_logic;
95
      enable : in std_logic;
96
 
97
      requestReadReady_o : out std_logic;
98
      requestWriteReady_o : out std_logic;
99
      requestVc_o : out std_logic;
100
      requestCrf_o : out std_logic;
101
      requestPrio_o : out std_logic_vector(1 downto 0);
102
      requestTt_o : out std_logic_vector(1 downto 0);
103
      requestDstId_o : out std_logic_vector(31 downto 0);
104
      requestSrcId_o : out std_logic_vector(31 downto 0);
105
      requestTid_o : out std_logic_vector(7 downto 0);
106
      requestOffset_o : out std_logic_vector(20 downto 0);
107
      requestWdptr_o : out std_logic;
108
      requestPayloadLength_o : out std_logic_vector(3 downto 0);
109
      requestPayloadIndex_i : in std_logic_vector(3 downto 0);
110
      requestPayload_o : out std_logic_vector(31 downto 0);
111
      requestDone_i : in std_logic;
112
 
113
      slaveCyc_i : in std_logic;
114
      slaveStb_i : in std_logic;
115
      slaveAdr_i : in std_logic_vector(7 downto 0);
116
      slaveDat_i : in std_logic_vector(31 downto 0);
117
      slaveAck_o : out std_logic);
118
  end component;
119
 
120
  component MaintenanceResponseOutbound is
121
    port(
122
      clk : in std_logic;
123
      areset_n : in std_logic;
124
      enable : in std_logic;
125
 
126
      responseReadReady_i : in std_logic;
127
      responseWriteReady_i : in std_logic;
128
      responseVc_i : in std_logic;
129
      responseCrf_i : in std_logic;
130
      responsePrio_i : in std_logic_vector(1 downto 0);
131
      responseTt_i : in std_logic_vector(1 downto 0);
132
      responseDstId_i : in std_logic_vector(31 downto 0);
133
      responseSrcId_i : in std_logic_vector(31 downto 0);
134
      responseTid_i : in std_logic_vector(7 downto 0);
135
      responseWdptr_i : in std_logic;
136
      responsePayloadLength_i : in std_logic_vector(3 downto 0);
137
      responsePayloadWrite_i : in std_logic;
138
      responsePayloadIndex_i : in std_logic_vector(3 downto 0);
139
      responsePayload_i : in std_logic_vector(31 downto 0);
140
      responseDone_o : out std_logic;
141
 
142
      masterCyc_o : out std_logic;
143
      masterStb_o : out std_logic;
144
      masterDat_o : out std_logic_vector(31 downto 0);
145
      masterAck_i : in std_logic);
146
  end component;
147
 
148
  type StateType is (IDLE,
149
                     CONFIG_READ, CONFIG_READ_RESPONSE,
150
                     CONFIG_WRITE, CONFIG_WRITE_RESPONSE);
151
  signal state : StateType;
152
 
153
  signal vc : std_logic;
154
  signal crf : std_logic;
155
  signal prio : std_logic_vector(1 downto 0);
156
  signal tt : std_logic_vector(1 downto 0);
157
  signal dstId : std_logic_vector(31 downto 0);
158
  signal srcId : std_logic_vector(31 downto 0);
159
  signal tid : std_logic_vector(7 downto 0);
160
  signal wdptr : std_logic;
161
 
162
  signal configAdr : std_logic_vector(21 downto 0);
163
  signal configDat : std_logic_vector(31 downto 0);
164
 
165
  signal requestReadReady : std_logic;
166
  signal requestWriteReady : std_logic;
167
  signal requestOffset : std_logic_vector(20 downto 0);
168
  signal requestPayloadLength : std_logic_vector(3 downto 0);
169
  signal requestPayloadIndex : std_logic_vector(3 downto 0);
170
  signal requestPayload : std_logic_vector(31 downto 0);
171
  signal requestDone : std_logic;
172
 
173
  signal responseReadReady : std_logic;
174
  signal responseWriteReady : std_logic;
175
  signal responsePayloadWrite : std_logic;
176
  signal responsePayloadIndex : std_logic_vector(3 downto 0);
177
  signal responseDone : std_logic;
178
 
179
begin
180
 
181
  configAdr_o <= configAdr;
182
  configDat_o <= configDat;
183
 
184
  -----------------------------------------------------------------------------
185
  -- 
186
  -----------------------------------------------------------------------------
187
  Maintenance: process(clk, areset_n)
188
  begin
189
    if (areset_n = '0') then
190
      configStb_o <= '0';
191
      configWe_o <= '0';
192
      configAdr <= (others=>'0');
193
      configDat <= (others=>'0');
194
 
195
      responseReadReady <= '0';
196
      responseWriteReady <= '0';
197
      responsePayloadWrite <= '0';
198
 
199
      requestDone <= '0';
200
 
201
      requestPayloadIndex <= (others=>'0');
202
    elsif (clk'event and clk = '1') then
203
      requestDone <= '0';
204
      responsePayloadWrite <= '0';
205
 
206
      if (responsePayloadWrite = '1') then
207
        responsePayloadIndex <= std_logic_vector(unsigned(responsePayloadIndex) + 1);
208
      end if;
209
 
210
      case state is
211
        when IDLE =>
212
          ---------------------------------------------------------------------
213
          -- 
214
          ---------------------------------------------------------------------
215
          responsePayloadIndex <= (others=>'0');
216
          if (requestReadReady = '1') then
217
            configStb_o <= '1';
218
            configWe_o <= '0';
219
            configAdr <= requestOffset & wdptr;
220
            state <= CONFIG_READ;
221
          elsif (requestWriteReady = '1') then
222
            configStb_o <= '1';
223
            configWe_o <= '1';
224
            configAdr <= requestOffset & wdptr;
225
            configDat <= requestPayload;
226
            requestPayloadIndex <= std_logic_vector(unsigned(requestPayloadIndex) + 1);
227
            state <= CONFIG_WRITE;
228
          else
229
            responsePayloadIndex <= (others=>'0');
230
            requestPayloadIndex <= (others=>'0');
231
          end if;
232
 
233
        when CONFIG_READ =>
234
          ---------------------------------------------------------------------
235
          -- 
236
          ---------------------------------------------------------------------
237
          if (configAck_i = '1') then
238
            responsePayloadWrite <= '1';
239
 
240
            if (responsePayloadIndex /= requestPayloadLength) then
241
              configAdr <= std_logic_vector(unsigned(configAdr) + 1);
242
            else
243
              requestDone <= '1';
244
              configStb_o <= '0';
245
              state <= CONFIG_READ_RESPONSE;
246
            end if;
247
          end if;
248
 
249
        when CONFIG_READ_RESPONSE =>
250
          ---------------------------------------------------------------------
251
          -- 
252
          ---------------------------------------------------------------------
253
          if (responseDone = '1') then
254
            responseReadReady <= '0';
255
            state <= IDLE;
256
          else
257
            responseReadReady <= '1';
258
          end if;
259
 
260
        when CONFIG_WRITE =>
261
          ---------------------------------------------------------------------
262
          -- 
263
          ---------------------------------------------------------------------
264
          if (configAck_i = '1') then
265
            responsePayloadWrite <= '1';
266
 
267
            if (responsePayloadIndex /= requestPayloadLength) then
268
              configAdr <= std_logic_vector(unsigned(configAdr) + 1);
269
              configDat <= requestPayload;
270
              requestPayloadIndex <= std_logic_vector(unsigned(requestPayloadIndex) + 1);
271
            else
272
              requestDone <= '1';
273
              configStb_o <= '0';
274
              state <= CONFIG_WRITE_RESPONSE;
275
            end if;
276
          end if;
277
 
278
        when CONFIG_WRITE_RESPONSE =>
279
          ---------------------------------------------------------------------
280
          -- 
281
          ---------------------------------------------------------------------
282
          if (responseDone = '1') then
283
            responseWriteReady <= '0';
284
            state <= IDLE;
285
          else
286
            responseWriteReady <= '1';
287
          end if;
288
 
289
        when others =>
290
 
291
      end case;
292
    end if;
293
  end process;
294
 
295
  -----------------------------------------------------------------------------
296
  -- Request packet handler.
297
  -----------------------------------------------------------------------------
298
  RequestInbound: MaintenanceRequestInbound
299
    port map(
300
      clk=>clk,
301
      areset_n=>areset_n,
302
      enable=>enable,
303
      requestReadReady_o=>requestReadReady,
304
      requestWriteReady_o=>requestWriteReady,
305
      requestVc_o=>vc,
306
      requestCrf_o=>crf,
307
      requestPrio_o=>prio,
308
      requestTt_o=>tt,
309
      requestDstId_o=>dstId,
310
      requestSrcId_o=>srcId,
311
      requestTid_o=>tid,
312
      requestOffset_o=>requestOffset,
313
      requestWdptr_o=>wdptr,
314
      requestPayloadLength_o=>requestPayloadLength,
315
      requestPayloadIndex_i=>requestPayloadIndex,
316
      requestPayload_o=>requestPayload,
317
      requestDone_i=>requestDone,
318
      slaveCyc_i=>slaveCyc_i,
319
      slaveStb_i=>slaveStb_i,
320
      slaveAdr_i=>slaveAdr_i,
321
      slaveDat_i=>slaveDat_i,
322
      slaveAck_o=>slaveAck_o);
323
 
324
  -----------------------------------------------------------------------------
325
  -- Response packet handler.
326
  -----------------------------------------------------------------------------
327
  -- Note that the dstId and srcId is flipped since the response should be
328
  -- returned to the source.
329
  ResponseOutbound: MaintenanceResponseOutbound
330
    port map(
331
      clk=>clk, areset_n=>areset_n, enable=>enable,
332
      responseReadReady_i=>responseReadReady,
333
      responseWriteReady_i=>responseWriteReady,
334
      responseVc_i=>vc,
335
      responseCrf_i=>crf,
336
      responsePrio_i=>prio,
337
      responseTt_i=>tt,
338
      responseDstId_i=>srcId,
339
      responseSrcId_i=>dstId,
340
      responseTid_i=>tid,
341
      responseWdptr_i=>wdptr,
342
      responsePayloadLength_i=>requestPayloadLength,
343
      responsePayloadWrite_i=>responsePayloadWrite,
344
      responsePayloadIndex_i=>responsePayloadIndex,
345
      responsePayload_i=>configDat_i,
346
      responseDone_o=>responseDone,
347
      masterCyc_o=>masterCyc_o,
348
      masterStb_o=>masterStb_o,
349
      masterDat_o=>masterDat_o,
350
      masterAck_i=>masterAck_i);
351
 
352
end architecture;
353
 
354
 
355
-------------------------------------------------------------------------------
356
-- 
357
-------------------------------------------------------------------------------
358
library ieee;
359
use ieee.std_logic_1164.all;
360
use ieee.numeric_std.all;
361
use work.rio_common.all;
362
 
363
 
364
-------------------------------------------------------------------------------
365
-- 
366
-------------------------------------------------------------------------------
367
entity MaintenanceRequestInbound is
368
  port(
369
    clk : in std_logic;
370
    areset_n : in std_logic;
371
    enable : in std_logic;
372
 
373
    requestReadReady_o : out std_logic;
374
    requestWriteReady_o : out std_logic;
375
    requestVc_o : out std_logic;
376
    requestCrf_o : out std_logic;
377
    requestPrio_o : out std_logic_vector(1 downto 0);
378
    requestTt_o : out std_logic_vector(1 downto 0);
379
    requestDstId_o : out std_logic_vector(31 downto 0);
380
    requestSrcId_o : out std_logic_vector(31 downto 0);
381
    requestTid_o : out std_logic_vector(7 downto 0);
382
    requestOffset_o : out std_logic_vector(20 downto 0);
383
    requestWdptr_o : out std_logic;
384
    requestPayloadLength_o : out std_logic_vector(3 downto 0);
385
    requestPayloadIndex_i : in std_logic_vector(3 downto 0);
386
    requestPayload_o : out std_logic_vector(31 downto 0);
387
    requestDone_i : in std_logic;
388
 
389
    slaveCyc_i : in std_logic;
390
    slaveStb_i : in std_logic;
391
    slaveAdr_i : in std_logic_vector(7 downto 0);
392
    slaveDat_i : in std_logic_vector(31 downto 0);
393
    slaveAck_o : out std_logic);
394
end entity;
395
 
396
 
397
-------------------------------------------------------------------------------
398
-- 
399
-------------------------------------------------------------------------------
400
architecture MaintenanceRequestInbound of MaintenanceRequestInbound is
401
  component MemorySimpleDualPort
402
    generic(
403
      ADDRESS_WIDTH : natural := 1;
404
      DATA_WIDTH : natural := 1);
405
    port(
406
      clkA_i : in std_logic;
407
      enableA_i : in std_logic;
408
      addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
409
      dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
410
 
411
      clkB_i : in std_logic;
412
      enableB_i : in std_logic;
413
      addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
414
      dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
415
  end component;
416
 
417
  type StateType is (RECEIVE_PACKET, READY);
418
  signal state : StateType;
419
 
420
  signal wdptr : std_logic;
421
  signal size : std_logic_vector(3 downto 0);
422
  signal words : natural range 0 to 32;
423
 
424
  signal slaveAck : std_logic;
425
  signal maintReadComplete : std_logic;
426
  signal maintWriteComplete : std_logic;
427
 
428
  signal packetIndex : natural range 0 to 33;
429
  signal requestData : std_logic_vector(31 downto 0);
430
 
431
  signal memoryWrite : std_logic;
432
  signal memoryAddress : std_logic_vector(3 downto 0);
433
  signal memoryDataIn : std_logic_vector(31 downto 0);
434
 
435
begin
436
 
437
  slaveAck_o <= slaveAck;
438
 
439
  requestReadReady_o <= maintReadComplete when (state = READY) else '0';
440
  requestWriteReady_o <= maintWriteComplete when (state = READY) else '0';
441
 
442
  MaintenanceRequest: process(clk, areset_n)
443
  begin
444
    if (areset_n = '0') then
445
      slaveAck <= '0';
446
 
447
      maintReadComplete <= '0';
448
      maintWriteComplete <= '0';
449
 
450
      requestVc_o <= '0';
451
      requestCrf_o <= '0';
452
      requestPrio_o <= "00";
453
      requestTt_o <= "00";
454
      requestOffset_o <= (others=>'0');
455
 
456
      wdptr <= '0';
457
      size <= (others=>'0');
458
 
459
      packetIndex <= 0;
460
      memoryWrite <= '0';
461
      memoryAddress <= (others=>'0');
462
      memoryDataIn <= (others=>'0');
463
    elsif (clk'event and clk = '1') then
464
      case state is
465
        when RECEIVE_PACKET =>
466
          ---------------------------------------------------------------------
467
          -- This state waits for a new maintenance request packet, receives it
468
          -- and parses it.
469
          ---------------------------------------------------------------------
470
          if (slaveCyc_i = '1') then
471
            if (slaveAck = '0') then
472
              if (slaveStb_i = '1') then
473
                if (slaveAdr_i = x"80") then
474
                  -------------------------------------------------------------
475
                  -- Maintenance Read Request packet parser.
476
                  -------------------------------------------------------------
477
                  case (packetIndex) is
478
                    when 0 =>
479
                      -- x"0000" & ackid & vc & crf & prio & tt & ftype
480
                      requestVc_o <= slaveDat_i(9);
481
                      requestCrf_o <= slaveDat_i(8);
482
                      requestPrio_o <= slaveDat_i(7 downto 6);
483
                      requestTt_o <= slaveDat_i(5 downto 4);
484
                      packetIndex <= packetIndex + 1;
485
                    when 1 =>
486
                      -- destid
487
                      requestDstId_o <= slaveDat_i;
488
                      packetIndex <= packetIndex + 1;
489
                    when 2 =>
490
                      -- srcid
491
                      requestSrcId_o <= slaveDat_i;
492
                      packetIndex <= packetIndex + 1;
493
                    when 3 =>
494
                      -- transaction & rdsize & srcTID & hop & config_offset(20:13)
495
                      size <= slaveDat_i(27 downto 24);
496
                      requestTid_o <= slaveDat_i(23 downto 16);
497
                      requestOffset_o(20 downto 13) <= slaveDat_i(7 downto 0);
498
                      packetIndex <= packetIndex + 1;
499
                    when 4 =>
500
                      -- config_offset(12:0) & wdptr & rsrv & crc(15:0)
501
                      requestOffset_o(12 downto 0) <= slaveDat_i(31 downto 19);
502
                      wdptr <= slaveDat_i(18);
503
                      packetIndex <= packetIndex + 1;
504
                      maintReadComplete <= '1';
505
                    when others =>
506
                      -- There should be no more content in a maintenance read request.
507
                      -- Discard.
508
                  end case;
509
                elsif (slaveAdr_i = x"81") then
510
                  -------------------------------------------------------------
511
                  -- Maintenance Write Request packet parser.
512
                  -------------------------------------------------------------
513
                  case (packetIndex) is
514
                    when 0 =>
515
                      -- x"0000" & ackid & vc & crf & prio & tt & ftype
516
                      requestVc_o <= slaveDat_i(9);
517
                      requestCrf_o <= slaveDat_i(8);
518
                      requestPrio_o <= slaveDat_i(7 downto 6);
519
                      requestTt_o <= slaveDat_i(5 downto 4);
520
                      packetIndex <= packetIndex + 1;
521
                    when 1 =>
522
                      -- destId
523
                      requestDstId_o <= slaveDat_i;
524
                      packetIndex <= packetIndex + 1;
525
                    when 2 =>
526
                      -- srcId
527
                      requestSrcId_o <= slaveDat_i;
528
                      packetIndex <= packetIndex + 1;
529
                    when 3 =>
530
                      -- transaction & wrsize & srcTID & hop & config_offset(20:13)
531
                      size <= slaveDat_i(27 downto 24);
532
                      requestTid_o <= slaveDat_i(23 downto 16);
533
                      requestOffset_o(20 downto 13) <= slaveDat_i(7 downto 0);
534
                      packetIndex <= packetIndex + 1;
535
                    when 4 =>
536
                      -- config_offset(12:0) & wdptr & rsrv & double-word(63:48)
537
                      requestOffset_o(12 downto 0) <= slaveDat_i(31 downto 19);
538
                      wdptr <= slaveDat_i(18);
539
                      requestData(31 downto 16) <= slaveDat_i(15 downto 0);
540
                      packetIndex <= packetIndex + 1;
541
                    when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 =>
542
                      -- double-word(47:16)
543
                      requestData(31 downto 16) <= slaveDat_i(15 downto 0);
544
                      packetIndex <= packetIndex + 1;
545
 
546
                      if (not ((size = "1000") and (wdptr = '1'))) then
547
                        memoryWrite <= '1';
548
                        memoryDataIn <= requestData(31 downto 16) & slaveDat_i(31 downto 16);
549
                      end if;
550
                    when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 =>
551
                      -- double-word(15:0) & double-word(63:48)
552
                      requestData(31 downto 16) <= slaveDat_i(15 downto 0);
553
                      packetIndex <= packetIndex + 1;
554
 
555
                      memoryWrite <= '1';
556
                      memoryDataIn <= requestData(31 downto 16) & slaveDat_i(31 downto 16);
557
                      maintWriteComplete <= '1';
558
                    when others =>
559
                      -- There should be no more content in a maintenance write request.
560
                      -- Discard.
561
                  end case;
562
                end if;
563
                slaveAck <= '1';
564
              end if;
565
            else
566
              if (memoryWrite = '1') then
567
                memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
568
              end if;
569
 
570
              memoryWrite <= '0';
571
              slaveAck <= '0';
572
            end if;
573
          else
574
            if (maintReadComplete = '1') or (maintWriteComplete = '1') then
575
              state <= READY;
576
            end if;
577
            packetIndex <= 0;
578
            memoryAddress <= (others=>'0');
579
          end if;
580
 
581
        when READY =>
582
          ---------------------------------------------------------------------
583
          -- Wait for the handler of the packet to signal that it has been
584
          -- processed.
585
          ---------------------------------------------------------------------
586
          if (requestDone_i = '1') then
587
            maintReadComplete <= '0';
588
            maintWriteComplete <= '0';
589
            state <= RECEIVE_PACKET;
590
          end if;
591
 
592
        when others =>
593
          ---------------------------------------------------------------------
594
          -- 
595
          ---------------------------------------------------------------------
596
 
597
      end case;
598
    end if;
599
  end process;
600
 
601
  -----------------------------------------------------------------------------
602
  -- Transformation of rdsize/wrsize into length of access and byte lanes.
603
  -----------------------------------------------------------------------------
604
 
605
  process(clk, areset_n)
606
  begin
607
    if (areset_n = '0') then
608
      requestPayloadLength_o <= (others=>'0');
609
      requestWdptr_o <= '0';
610
    elsif (clk'event and clk = '1') then
611
      if (maintReadComplete = '1') or (maintWriteComplete = '1') then
612
        if (wdptr = '0') then
613
          case size is
614
            when "1000" =>
615
              -- Read 1 word.
616
              requestPayloadLength_o <= "0000";
617
              requestWdptr_o <= '0';
618
            when "1011" =>
619
              -- Read 2 words.
620
              requestPayloadLength_o <= "0001";
621
              requestWdptr_o <= '0';
622
            when "1100" =>
623
              -- Read 8 words.
624
              requestPayloadLength_o <= "0111";
625
              requestWdptr_o <= '0';
626
            when others =>
627
              -- REMARK: Not allowed for a maintenance packet.
628
              requestPayloadLength_o <= "0000";
629
              requestWdptr_o <= '0';
630
          end case;
631
        else
632
          case size is
633
            when "1000" =>
634
              -- Read 1 word.
635
              requestPayloadLength_o <= "0000";
636
              requestWdptr_o <= '1';
637
            when "1011" =>
638
              -- Read 4 words.
639
              requestPayloadLength_o <= "0011";
640
              requestWdptr_o <= '0';
641
            when "1100" =>
642
              -- Read 16 words.
643
              requestPayloadLength_o <= "1111";
644
              requestWdptr_o <= '0';
645
            when others =>
646
              -- REMARK: Not allowed for a maintenance packet.
647
              requestPayloadLength_o <= "0000";
648
              requestWdptr_o <= '0';
649
          end case;
650
        end if;
651
      end if;
652
    end if;
653
  end process;
654
 
655
  -----------------------------------------------------------------------------
656
  -- Payload content memory.
657
  -----------------------------------------------------------------------------
658
  PayloadMemory: MemorySimpleDualPort
659
    generic map(ADDRESS_WIDTH=>4, DATA_WIDTH=>32)
660
    port map(clkA_i=>clk,
661
             enableA_i=>memoryWrite,
662
             addressA_i=>memoryAddress,
663
             dataA_i=>memoryDataIn,
664
             clkB_i=>clk,
665
             enableB_i=>enable,
666
             addressB_i=>requestPayloadIndex_i,
667
             dataB_o=>requestPayload_o);
668
 
669
end architecture;
670
 
671
 
672
-------------------------------------------------------------------------------
673
-- 
674
-------------------------------------------------------------------------------
675
library ieee;
676
use ieee.std_logic_1164.all;
677
use ieee.numeric_std.all;
678
use work.rio_common.all;
679
 
680
-------------------------------------------------------------------------------
681
-- 
682
-------------------------------------------------------------------------------
683
-- REMARK: Add handler for maintenance response with error also...
684
entity MaintenanceResponseOutbound is
685
  port(
686
    clk : in std_logic;
687
    areset_n : in std_logic;
688
    enable : in std_logic;
689
 
690
    responseReadReady_i : in std_logic;
691
    responseWriteReady_i : in std_logic;
692
    responseVc_i : in std_logic;
693
    responseCrf_i : in std_logic;
694
    responsePrio_i : in std_logic_vector(1 downto 0);
695
    responseTt_i : in std_logic_vector(1 downto 0);
696
    responseDstId_i : in std_logic_vector(31 downto 0);
697
    responseSrcId_i : in std_logic_vector(31 downto 0);
698
    responseTid_i : in std_logic_vector(7 downto 0);
699
    responseWdptr_i : in std_logic;
700
    responsePayloadLength_i : in std_logic_vector(3 downto 0);
701
    responsePayloadWrite_i : in std_logic;
702
    responsePayloadIndex_i : in std_logic_vector(3 downto 0);
703
    responsePayload_i : in std_logic_vector(31 downto 0);
704
    responseDone_o : out std_logic;
705
 
706
    masterCyc_o : out std_logic;
707
    masterStb_o : out std_logic;
708
    masterDat_o : out std_logic_vector(31 downto 0);
709
    masterAck_i : in std_logic);
710
end entity;
711
 
712
 
713
-------------------------------------------------------------------------------
714
-- 
715
-------------------------------------------------------------------------------
716
architecture MaintenanceResponseOutbound of MaintenanceResponseOutbound is
717
  component MemorySimpleDualPort
718
    generic(
719
      ADDRESS_WIDTH : natural := 1;
720
      DATA_WIDTH : natural := 1);
721
    port(
722
      clkA_i : in std_logic;
723
      enableA_i : in std_logic;
724
      addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
725
      dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
726
 
727
      clkB_i : in std_logic;
728
      enableB_i : in std_logic;
729
      addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
730
      dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
731
  end component;
732
 
733
  type StateType is (WAIT_PACKET,
734
                     READ_RESPONSE, WRITE_RESPONSE,
735
                     WAIT_COMPLETE, RESPONSE_DONE);
736
  signal state : StateType;
737
 
738
  signal packetIndex : natural range 0 to 33;
739
  signal responseHeader : std_logic_vector(31 downto 0);
740
  signal responsePayload : std_logic_vector(31 downto 0);
741
  signal responsePayloadIndex : std_logic_vector(2 downto 0);
742
 
743
  signal memoryEnable : std_logic;
744
  signal memoryAddress : std_logic_vector(3 downto 0);
745
  signal memoryDataRead : std_logic_vector(31 downto 0);
746
 
747
begin
748
 
749
  responseHeader <=
750
    x"0000" & "000000" & responseVc_i & responseCrf_i &
751
    responsePrio_i & responseTt_i & x"8";
752
 
753
  MaintenanceResponse: process(clk, areset_n)
754
  begin
755
    if (areset_n = '0') then
756
      masterCyc_o <= '0';
757
      masterStb_o <= '0';
758
 
759
      memoryEnable <= '0';
760
      memoryAddress <= (others=>'0');
761
 
762
      responsePayloadIndex <= (others=>'0');
763
      responseDone_o <= '0';
764
 
765
      state <= WAIT_PACKET;
766
    elsif (clk'event and clk = '1') then
767
      if (enable = '1') then
768
        case state is
769
          when WAIT_PACKET =>
770
            -------------------------------------------------------------------
771
            -- 
772
            -------------------------------------------------------------------
773
            if (responseReadReady_i = '1') then
774
              masterCyc_o <= '1';
775
              masterStb_o <= '1';
776
              masterDat_o <= responseHeader;
777
              packetIndex <= 1;
778
              memoryEnable <= '1';
779
              memoryAddress <= (others=>'0');
780
              responsePayloadIndex <= (others=>'0');
781
              state <= READ_RESPONSE;
782
            elsif (responseWriteReady_i = '1') then
783
              masterCyc_o <= '1';
784
              masterStb_o <= '1';
785
              masterDat_o <= responseHeader;
786
              packetIndex <= 1;
787
              state <= WRITE_RESPONSE;
788
            end if;
789
 
790
          when READ_RESPONSE =>
791
            ---------------------------------------------------------------------
792
            -- 
793
            ---------------------------------------------------------------------
794
            if (masterAck_i = '1') then
795
              case (packetIndex) is
796
                when 1 =>
797
                  -- destination
798
                  masterDat_o <= responseDstId_i;
799
                  packetIndex <= packetIndex + 1;
800
                when 2 =>
801
                  -- source 
802
                  masterDat_o <= responseSrcId_i;
803
                  packetIndex <= packetIndex + 1;
804
                when 3 =>
805
                  -- transaction & status & targetTID & hop & reserved(7:0)
806
                  masterDat_o <= "0010" & "0000" & responseTid_i & x"ff" & x"00";
807
                  packetIndex <= packetIndex + 1;
808
                when 4 =>
809
                  -- reserved(15:0) & double-wordN(63:48)
810
                  if (responsePayloadLength_i = "0000") and (responseWdptr_i = '0') then
811
                    masterDat_o <= x"0000" & memoryDataRead(31 downto 16);
812
                    responsePayload(31 downto 16) <= memoryDataRead(15 downto 0);
813
                    memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
814
                  elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then
815
                    masterDat_o <= x"0000" & x"0000";
816
                  else
817
                    masterDat_o <= x"0000" & memoryDataRead(31 downto 16);
818
                    responsePayload(31 downto 16) <= memoryDataRead(15 downto 0);
819
                    memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
820
                  end if;
821
                  packetIndex <= packetIndex + 1;
822
                when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 =>
823
                  -- double-wordN(47:16)
824
                  if (responsePayloadLength_i = "0000") and (responseWdptr_i = '0') then
825
                    masterDat_o <= responsePayload(31 downto 16) & x"0000";
826
                  elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then
827
                    masterDat_o <= x"0000" & memoryDataRead(31 downto 16);
828
                    responsePayload(31 downto 16) <= memoryDataRead(15 downto 0);
829
                    memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
830
                  else
831
                    masterDat_o <=
832
                      responsePayload(31 downto 16) & memoryDataRead(31 downto 16);
833
                    responsePayload(31 downto 16) <= memoryDataRead(15 downto 0);
834
                    memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
835
                  end if;
836
                  packetIndex <= packetIndex + 1;
837
                when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 =>
838
                  -- double-wordN(15:0) & double-wordN(63:48)
839
                  if (responsePayloadLength_i = "0000") and (responseWdptr_i = '0') then
840
                    masterDat_o <= x"0000" & x"0000";
841
                  elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then
842
                    masterDat_o <= responsePayload(31 downto 16) & x"0000";
843
                  else
844
                    if (responsePayloadIndex /= responsePayloadLength_i(3 downto 1)) then
845
                      masterDat_o <=
846
                        responsePayload(31 downto 16) & memoryDataRead(31 downto 16);
847
                      responsePayload(31 downto 16) <= memoryDataRead(15 downto 0);
848
                      memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
849
                    else
850
                      masterDat_o <=
851
                        responsePayload(31 downto 16) & x"0000";
852
                      responsePayload(31 downto 16) <= memoryDataRead(15 downto 0);
853
                      memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
854
                    end if;
855
                  end if;
856
 
857
                  responsePayloadIndex <=
858
                    std_logic_vector(unsigned(responsePayloadIndex) + 1);
859
 
860
                  if (responsePayloadIndex = responsePayloadLength_i(3 downto 1)) then
861
                    state <= WAIT_COMPLETE;
862
                  else
863
                    packetIndex <= packetIndex + 1;
864
                  end if;
865
                when others =>
866
                  -- Unallowed response length.
867
                  -- Dont do anything.
868
              end case;
869
            end if;
870
 
871
          when WRITE_RESPONSE =>
872
            ---------------------------------------------------------------------
873
            -- 
874
            ---------------------------------------------------------------------
875
            if (masterAck_i = '1') then
876
              case (packetIndex) is
877
                when 1 =>
878
                  -- destination
879
                  masterDat_o <= responseDstId_i;
880
                  packetIndex <= packetIndex + 1;
881
                when 2 =>
882
                  -- source 
883
                  masterDat_o <= responseSrcId_i;
884
                  packetIndex <= packetIndex + 1;
885
                when 3 =>
886
                  -- transaction & status & targetTID & hop & reserved(7:0)
887
                  masterDat_o <= "0011" & "0000" & responseTid_i & x"ff" & x"00";
888
                  packetIndex <= packetIndex + 1;
889
                when others =>
890
                  -- reserved(15:0) & crc(15:0)
891
                  masterDat_o <= x"00000000";
892
                  packetIndex <= packetIndex + 1;
893
                  state <= WAIT_COMPLETE;
894
              end case;
895
            end if;
896
 
897
          when WAIT_COMPLETE =>
898
            -------------------------------------------------------------------
899
            -- 
900
            -------------------------------------------------------------------
901
            if (masterAck_i = '1') then
902
              masterCyc_o <= '0';
903
              masterStb_o <= '0';
904
              state <= RESPONSE_DONE;
905
            end if;
906
 
907
          when RESPONSE_DONE =>
908
            ---------------------------------------------------------------------
909
            -- 
910
            ---------------------------------------------------------------------
911
            memoryEnable <= '0';
912
            if (responseReadReady_i = '0') and (responseWriteReady_i = '0') then
913
              state <= WAIT_PACKET;
914
              responseDone_o <= '0';
915
            else
916
              responseDone_o <= '1';
917
            end if;
918
 
919
          when others =>
920
            ---------------------------------------------------------------------
921
            -- 
922
            ---------------------------------------------------------------------
923
            state <= WAIT_PACKET;
924
 
925
        end case;
926
      end if;
927
    end if;
928
  end process;
929
 
930
  -----------------------------------------------------------------------------
931
  -- Payload content memory.
932
  -----------------------------------------------------------------------------
933
  PayloadMemory: MemorySimpleDualPort
934
    generic map(ADDRESS_WIDTH=>4, DATA_WIDTH=>32)
935
    port map(clkA_i=>clk,
936
             enableA_i=>responsePayloadWrite_i,
937
             addressA_i=>responsePayloadIndex_i,
938
             dataA_i=>responsePayload_i,
939
             clkB_i=>clk,
940
             enableB_i=>memoryEnable,
941
             addressB_i=>memoryAddress,
942
             dataB_o=>memoryDataRead);
943
 
944
end architecture;

powered by: WebSVN 2.1.0

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