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 45

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

powered by: WebSVN 2.1.0

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