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

Subversion Repositories rio

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

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

Line No. Rev Author Line
1 6 magro732
-------------------------------------------------------------------------------
2
-- 
3
-- RapidIO IP Library Core
4
-- 
5
-- This file is part of the RapidIO IP library project
6
-- http://www.opencores.org/cores/rio/
7
-- 
8
-- Description
9
-- Containing a bridge between a RapidIO network and a Wishbone bus. Packets
10 39 magro732
-- NWRITE, NWRITER and NREAD are currently supported.
11 6 magro732
-- 
12
-- To Do:
13 45 magro732
-- REMARK: Set the stb_o to '0' in between read accesses to conform better to a
14
-- block transfer in the Wishbone standard.
15
-- REMARK: Clean up cyc-signals, only stb-signals are needed (between
16
-- RioLogicalCommon and the packet handlers).
17
-- REMARK: Add support for the lock_o to be sure to transfer all the packet
18
-- content atomically?
19
-- REMARK: Add support for EXTENDED_ADDRESS.
20
-- REMARK: Use the baseDeviceId when sending packets? Currently, all responses
21
-- are sent with destination<->source exchanged so the baseDeviceId is not
22
-- needed.
23
-- REMARK: Support inbound data with full bandwidth, not just half, applies to
24
-- RioLogicalCommon and the packet handlers.
25
-- REMARK: Move the packet handlers to seperate files.
26
-- REMARK: Increase the priority of the response-packet when sent?
27
-- REMARK: Implement error indications if erronous packets are received.
28
-- REMARK: Implement error indications if err_i is received on the Wishbone bus.
29
-- REMARK: Add support for extended features to dynamically configure the status
30
-- from the port this block is connected to. Needed for the discovered- and
31
-- masterEnable-bits.
32
-- REMARK: Add support for outbound doorbells connected to interrupt input pins.
33 6 magro732
-- 
34
-- Author(s): 
35 39 magro732
-- - Magnus Rosenius, magro732@opencores.org
36 6 magro732
-- 
37
-------------------------------------------------------------------------------
38
-- 
39
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
40
-- 
41
-- This source file may be used and distributed without 
42
-- restriction provided that this copyright statement is not 
43
-- removed from the file and that any derivative work contains 
44
-- the original copyright notice and the associated disclaimer. 
45
-- 
46
-- This source file is free software; you can redistribute it 
47
-- and/or modify it under the terms of the GNU Lesser General 
48
-- Public License as published by the Free Software Foundation; 
49
-- either version 2.1 of the License, or (at your option) any 
50
-- later version. 
51
-- 
52
-- This source is distributed in the hope that it will be 
53
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
54
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
55
-- PURPOSE. See the GNU Lesser General Public License for more 
56
-- details. 
57
-- 
58
-- You should have received a copy of the GNU Lesser General 
59
-- Public License along with this source; if not, download it 
60
-- from http://www.opencores.org/lgpl.shtml 
61
-- 
62
-------------------------------------------------------------------------------
63
 
64 45 magro732
 
65 39 magro732
-------------------------------------------------------------------------------
66
-- RioWbBridge.
67 45 magro732
-- This block acts as an RapidIO endpoint and converts packets into Wishbone
68
-- accesses.
69 39 magro732
-------------------------------------------------------------------------------
70 6 magro732
library ieee;
71
use ieee.std_logic_1164.all;
72 42 magro732
use ieee.numeric_std.all;
73 6 magro732
use work.rio_common.all;
74
 
75
-------------------------------------------------------------------------------
76 39 magro732
-- Entity for RioWbBridge.
77 6 magro732
-------------------------------------------------------------------------------
78 39 magro732
entity RioWbBridge is
79 6 magro732
  generic(
80 39 magro732
    EXTENDED_ADDRESS : natural range 0 to 2 := 0;
81 6 magro732
    DEVICE_IDENTITY : std_logic_vector(15 downto 0);
82
    DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
83
    DEVICE_REV : std_logic_vector(31 downto 0);
84
    ASSY_IDENTITY : std_logic_vector(15 downto 0);
85
    ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
86 39 magro732
    ASSY_REV : std_logic_vector(15 downto 0));
87 6 magro732
  port(
88 39 magro732
    clk : in std_logic;
89
    areset_n : in std_logic;
90 44 magro732
    enable : in std_logic;
91 6 magro732
 
92
    readFrameEmpty_i : in std_logic;
93
    readFrame_o : out std_logic;
94
    readContent_o : out std_logic;
95
    readContentEnd_i : in std_logic;
96
    readContentData_i : in std_logic_vector(31 downto 0);
97
    writeFrameFull_i : in std_logic;
98
    writeFrame_o : out std_logic;
99
    writeFrameAbort_o : out std_logic;
100
    writeContent_o : out std_logic;
101
    writeContentData_o : out std_logic_vector(31 downto 0);
102
 
103 39 magro732
    cyc_o : out std_logic;
104
    stb_o : out std_logic;
105
    we_o : out std_logic;
106
    adr_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
107
    sel_o : out std_logic_vector(7 downto 0);
108
    dat_o : out std_logic_vector(63 downto 0);
109
    dat_i : in std_logic_vector(63 downto 0);
110
    err_i : in std_logic;
111
    ack_i : in std_logic);
112
end entity;
113 6 magro732
 
114 39 magro732
 
115 6 magro732
-------------------------------------------------------------------------------
116
-- Architecture for RioWbBridge.
117
-------------------------------------------------------------------------------
118 39 magro732
architecture RioWbBridgeImpl of RioWbBridge is
119 6 magro732
 
120 39 magro732
  component RequestClassInbound is
121
    generic(
122
      EXTENDED_ADDRESS : natural range 0 to 2 := 0);
123 6 magro732
    port(
124 39 magro732
      clk : in std_logic;
125
      areset_n : in std_logic;
126
      enable : in std_logic;
127
 
128
      ready_o : out std_logic;
129
      vc_o : out std_logic;
130
      crf_o : out std_logic;
131
      prio_o : out std_logic_vector(1 downto 0);
132
      tt_o : out std_logic_vector(1 downto 0);
133
      dstId_o : out std_logic_vector(31 downto 0);
134
      srcId_o : out std_logic_vector(31 downto 0);
135
      tid_o : out std_logic_vector(7 downto 0);
136
      address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
137 44 magro732
      length_o : out std_logic_vector(4 downto 0);
138 39 magro732
      select_o : out std_logic_vector(7 downto 0);
139
      done_i : in std_logic;
140
 
141 45 magro732
      inboundCyc_i : in std_logic;
142
      inboundStb_i : in std_logic;
143
      inboundAdr_i : in std_logic_vector(7 downto 0);
144
      inboundDat_i : in std_logic_vector(31 downto 0);
145
      inboundAck_o : out std_logic);
146 6 magro732
  end component;
147
 
148 39 magro732
  component WriteClassInbound is
149
    generic(
150
      EXTENDED_ADDRESS : natural range 0 to 2 := 0);
151
    port(
152
      clk : in std_logic;
153
      areset_n : in std_logic;
154
      enable : in std_logic;
155 6 magro732
 
156 39 magro732
      ready_o : out std_logic;
157 45 magro732
      responseNeeded_o : out std_logic;
158 39 magro732
      vc_o : out std_logic;
159
      crf_o : out std_logic;
160
      prio_o : out std_logic_vector(1 downto 0);
161
      tt_o : out std_logic_vector(1 downto 0);
162
      dstId_o : out std_logic_vector(31 downto 0);
163
      srcId_o : out std_logic_vector(31 downto 0);
164
      tid_o : out std_logic_vector(7 downto 0);
165
      address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
166 44 magro732
      length_o : out std_logic_vector(4 downto 0);
167 39 magro732
      select_o : out std_logic_vector(7 downto 0);
168 44 magro732
      payloadRead_i : in std_logic;
169
      payloadIndex_i : in std_logic_vector(4 downto 0);
170
      payload_o : out std_logic_vector(63 downto 0);
171 39 magro732
      done_i : in std_logic;
172
 
173 45 magro732
      inboundCyc_i : in std_logic;
174
      inboundStb_i : in std_logic;
175
      inboundAdr_i : in std_logic_vector(7 downto 0);
176
      inboundDat_i : in std_logic_vector(31 downto 0);
177
      inboundAck_o : out std_logic);
178 39 magro732
  end component;
179 6 magro732
 
180 39 magro732
  component ResponseClassOutbound is
181
    port(
182
      clk : in std_logic;
183
      areset_n : in std_logic;
184
      enable : in std_logic;
185 6 magro732
 
186 39 magro732
      ready_i : in std_logic;
187
      vc_i : in std_logic;
188
      crf_i : in std_logic;
189
      prio_i : in std_logic_vector(1 downto 0);
190
      tt_i : in std_logic_vector(1 downto 0);
191
      dstid_i : in std_logic_vector(31 downto 0);
192
      srcid_i : in std_logic_vector(31 downto 0);
193
      tid_i : in std_logic_vector(7 downto 0);
194
      error_i : in std_logic;
195
      payloadPresent_i :  in std_logic;
196 44 magro732
      payloadLength_i : in std_logic_vector(4 downto 0);
197 39 magro732
      payloadWrite_i : in std_logic;
198 44 magro732
      payloadIndex_i : in std_logic_vector(4 downto 0);
199
      payload_i : in std_logic_vector(63 downto 0);
200 39 magro732
      done_o : out std_logic;
201
 
202 45 magro732
      outboundCyc_o : out std_logic;
203
      outboundStb_o : out std_logic;
204
      outboundDat_o : out std_logic_vector(31 downto 0);
205
      outboundAck_i : in std_logic);
206 39 magro732
  end component;
207 6 magro732
 
208 45 magro732
  component RioLogicalMaintenance is
209
    port(
210
      clk : in std_logic;
211
      areset_n : in std_logic;
212
      enable : in std_logic;
213
 
214
      configStb_o : out std_logic;
215
      configWe_o : out std_logic;
216
      configAdr_o : out std_logic_vector(21 downto 0);
217
      configDat_o : out std_logic_vector(31 downto 0);
218
      configDat_i : in std_logic_vector(31 downto 0);
219
      configAck_i : in std_logic;
220
 
221
      inboundCyc_i : in std_logic;
222
      inboundStb_i : in std_logic;
223
      inboundAdr_i : in std_logic_vector(7 downto 0);
224
      inboundDat_i : in std_logic_vector(31 downto 0);
225
      inboundAck_o : out std_logic;
226
 
227
      outboundCyc_o : out std_logic;
228
      outboundStb_o : out std_logic;
229
      outboundDat_o : out std_logic_vector(31 downto 0);
230
      outboundAck_i : in std_logic);
231
  end component;
232
 
233 39 magro732
  component RioLogicalCommon is
234 45 magro732
    generic(
235
      PORTS : natural);
236 39 magro732
    port(
237
      clk : in std_logic;
238
      areset_n : in std_logic;
239
      enable : in std_logic;
240
 
241
      readFrameEmpty_i : in std_logic;
242
      readFrame_o : out std_logic;
243
      readContent_o : out std_logic;
244
      readContentEnd_i : in std_logic;
245
      readContentData_i : in std_logic_vector(31 downto 0);
246 6 magro732
 
247 39 magro732
      writeFrameFull_i : in std_logic;
248
      writeFrame_o : out std_logic;
249
      writeFrameAbort_o : out std_logic;
250
      writeContent_o : out std_logic;
251
      writeContentData_o : out std_logic_vector(31 downto 0);
252
 
253 45 magro732
      inboundCyc_o : out std_logic;
254
      inboundStb_o : out std_logic;
255
      inboundAdr_o : out std_logic_vector(7 downto 0);
256
      inboundDat_o : out std_logic_vector(31 downto 0);
257
      inboundAck_i : in std_logic;
258 39 magro732
 
259 45 magro732
      outboundCyc_i : in std_logic_vector(PORTS-1 downto 0);
260
      outboundStb_i : in std_logic_vector(PORTS-1 downto 0);
261
      outboundDat_i : in std_logic_vector(32*PORTS-1 downto 0);
262
      outboundAck_o : out std_logic_vector(PORTS-1 downto 0));
263 39 magro732
  end component;
264
 
265 45 magro732
  constant PORTS : natural := 2;
266
 
267 44 magro732
  type StateType is (IDLE,
268
                     REQUEST_CLASS, REQUEST_CLASS_RESPONSE,
269 45 magro732
                     WRITE_CLASS, WRITE_CLASS_ACCESS, WRITE_CLASS_ACK, WRITE_CLASS_RESPONSE);
270 44 magro732
  signal state : StateType;
271
 
272
  signal adr : std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
273
  signal datOut : std_logic_vector(63 downto 0);
274
 
275
  signal payloadUpdate : std_logic;
276
  signal payloadIndex : std_logic_vector(4 downto 0);
277
 
278
  signal requestReady : std_logic;
279
  signal requestVc : std_logic;
280
  signal requestCrf : std_logic;
281
  signal requestPrio : std_logic_vector(1 downto 0);
282
  signal requestTt : std_logic_vector(1 downto 0);
283
  signal requestDstId : std_logic_vector(31 downto 0);
284
  signal requestSrcId : std_logic_vector(31 downto 0);
285
  signal requestTid : std_logic_vector(7 downto 0);
286
  signal requestAddress : std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
287
  signal requestLength : std_logic_vector(4 downto 0);
288
  signal requestSelect : std_logic_vector(7 downto 0);
289
  signal requestDone : std_logic;
290
  signal requestAck : std_logic;
291
 
292
  signal writeReady : std_logic;
293 45 magro732
  signal writeResponse : std_logic;
294 44 magro732
  signal writeVc : std_logic;
295
  signal writeCrf : std_logic;
296
  signal writePrio : std_logic_vector(1 downto 0);
297
  signal writeTt : std_logic_vector(1 downto 0);
298
  signal writeDstId : std_logic_vector(31 downto 0);
299
  signal writeSrcId : std_logic_vector(31 downto 0);
300
  signal writeTid : std_logic_vector(7 downto 0);
301
  signal writeAddress : std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
302
  signal writeLength : std_logic_vector(4 downto 0);
303
  signal writeSelect : std_logic_vector(7 downto 0);
304
  signal writePayload : std_logic_vector(63 downto 0);
305
  signal writeDone : std_logic;
306
  signal writeAck : std_logic;
307
 
308
  signal responseReady : std_logic;
309
  signal responseVc : std_logic;
310
  signal responseCrf : std_logic;
311
  signal responsePrio : std_logic_vector(1 downto 0);
312
  signal responseTt : std_logic_vector(1 downto 0);
313
  signal responseDstId : std_logic_vector(31 downto 0);
314
  signal responseSrcId : std_logic_vector(31 downto 0);
315
  signal responseTid : std_logic_vector(7 downto 0);
316
  signal responseError : std_logic;
317
  signal responsePayloadPresent : std_logic;
318
  signal responsePayload : std_logic_vector(63 downto 0);
319
  signal responseDone : std_logic;
320
 
321 45 magro732
  signal configStb : std_logic;
322
  signal configWe : std_logic;
323
  signal configAdr : std_logic_vector(21 downto 0);
324
  signal configAdrByte : std_logic_vector(23 downto 0);
325
  signal configDatWrite : std_logic_vector(31 downto 0);
326
  signal configDatRead : std_logic_vector(31 downto 0);
327
  signal configAck : std_logic;
328
  signal maintenanceAck : std_logic;
329
 
330 44 magro732
  signal inboundCyc : std_logic;
331
  signal inboundStb : std_logic;
332
  signal inboundAdr : std_logic_vector(7 downto 0);
333
  signal inboundDat : std_logic_vector(31 downto 0);
334
  signal inboundAck : std_logic;
335
 
336 45 magro732
  signal outboundCyc : std_logic_vector(PORTS-1 downto 0);
337
  signal outboundStb : std_logic_vector(PORTS-1 downto 0);
338
  signal outboundDat : std_logic_vector(32*PORTS-1 downto 0);
339
  signal outboundAck : std_logic_vector(PORTS-1 downto 0);
340 39 magro732
 
341
begin
342
 
343 44 magro732
  responseVc <= requestVc when (responsePayloadPresent = '1') else writeVc;
344
  responseCrf <= requestCrf when (responsePayloadPresent = '1') else writeCrf;
345
  responsePrio <= requestPrio when (responsePayloadPresent = '1') else writePrio;
346
  responseTt <= requestTt when (responsePayloadPresent = '1') else writeTt;
347
  responseDstId <= requestSrcId when (responsePayloadPresent = '1') else writeSrcId;
348
  responseSrcId <= requestDstId when (responsePayloadPresent = '1') else writeDstId;
349
  responseTid <= requestTid when (responsePayloadPresent = '1') else writeTid;
350
 
351 6 magro732
  -----------------------------------------------------------------------------
352 39 magro732
  -- 
353 6 magro732
  -----------------------------------------------------------------------------
354 39 magro732
  adr_o <= adr;
355
  dat_o <= datOut;
356
 
357
  Bridge: process(clk, areset_n)
358 6 magro732
  begin
359 39 magro732
    if (areset_n = '0') then
360
      cyc_o <= '0';
361
      stb_o <= '0';
362
      we_o <= '0';
363
      adr <= (others=>'0');
364
      datOut <= (others=>'0');
365 6 magro732
 
366 44 magro732
      payloadUpdate <= '0';
367
      payloadIndex <= (others=>'0');
368
 
369 39 magro732
      requestDone <= '0';
370
 
371 44 magro732
      writeDone <= '0';
372
 
373
      responseReady <= '0';
374
      responseError <= '0';
375
      responsePayloadPresent <= '0';
376
      responsePayload <= (others=>'0');
377 39 magro732
    elsif (clk'event and clk = '1') then
378 44 magro732
      if (enable = '1') then
379
        requestDone <= '0';
380
        writeDone <= '0';
381
        responseReady <= '0';
382
 
383
        payloadUpdate <= '0';
384
        if (payloadUpdate = '1') then
385
          payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
386
        end if;
387
 
388
        case state is
389
          when IDLE =>
390
            ---------------------------------------------------------------------
391
            -- 
392
            ---------------------------------------------------------------------
393
            if (requestReady = '1') then
394
              cyc_o <= '1';
395
              stb_o <= '1';
396
              we_o <= '0';
397
              adr <= requestAddress;
398
              sel_o <= requestSelect;
399
 
400
              payloadIndex <= (others=>'0');
401
 
402
              responsePayloadPresent <= '1';
403
              state <= REQUEST_CLASS;
404
            elsif (writeReady = '1') then
405
              adr <= writeAddress;
406 39 magro732
 
407 44 magro732
              payloadUpdate <= '1';
408
              payloadIndex <= (others=>'0');
409
 
410
              responsePayloadPresent <= '0';
411
              state <= WRITE_CLASS;
412
            end if;
413 39 magro732
 
414 44 magro732
          when REQUEST_CLASS =>
415
            ---------------------------------------------------------------------
416
            -- 
417
            ---------------------------------------------------------------------
418
            if (ack_i = '1') then
419
              -- Note that responsePayloadIndex is updated after the write has been made.
420
              payloadUpdate <= '1';
421
              responsePayload <= dat_i;
422
 
423 39 magro732
              adr <= std_logic_vector(unsigned(adr) + 1);
424 44 magro732
 
425
              if (payloadIndex = requestLength) then
426
                requestDone <= '1';
427
                cyc_o <= '0';
428
                stb_o <= '0';
429
                state <= REQUEST_CLASS_RESPONSE;
430
              end if;
431 39 magro732
--          elsif(err_i = '1') then
432
--            REMARK: Implement error indication from wb-bus...
433 44 magro732
            end if;
434 39 magro732
 
435 44 magro732
          when REQUEST_CLASS_RESPONSE =>
436
            ---------------------------------------------------------------------
437
            -- 
438
            ---------------------------------------------------------------------
439
            if (responseDone = '1') then
440
              responseReady <= '0';
441
              state <= IDLE;
442
            else
443
              responseReady <= '1';
444
            end if;
445 6 magro732
 
446 44 magro732
          when WRITE_CLASS =>
447
            ---------------------------------------------------------------------
448
            -- 
449
            ---------------------------------------------------------------------
450 45 magro732
            state <= WRITE_CLASS_ACCESS;
451
 
452
          when WRITE_CLASS_ACCESS =>
453
            ---------------------------------------------------------------------
454
            -- 
455
            ---------------------------------------------------------------------
456
            cyc_o <= '1';
457
            stb_o <= '1';
458
            we_o <= '1';
459
            sel_o <= writeSelect;
460
            datOut <= writePayload;
461
            payloadUpdate <= '1';
462
 
463
            state <= WRITE_CLASS_ACK;
464
 
465
          when WRITE_CLASS_ACK =>
466
            ---------------------------------------------------------------------
467
            -- 
468
            ---------------------------------------------------------------------
469 44 magro732
            if (ack_i = '1') then
470
              adr <= std_logic_vector(unsigned(adr) + 1);
471
 
472 45 magro732
              if (unsigned(payloadIndex) /= (unsigned(writeLength)+2)) then
473
                stb_o <= '0';
474
                state <= WRITE_CLASS_ACCESS;
475 44 magro732
              else
476
                writeDone <= '1';
477
                cyc_o <= '0';
478
                stb_o <= '0';
479
                state <= WRITE_CLASS_RESPONSE;
480
              end if;
481
            end if;
482
 
483
          when WRITE_CLASS_RESPONSE =>
484
            ---------------------------------------------------------------------
485
            -- 
486
            ---------------------------------------------------------------------
487 45 magro732
            if (responseDone = '1') or (writeResponse = '0') then
488 44 magro732
              responseReady <= '0';
489
              state <= IDLE;
490 39 magro732
            else
491 44 magro732
              responseReady <= '1';
492 39 magro732
            end if;
493 6 magro732
 
494 44 magro732
          when others =>
495 6 magro732
 
496 44 magro732
        end case;
497
      end if;
498 39 magro732
    end if;
499
  end process;
500
 
501
  -----------------------------------------------------------------------------
502 45 magro732
  -- Packet handlers.
503 39 magro732
  -----------------------------------------------------------------------------
504 6 magro732
 
505 39 magro732
  RequestClassInboundInst: RequestClassInbound
506
    generic map(
507
      EXTENDED_ADDRESS=>EXTENDED_ADDRESS)
508
    port map(
509
      clk=>clk,
510
      areset_n=>areset_n,
511
      enable=>enable,
512
      ready_o=>requestReady,
513
      vc_o=>requestVc,
514
      crf_o=>requestCrf,
515
      prio_o=>requestPrio,
516
      tt_o=>requestTt,
517
      dstId_o=>requestDstId,
518
      srcId_o=>requestSrcId,
519
      tid_o=>requestTid,
520
      address_o=>requestAddress,
521 44 magro732
      length_o=>requestLength,
522 39 magro732
      select_o=>requestSelect,
523
      done_i=>requestDone,
524 45 magro732
      inboundCyc_i=>inboundCyc,
525
      inboundStb_i=>inboundStb,
526
      inboundAdr_i=>inboundAdr,
527
      inboundDat_i=>inboundDat,
528
      inboundAck_o=>requestAck);
529 6 magro732
 
530 39 magro732
  WriteClassInboundInst: WriteClassInbound
531
    generic map(
532
      EXTENDED_ADDRESS=>EXTENDED_ADDRESS)
533
    port map(
534
      clk=>clk,
535
      areset_n=>areset_n,
536
      enable=>enable,
537
      ready_o=>writeReady,
538 45 magro732
      responseNeeded_o=>writeResponse,
539 39 magro732
      vc_o=>writeVc,
540
      crf_o=>writeCrf,
541
      prio_o=>writePrio,
542
      tt_o=>writeTt,
543
      dstId_o=>writeDstId,
544
      srcId_o=>writeSrcId,
545
      tid_o=>writeTid,
546
      address_o=>writeAddress,
547
      length_o=>writeLength,
548
      select_o=>writeSelect,
549 44 magro732
      payloadRead_i=>payloadUpdate,
550
      payloadIndex_i=>payloadIndex,
551 39 magro732
      payload_o=>writePayload,
552
      done_i=>writeDone,
553 45 magro732
      inboundCyc_i=>inboundCyc,
554
      inboundStb_i=>inboundStb,
555
      inboundAdr_i=>inboundAdr,
556
      inboundDat_i=>inboundDat,
557
      inboundAck_o=>writeAck);
558 6 magro732
 
559 39 magro732
  ResponseClassOutboundInst: ResponseClassOutbound
560
    port map(
561
      clk=>clk,
562
      areset_n=>areset_n,
563
      enable=>enable,
564
      ready_i=>responseReady,
565 44 magro732
      vc_i=>responseVc,
566
      crf_i=>responseCrf,
567
      prio_i=>responsePrio,
568
      tt_i=>responseTt,
569
      dstid_i=>responseDstId,
570
      srcid_i=>responseSrcId,
571
      tid_i=>responseTid,
572 39 magro732
      error_i=>responseError,
573
      payloadPresent_i=>responsePayloadPresent,
574 44 magro732
      payloadLength_i=>requestLength,
575
      payloadWrite_i=>payloadUpdate,
576
      payloadIndex_i=>payloadIndex,
577 39 magro732
      payload_i=>responsePayload,
578
      done_o=>responseDone,
579 45 magro732
      outboundCyc_o=>outboundCyc(0),
580
      outboundStb_o=>outboundStb(0),
581
      outboundDat_o=>outboundDat(31 downto 0),
582
      outboundAck_i=>outboundAck(0));
583 44 magro732
 
584 45 magro732
  -- Maintenance packet processing.
585
  MaintenanceInst: RioLogicalMaintenance
586
    port map(
587
      clk=>clk,
588
      areset_n=>areset_n,
589
      enable=>enable,
590
      configStb_o=>configStb,
591
      configWe_o=>configWe,
592
      configAdr_o=>configAdr,
593
      configDat_o=>configDatWrite,
594
      configDat_i=>configDatRead,
595
      configAck_i=>configAck,
596
      inboundCyc_i=>inboundCyc,
597
      inboundStb_i=>inboundStb,
598
      inboundAdr_i=>inboundAdr,
599
      inboundDat_i=>inboundDat,
600
      inboundAck_o=>maintenanceAck,
601
      outboundCyc_o=>outboundCyc(1),
602
      outboundStb_o=>outboundStb(1),
603
      outboundDat_o=>outboundDat(63 downto 32),
604
      outboundAck_i=>outboundAck(1));
605
 
606
  -----------------------------------------------------------------------------
607
  -- Common interface toward the packet queues.
608
  -----------------------------------------------------------------------------
609
 
610
  inboundAck <= requestAck or writeAck or maintenanceAck;
611 39 magro732
  RioLogicalCommonInst: RioLogicalCommon
612 45 magro732
    generic map(PORTS=>PORTS)
613 39 magro732
    port map(
614
      clk=>clk,
615
      areset_n=>areset_n,
616
      enable=>enable,
617
      readFrameEmpty_i=>readFrameEmpty_i,
618
      readFrame_o=>readFrame_o,
619
      readContent_o=>readContent_o,
620
      readContentEnd_i=>readContentEnd_i,
621
      readContentData_i=>readContentData_i,
622
      writeFrameFull_i=>writeFrameFull_i,
623
      writeFrame_o=>writeFrame_o,
624
      writeFrameAbort_o=>writeFrameAbort_o,
625
      writeContent_o=>writeContent_o,
626
      writeContentData_o=>writeContentData_o,
627 45 magro732
      inboundCyc_o=>inboundCyc,
628
      inboundStb_o=>inboundStb,
629
      inboundAdr_o=>inboundAdr,
630
      inboundDat_o=>inboundDat,
631
      inboundAck_i=>inboundAck,
632
      outboundCyc_i=>outboundCyc,
633
      outboundStb_i=>outboundStb,
634
      outboundDat_i=>outboundDat,
635
      outboundAck_o=>outboundAck);
636 6 magro732
 
637 39 magro732
  -----------------------------------------------------------------------------
638
  -- Configuration memory.
639
  -----------------------------------------------------------------------------
640 45 magro732
  configAdrByte <= configAdr & "00";
641
  memoryConfig : process(clk, areset_n)
642
    variable componentTag : std_logic_vector(31 downto 0);
643
    variable hostBaseDeviceIdLocked : std_logic;
644
    variable hostBaseDeviceId : std_logic_vector(15 downto 0);
645
  begin
646
    if (areset_n = '0') then
647
      componentTag := (others => '0');
648
      hostBaseDeviceIdLocked := '0';
649
      hostBaseDeviceId := (others => '1');
650 6 magro732
 
651 45 magro732
      configDatRead <= (others => '0');
652
      configAck <= '0';
653
    elsif (clk'event and clk = '1') then
654
      if (configAck = '0') then
655
        if (configStb = '1') then
656
          configAck <= '1';
657
          configDatRead <= (others=>'0');
658
 
659
          -- Check the address the access is for.
660
          case (configAdrByte) is
661
            when x"000000" =>
662
              -----------------------------------------------------------------
663
              -- Device Identity CAR. Read-only.
664
              -----------------------------------------------------------------
665
              configDatRead(31 downto 16) <= DEVICE_IDENTITY;
666
              configDatRead(15 downto 0) <= DEVICE_VENDOR_IDENTITY;
667
 
668
            when x"000004" =>
669
              -----------------------------------------------------------------
670
              -- Device Information CAR. Read-only.
671
              -----------------------------------------------------------------
672
              configDatRead(31 downto 0) <= DEVICE_REV;
673
 
674
            when x"000008" =>
675
              -----------------------------------------------------------------
676
              -- Assembly Identity CAR. Read-only.
677
              -----------------------------------------------------------------
678
              configDatRead(31 downto 16) <= ASSY_IDENTITY;
679
              configDatRead(15 downto 0) <= ASSY_VENDOR_IDENTITY;
680
 
681
            when x"00000c" =>
682
              -----------------------------------------------------------------
683
              -- Assembly Information CAR. Read-only.
684
              -----------------------------------------------------------------
685
              configDatRead(31 downto 16) <= ASSY_REV;
686
 
687
            when x"000010" =>
688
              -----------------------------------------------------------------
689
              -- Processing Element Features CAR. Read-only.
690
              -----------------------------------------------------------------
691
              -- Bridge.
692
              configDatRead(31) <= '1';
693
              -- Extended addressing support, 34-bit addresses.
694
              configDatRead(2 downto 0) <= "001";
695
 
696
            when x"000018" =>
697
              -----------------------------------------------------------------
698
              -- Source Operations CAR. Read-only.
699
              -----------------------------------------------------------------
700
              -- Cannot act as a source of any packets.
701
 
702
            when x"00001c" =>
703
              -----------------------------------------------------------------
704
              -- Destination Operations CAR. Read-only.
705
              -----------------------------------------------------------------
706
              -- Read, supported.
707
              configDatRead(15) <= '1';
708
              -- Write, supported.
709
              configDatRead(14) <= '1';
710
              -- Write-with-response, supported.
711
              configDatRead(12) <= '1';
712
 
713
            when x"00004c" =>
714
              -----------------------------------------------------------------
715
              -- Processing Element Logical Layer Control CSR.
716
              -----------------------------------------------------------------
717
              -- Extended addressing control, PE supports 34 bits addresses.
718
              configDatRead(2 downto 0) <= "001";
719 6 magro732
 
720 45 magro732
            when x"000060" =>
721
              -----------------------------------------------------------------
722
              -- Base Device ID CSR.
723
              -----------------------------------------------------------------
724
              -- This is not used since this endpoint only replies to packets
725
              -- and it can then use the destination deviceId as a source.
726
 
727
            when x"000068" =>
728
              -----------------------------------------------------------------
729
              -- Host Base Device ID Lock CSR.
730
              -----------------------------------------------------------------
731 6 magro732
 
732 45 magro732
              -- Check if writing.
733
              if (configWe = '1') then
734
                -- Write access.
735
 
736
                -- Check if this field has been written before.
737
                if (hostBaseDeviceIdLocked = '0') then
738
                  -- The field has not been written.
739
                  -- Lock the field and set the host base device id.
740
                  hostBaseDeviceIdLocked := '1';
741
                  hostBaseDeviceId := configDatWrite(15 downto 0);
742
                else
743
                  -- The field has been written.
744
                  -- Check if the written data is the same as the stored.
745
                  if (hostBaseDeviceId = configDatWrite(15 downto 0)) then
746
                    -- Same as stored, reset the value to its initial value.
747
                    hostBaseDeviceIdLocked := '0';
748
                    hostBaseDeviceId := (others => '1');
749
                  else
750
                    -- Not writing the same as the stored value.
751
                    -- Ignore the write.
752
                  end if;
753
                end if;
754
              end if;
755
 
756
              configDatRead(15 downto 0) <= hostBaseDeviceId;
757
 
758
            when x"00006C" =>
759
              -----------------------------------------------------------------
760
              -- Component TAG CSR.
761
              -----------------------------------------------------------------
762
              if (configWe = '1') then
763
                componentTag := configDatWrite;
764
              end if;
765
 
766
              configDatRead <= componentTag;
767
 
768
            when others =>
769
              -----------------------------------------------------------------
770
              -- Other access.
771
              -----------------------------------------------------------------
772
              -- Respond with all zeros.
773
              configDatRead <= (others => '0');
774
          end case;
775
        end if;
776
      else
777
        configAck <= '0';
778
      end if;
779
    end if;
780
  end process;
781
 
782 39 magro732
end architecture;
783 6 magro732
 
784
 
785 39 magro732
-------------------------------------------------------------------------------
786
-- 
787
-------------------------------------------------------------------------------
788
-- REMARK: Extended addresses are not supported yet...
789
library ieee;
790
use ieee.std_logic_1164.all;
791
use ieee.numeric_std.all;
792
use work.rio_common.all;
793 6 magro732
 
794
 
795 39 magro732
-------------------------------------------------------------------------------
796
-- 
797
-------------------------------------------------------------------------------
798
entity RequestClassInbound is
799
  generic(
800
    EXTENDED_ADDRESS : natural range 0 to 2 := 0);
801
  port(
802
    clk : in std_logic;
803
    areset_n : in std_logic;
804
    enable : in std_logic;
805 6 magro732
 
806 39 magro732
    ready_o : out std_logic;
807
    vc_o : out std_logic;
808
    crf_o : out std_logic;
809
    prio_o : out std_logic_vector(1 downto 0);
810
    tt_o : out std_logic_vector(1 downto 0);
811
    dstId_o : out std_logic_vector(31 downto 0);
812
    srcId_o : out std_logic_vector(31 downto 0);
813
    tid_o : out std_logic_vector(7 downto 0);
814
    address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
815 44 magro732
    length_o : out std_logic_vector(4 downto 0);
816 39 magro732
    select_o : out std_logic_vector(7 downto 0);
817
    done_i : in std_logic;
818
 
819 45 magro732
    inboundCyc_i : in std_logic;
820
    inboundStb_i : in std_logic;
821
    inboundAdr_i : in std_logic_vector(7 downto 0);
822
    inboundDat_i : in std_logic_vector(31 downto 0);
823
    inboundAck_o : out std_logic);
824 39 magro732
end entity;
825
 
826
 
827
-------------------------------------------------------------------------------
828
-- 
829
-------------------------------------------------------------------------------
830
architecture RequestClassInbound of RequestClassInbound is
831
  type StateType is (RECEIVE_PACKET, READY);
832
  signal state : StateType;
833
 
834
  signal rdsize : std_logic_vector(3 downto 0);
835
  signal wdptr : std_logic;
836
 
837 45 magro732
  signal inboundAck : std_logic;
838 39 magro732
  signal complete : std_logic;
839
 
840 45 magro732
  signal packetIndex : natural range 0 to 69;
841 39 magro732
 
842
begin
843
 
844 45 magro732
  inboundAck_o <= inboundAck;
845 39 magro732
 
846
  ready_o <= complete when (state = READY) else '0';
847
 
848
  RequestClass: process(clk, areset_n)
849
  begin
850
    if (areset_n = '0') then
851 44 magro732
      state <= RECEIVE_PACKET;
852
 
853
      rdsize <= (others=>'0');
854
      wdptr <= '0';
855
 
856 45 magro732
      inboundAck <= '0';
857 39 magro732
      complete <= '0';
858
 
859 44 magro732
      packetIndex <= 0;
860
 
861 39 magro732
      vc_o <= '0';
862
      crf_o <= '0';
863
      prio_o <= "00";
864
      tt_o <= "00";
865 44 magro732
      dstId_o <= (others=>'0');
866
      srcId_o <= (others=>'0');
867
      tid_o <= (others=>'0');
868 39 magro732
      address_o <= (others=>'0');
869
    elsif (clk'event and clk = '1') then
870
      case state is
871
        when RECEIVE_PACKET =>
872
          ---------------------------------------------------------------------
873
          -- This state waits for a new REQUEST class packet, receives it
874
          -- and parses it.
875
          ---------------------------------------------------------------------
876 45 magro732
          if (inboundCyc_i = '1') then
877
            if (inboundAck = '0') then
878
              if (inboundStb_i = '1') then
879
                if (inboundAdr_i = x"24") then
880 39 magro732
                  -------------------------------------------------------------
881
                  -- NREAD packet parser.
882
                  -------------------------------------------------------------
883
                  case (packetIndex) is
884
                    when 0 =>
885
                      -- x"0000" & ackid & vc & crf & prio & tt & ftype
886 45 magro732
                      vc_o <= inboundDat_i(9);
887
                      crf_o <= inboundDat_i(8);
888
                      prio_o <= inboundDat_i(7 downto 6);
889
                      tt_o <= inboundDat_i(5 downto 4);
890 39 magro732
                      packetIndex <= packetIndex + 1;
891
                    when 1 =>
892
                      -- dstid
893 45 magro732
                      dstId_o <= inboundDat_i;
894 39 magro732
                      packetIndex <= packetIndex + 1;
895
                    when 2 =>
896
                      -- srcid
897 45 magro732
                      srcId_o <= inboundDat_i;
898 39 magro732
                      packetIndex <= packetIndex + 1;
899
                    when 3 =>
900
                      -- transaction(3:0) & rdsize(3:0) & srcTID(7:0) & address(28:13)
901 45 magro732
                      rdsize <= inboundDat_i(27 downto 24);
902
                      tid_o <= inboundDat_i(23 downto 16);
903
                      address_o(28 downto 13) <= inboundDat_i(15 downto 0);
904 39 magro732
                      packetIndex <= packetIndex + 1;
905
                    when 4 =>
906
                      -- address(12:0) & wdptr & xamsbs(1:0) & crc(15:0)
907 45 magro732
                      address_o(12 downto 0) <= inboundDat_i(31 downto 19);
908
                      wdptr <= inboundDat_i(18);
909
                      address_o(30 downto 29) <= inboundDat_i(17 downto 16);
910 39 magro732
                      packetIndex <= packetIndex + 1;
911
                      complete <= '1';
912
                    when others =>
913
                      -- There should be no more content in an NREAD.
914
                      -- Discard.
915
                  end case;
916 45 magro732
                  inboundAck <= '1';
917 6 magro732
                end if;
918
              end if;
919
            else
920 45 magro732
              inboundAck <= '0';
921 6 magro732
            end if;
922
          else
923 39 magro732
            if (complete = '1') then
924
              state <= READY;
925 6 magro732
            end if;
926 39 magro732
            packetIndex <= 0;
927 6 magro732
          end if;
928
 
929 39 magro732
        when READY =>
930
          ---------------------------------------------------------------------
931
          -- Wait for the handler of the packet to signal that it has been
932
          -- processed.
933
          ---------------------------------------------------------------------
934
          if (done_i = '1') then
935
            complete <= '0';
936
            state <= RECEIVE_PACKET;
937 6 magro732
          end if;
938
 
939 39 magro732
        when others =>
940
          ---------------------------------------------------------------------
941
          -- 
942
          ---------------------------------------------------------------------
943 6 magro732
 
944 39 magro732
      end case;
945
    end if;
946
  end process;
947
 
948
  -----------------------------------------------------------------------------
949
  -- Transformation of rdsize and wdptr into length of access and byte lanes.
950
  -----------------------------------------------------------------------------
951
 
952
  process(clk, areset_n)
953
  begin
954
    if (areset_n = '0') then
955 44 magro732
      length_o <= "00000";
956 39 magro732
      select_o <= (others=>'0');
957
    elsif (clk'event and clk = '1') then
958
      if (complete = '1') then
959
        if (wdptr = '0') then
960
          case rdsize is
961
            when "0000" =>
962 44 magro732
              length_o <= "00000";
963 39 magro732
              select_o <= "10000000";
964
            when "0001" =>
965 44 magro732
              length_o <= "00000";
966 39 magro732
              select_o <= "01000000";
967
            when "0010" =>
968 44 magro732
              length_o <= "00000";
969 39 magro732
              select_o <= "00100000";
970
            when "0011" =>
971 44 magro732
              length_o <= "00000";
972 39 magro732
              select_o <= "00010000";
973
            when "0100" =>
974 44 magro732
              length_o <= "00000";
975 39 magro732
              select_o <= "11000000";
976
            when "0101" =>
977 44 magro732
              length_o <= "00000";
978 39 magro732
              select_o <= "11100000";
979
            when "0110" =>
980 44 magro732
              length_o <= "00000";
981 39 magro732
              select_o <= "00110000";
982
            when "0111" =>
983 44 magro732
              length_o <= "00000";
984 39 magro732
              select_o <= "11111000";
985
            when "1000" =>
986 44 magro732
              length_o <= "00000";
987 39 magro732
              select_o <= "11110000";
988
            when "1001" =>
989 44 magro732
              length_o <= "00000";
990 39 magro732
              select_o <= "11111100";
991
            when "1010" =>
992 44 magro732
              length_o <= "00000";
993 39 magro732
              select_o <= "11111110";
994
            when "1011" =>
995 44 magro732
              length_o <= "00000";
996 39 magro732
              select_o <= "11111111";
997
            when "1100" =>
998 44 magro732
              length_o <= "00011";
999 39 magro732
              select_o <= "11111111";
1000
            when "1101" =>
1001 44 magro732
              length_o <= "01011";
1002 39 magro732
              select_o <= "11111111";
1003
            when "1110" =>
1004 44 magro732
              length_o <= "10011";
1005 39 magro732
              select_o <= "11111111";
1006
            when others =>
1007 44 magro732
              length_o <= "11011";
1008 39 magro732
              select_o <= "11111111";
1009
          end case;
1010
        else
1011
          case rdsize is
1012
            when "0000" =>
1013 44 magro732
              length_o <= "00000";
1014 39 magro732
              select_o <= "00001000";
1015
            when "0001" =>
1016 44 magro732
              length_o <= "00000";
1017 39 magro732
              select_o <= "00000100";
1018
            when "0010" =>
1019 44 magro732
              length_o <= "00000";
1020 39 magro732
              select_o <= "00000010";
1021
            when "0011" =>
1022 44 magro732
              length_o <= "00000";
1023 39 magro732
              select_o <= "00000001";
1024
            when "0100" =>
1025 44 magro732
              length_o <= "00000";
1026 39 magro732
              select_o <= "00001100";
1027
            when "0101" =>
1028 44 magro732
              length_o <= "00000";
1029 39 magro732
              select_o <= "00000111";
1030
            when "0110" =>
1031 44 magro732
              length_o <= "00000";
1032 39 magro732
              select_o <= "00000011";
1033
            when "0111" =>
1034 44 magro732
              length_o <= "00000";
1035 39 magro732
              select_o <= "00011111";
1036
            when "1000" =>
1037 44 magro732
              length_o <= "00000";
1038 39 magro732
              select_o <= "00001111";
1039
            when "1001" =>
1040 44 magro732
              length_o <= "00000";
1041 39 magro732
              select_o <= "00111111";
1042
            when "1010" =>
1043 44 magro732
              length_o <= "00000";
1044 39 magro732
              select_o <= "01111111";
1045
            when "1011" =>
1046 44 magro732
              length_o <= "00001";
1047 39 magro732
              select_o <= "11111111";
1048
            when "1100" =>
1049 44 magro732
              length_o <= "00111";
1050 39 magro732
              select_o <= "11111111";
1051
            when "1101" =>
1052 44 magro732
              length_o <= "01111";
1053 39 magro732
              select_o <= "11111111";
1054
            when "1110" =>
1055 44 magro732
              length_o <= "10111";
1056 39 magro732
              select_o <= "11111111";
1057
            when others =>
1058 44 magro732
              length_o <= "11111";
1059 39 magro732
              select_o <= "11111111";
1060
          end case;
1061
        end if;
1062
      end if;
1063
    end if;
1064
  end process;
1065
 
1066
end architecture;
1067
 
1068
 
1069
-------------------------------------------------------------------------------
1070
-- 
1071
-------------------------------------------------------------------------------
1072
library ieee;
1073
use ieee.std_logic_1164.all;
1074
use ieee.numeric_std.all;
1075
use work.rio_common.all;
1076
 
1077
 
1078
-------------------------------------------------------------------------------
1079
-- 
1080
-------------------------------------------------------------------------------
1081
entity WriteClassInbound is
1082
  generic(
1083
    EXTENDED_ADDRESS : natural range 0 to 2 := 0);
1084
  port(
1085
    clk : in std_logic;
1086
    areset_n : in std_logic;
1087
    enable : in std_logic;
1088
 
1089
    ready_o : out std_logic;
1090 45 magro732
    responseNeeded_o : out std_logic;
1091 39 magro732
    vc_o : out std_logic;
1092
    crf_o : out std_logic;
1093
    prio_o : out std_logic_vector(1 downto 0);
1094
    tt_o : out std_logic_vector(1 downto 0);
1095
    dstId_o : out std_logic_vector(31 downto 0);
1096
    srcId_o : out std_logic_vector(31 downto 0);
1097
    tid_o : out std_logic_vector(7 downto 0);
1098
    address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
1099 44 magro732
    length_o : out std_logic_vector(4 downto 0);
1100 39 magro732
    select_o : out std_logic_vector(7 downto 0);
1101 44 magro732
    payloadRead_i : in std_logic;
1102
    payloadIndex_i : in std_logic_vector(4 downto 0);
1103
    payload_o : out std_logic_vector(63 downto 0);
1104 39 magro732
    done_i : in std_logic;
1105
 
1106 45 magro732
    inboundCyc_i : in std_logic;
1107
    inboundStb_i : in std_logic;
1108
    inboundAdr_i : in std_logic_vector(7 downto 0);
1109
    inboundDat_i : in std_logic_vector(31 downto 0);
1110
    inboundAck_o : out std_logic);
1111 39 magro732
end entity;
1112
 
1113
 
1114
-------------------------------------------------------------------------------
1115
-- 
1116
-------------------------------------------------------------------------------
1117
architecture WriteClassInbound of WriteClassInbound is
1118
  component MemorySimpleDualPort
1119
    generic(
1120
      ADDRESS_WIDTH : natural := 1;
1121
      DATA_WIDTH : natural := 1);
1122
    port(
1123
      clkA_i : in std_logic;
1124
      enableA_i : in std_logic;
1125
      addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
1126
      dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
1127
 
1128
      clkB_i : in std_logic;
1129
      enableB_i : in std_logic;
1130
      addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
1131
      dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
1132
  end component;
1133
 
1134
  type StateType is (RECEIVE_PACKET, READY);
1135
  signal state : StateType;
1136
 
1137
  signal wdptr : std_logic;
1138
  signal wrsize : std_logic_vector(3 downto 0);
1139
 
1140 45 magro732
  signal inboundAck : std_logic;
1141 39 magro732
  signal complete : std_logic;
1142
 
1143 45 magro732
  signal packetIndex : natural range 0 to 69;
1144 39 magro732
 
1145 44 magro732
  signal doubleWord : std_logic_vector(63 downto 16);
1146
 
1147 39 magro732
  signal memoryWrite : std_logic;
1148
  signal memoryAddress : std_logic_vector(4 downto 0);
1149
  signal memoryDataIn : std_logic_vector(63 downto 0);
1150
 
1151 44 magro732
 
1152 39 magro732
begin
1153
 
1154 45 magro732
  inboundAck_o <= inboundAck;
1155 39 magro732
 
1156
  ready_o <= complete when (state = READY) else '0';
1157
 
1158
  WriteClass: process(clk, areset_n)
1159
  begin
1160
    if (areset_n = '0') then
1161 44 magro732
      state <= RECEIVE_PACKET;
1162
 
1163
      wdptr <= '0';
1164
      wrsize <= (others=>'0');
1165
 
1166 45 magro732
      inboundAck <= '0';
1167 39 magro732
      complete <= '0';
1168 45 magro732
      responseNeeded_o <= '0';
1169 39 magro732
 
1170 44 magro732
      packetIndex <= 0;
1171
      doubleWord <= (others=>'0');
1172
 
1173
      memoryWrite <= '0';
1174
      memoryAddress <= (others=>'0');
1175
      memoryDataIn <= (others=>'0');
1176
 
1177 39 magro732
      vc_o <= '0';
1178
      crf_o <= '0';
1179
      prio_o <= "00";
1180
      tt_o <= "00";
1181 44 magro732
      dstId_o <= (others=>'0');
1182
      srcId_o <= (others=>'0');
1183 39 magro732
      tid_o <= (others=>'0');
1184
      address_o <= (others=>'0');
1185
    elsif (clk'event and clk = '1') then
1186
      case state is
1187
        when RECEIVE_PACKET =>
1188 45 magro732
          if (inboundCyc_i = '1') then
1189
            if (inboundAck = '0') then
1190
              if (inboundStb_i = '1') then
1191
                if ((inboundAdr_i = x"55") or (inboundAdr_i = x"54")) then
1192 39 magro732
                  -------------------------------------------------------------
1193 45 magro732
                  -- NWRITE/NWRITER packet parser.
1194 39 magro732
                  -------------------------------------------------------------
1195
                  case (packetIndex) is
1196
                    when 0 =>
1197
                      -- x"0000" & ackid & vc & crf & prio & tt & ftype
1198 45 magro732
                      vc_o <= inboundDat_i(9);
1199
                      crf_o <= inboundDat_i(8);
1200
                      prio_o <= inboundDat_i(7 downto 6);
1201
                      tt_o <= inboundDat_i(5 downto 4);
1202 39 magro732
                      packetIndex <= packetIndex + 1;
1203
                    when 1 =>
1204
                      -- destId
1205 45 magro732
                      dstId_o <= inboundDat_i;
1206 39 magro732
                      packetIndex <= packetIndex + 1;
1207
                    when 2 =>
1208
                      -- srcId
1209 45 magro732
                      srcId_o <= inboundDat_i;
1210 39 magro732
                      packetIndex <= packetIndex + 1;
1211
                    when 3 =>
1212
                      -- transaction & wrsize & srcTID & address(28:13)
1213
                      -- REMARK: Add support for extended addresses here...
1214 45 magro732
                      if (inboundDat_i(31 downto 28) = "0101") then
1215
                        responseNeeded_o <= '1';
1216
                      else
1217
                        responseNeeded_o <= '0';
1218
                      end if;
1219
                      wrsize <= inboundDat_i(27 downto 24);
1220
                      tid_o <= inboundDat_i(23 downto 16);
1221
                      address_o(28 downto 13) <= inboundDat_i(15 downto 0);
1222 39 magro732
                      packetIndex <= packetIndex + 1;
1223
                    when 4 =>
1224
                      -- address(12:0) & wdptr & xamsbs(1:0) & double-word(63:48)
1225 45 magro732
                      address_o(12 downto 0) <= inboundDat_i(31 downto 19);
1226
                      wdptr <= inboundDat_i(18);
1227
                      address_o(30 downto 29) <= inboundDat_i(17 downto 16);
1228
                      doubleWord(63 downto 48) <= inboundDat_i(15 downto 0);
1229 39 magro732
                      packetIndex <= packetIndex + 1;
1230
                    when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31  | 33 | 35 |
1231
                      37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 59 | 61 | 63 | 65 | 67 =>
1232
                      -- double-word(47:16)
1233 45 magro732
                      doubleWord(47 downto 16) <= inboundDat_i;
1234 39 magro732
                      packetIndex <= packetIndex + 1;
1235
                    when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32  | 34 |
1236 45 magro732
                      36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 | 68 =>
1237 39 magro732
                      -- double-word(15:0) & double-word(63:48)
1238 45 magro732
                      doubleWord(63 downto 48) <= inboundDat_i(15 downto 0);
1239 39 magro732
                      packetIndex <= packetIndex + 1;
1240
 
1241
                      memoryWrite <= '1';
1242 45 magro732
                      memoryDataIn <= doubleWord(63 downto 16) & inboundDat_i(31 downto 16);
1243 39 magro732
                    when others =>
1244 45 magro732
                      -- There should be no more content in an NWRITE/NWRITER request.
1245 39 magro732
                      -- Discard.
1246
                  end case;
1247 45 magro732
                  inboundAck <= '1';
1248 6 magro732
                end if;
1249
              end if;
1250
            else
1251 39 magro732
              if (memoryWrite = '1') then
1252
                memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
1253
              end if;
1254
 
1255
              memoryWrite <= '0';
1256 45 magro732
              inboundAck <= '0';
1257 6 magro732
            end if;
1258
          else
1259 45 magro732
            if (packetIndex >= 6) then
1260
              complete <= '1';
1261 39 magro732
              state <= READY;
1262 45 magro732
            else
1263
              packetIndex <= 0;
1264
              memoryAddress <= (others=>'0');
1265 39 magro732
            end if;
1266 6 magro732
          end if;
1267
 
1268 39 magro732
        when READY =>
1269
          ---------------------------------------------------------------------
1270
          -- Wait for the handler of the packet to signal that it has been
1271
          -- processed.
1272
          ---------------------------------------------------------------------
1273
          if (done_i = '1') then
1274 45 magro732
            packetIndex <= 0;
1275
            memoryAddress <= (others=>'0');
1276 39 magro732
            complete <= '0';
1277
            state <= RECEIVE_PACKET;
1278 6 magro732
          end if;
1279
 
1280
        when others =>
1281 39 magro732
          ---------------------------------------------------------------------
1282
          -- 
1283
          ---------------------------------------------------------------------
1284 6 magro732
 
1285
      end case;
1286 39 magro732
    end if;
1287
  end process;
1288 6 magro732
 
1289 39 magro732
  -----------------------------------------------------------------------------
1290
  -- Transformation of wrsize and wdptr into length of access and byte lanes.
1291
  -----------------------------------------------------------------------------
1292
 
1293
  process(clk, areset_n)
1294
  begin
1295
    if (areset_n = '0') then
1296 44 magro732
      length_o <= "00000";
1297 39 magro732
      select_o <= (others=>'0');
1298
    elsif (clk'event and clk = '1') then
1299
      if (complete = '1') then
1300
        if (wdptr = '0') then
1301
          case wrsize is
1302
            when "0000" =>
1303 44 magro732
              length_o <= "00000";
1304 39 magro732
              select_o <= "10000000";
1305
            when "0001" =>
1306 44 magro732
              length_o <= "00000";
1307 39 magro732
              select_o <= "01000000";
1308
            when "0010" =>
1309 44 magro732
              length_o <= "00000";
1310 39 magro732
              select_o <= "00100000";
1311
            when "0011" =>
1312 44 magro732
              length_o <= "00000";
1313 39 magro732
              select_o <= "00010000";
1314
            when "0100" =>
1315 44 magro732
              length_o <= "00000";
1316 39 magro732
              select_o <= "11000000";
1317
            when "0101" =>
1318 44 magro732
              length_o <= "00000";
1319 39 magro732
              select_o <= "11100000";
1320
            when "0110" =>
1321 44 magro732
              length_o <= "00000";
1322 39 magro732
              select_o <= "00110000";
1323
            when "0111" =>
1324 44 magro732
              length_o <= "00000";
1325 39 magro732
              select_o <= "11111000";
1326
            when "1000" =>
1327 44 magro732
              length_o <= "00000";
1328 39 magro732
              select_o <= "11110000";
1329
            when "1001" =>
1330 44 magro732
              length_o <= "00000";
1331 39 magro732
              select_o <= "11111100";
1332
            when "1010" =>
1333 44 magro732
              length_o <= "00000";
1334 39 magro732
              select_o <= "11111110";
1335
            when "1011" =>
1336 44 magro732
              length_o <= "00000";
1337 39 magro732
              select_o <= "11111111";
1338
            when others =>
1339 45 magro732
              length_o <= std_logic_vector(unsigned(memoryAddress)-1);
1340 39 magro732
              select_o <= "11111111";
1341
          end case;
1342
        else
1343
          case wrsize is
1344
            when "0000" =>
1345 44 magro732
              length_o <= "00000";
1346 39 magro732
              select_o <= "00001000";
1347
            when "0001" =>
1348 44 magro732
              length_o <= "00000";
1349 39 magro732
              select_o <= "00000100";
1350
            when "0010" =>
1351 44 magro732
              length_o <= "00000";
1352 39 magro732
              select_o <= "00000010";
1353
            when "0011" =>
1354 44 magro732
              length_o <= "00000";
1355 39 magro732
              select_o <= "00000001";
1356
            when "0100" =>
1357 44 magro732
              length_o <= "00000";
1358 39 magro732
              select_o <= "00001100";
1359
            when "0101" =>
1360 44 magro732
              length_o <= "00000";
1361 39 magro732
              select_o <= "00000111";
1362
            when "0110" =>
1363 44 magro732
              length_o <= "00000";
1364 39 magro732
              select_o <= "00000011";
1365
            when "0111" =>
1366 44 magro732
              length_o <= "00000";
1367 39 magro732
              select_o <= "00011111";
1368
            when "1000" =>
1369 44 magro732
              length_o <= "00000";
1370 39 magro732
              select_o <= "00001111";
1371
            when "1001" =>
1372 44 magro732
              length_o <= "00000";
1373 39 magro732
              select_o <= "00111111";
1374
            when "1010" =>
1375 44 magro732
              length_o <= "00000";
1376 39 magro732
              select_o <= "01111111";
1377
            when others =>
1378 45 magro732
              length_o <= std_logic_vector(unsigned(memoryAddress)-1);
1379 39 magro732
              select_o <= "11111111";
1380
          end case;
1381
        end if;
1382
      end if;
1383 6 magro732
    end if;
1384 39 magro732
  end process;
1385 6 magro732
 
1386
  -----------------------------------------------------------------------------
1387 39 magro732
  -- Payload content memory.
1388 6 magro732
  -----------------------------------------------------------------------------
1389 44 magro732
 
1390 39 magro732
  PayloadMemory: MemorySimpleDualPort
1391
    generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>64)
1392
    port map(clkA_i=>clk,
1393
             enableA_i=>memoryWrite,
1394
             addressA_i=>memoryAddress,
1395
             dataA_i=>memoryDataIn,
1396
             clkB_i=>clk,
1397 44 magro732
             enableB_i=>payloadRead_i,
1398
             addressB_i=>payloadIndex_i,
1399 39 magro732
             dataB_o=>payload_o);
1400 6 magro732
 
1401 39 magro732
end architecture;
1402
 
1403
 
1404
 
1405
-------------------------------------------------------------------------------
1406
-- 
1407
-------------------------------------------------------------------------------
1408
library ieee;
1409
use ieee.std_logic_1164.all;
1410
use ieee.numeric_std.all;
1411
use work.rio_common.all;
1412
 
1413
-------------------------------------------------------------------------------
1414
-- 
1415
-------------------------------------------------------------------------------
1416
entity ResponseClassOutbound is
1417
  port(
1418
    clk : in std_logic;
1419
    areset_n : in std_logic;
1420
    enable : in std_logic;
1421
 
1422
    ready_i : in std_logic;
1423
    vc_i : in std_logic;
1424
    crf_i : in std_logic;
1425
    prio_i : in std_logic_vector(1 downto 0);
1426
    tt_i : in std_logic_vector(1 downto 0);
1427
    dstid_i : in std_logic_vector(31 downto 0);
1428
    srcid_i : in std_logic_vector(31 downto 0);
1429
    tid_i : in std_logic_vector(7 downto 0);
1430
    error_i : in std_logic;
1431
    payloadPresent_i :  in std_logic;
1432 44 magro732
    payloadLength_i : in std_logic_vector(4 downto 0);
1433 39 magro732
    payloadWrite_i : in std_logic;
1434 44 magro732
    payloadIndex_i : in std_logic_vector(4 downto 0);
1435
    payload_i : in std_logic_vector(63 downto 0);
1436 39 magro732
    done_o : out std_logic;
1437
 
1438 45 magro732
    outboundCyc_o : out std_logic;
1439
    outboundStb_o : out std_logic;
1440
    outboundDat_o : out std_logic_vector(31 downto 0);
1441
    outboundAck_i : in std_logic);
1442 39 magro732
end entity;
1443
 
1444
 
1445
-------------------------------------------------------------------------------
1446
-- 
1447
-------------------------------------------------------------------------------
1448
architecture ResponseClassOutbound of ResponseClassOutbound is
1449
  component MemorySimpleDualPort
1450
    generic(
1451
      ADDRESS_WIDTH : natural := 1;
1452
      DATA_WIDTH : natural := 1);
1453
    port(
1454
      clkA_i : in std_logic;
1455
      enableA_i : in std_logic;
1456
      addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
1457
      dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
1458
 
1459
      clkB_i : in std_logic;
1460
      enableB_i : in std_logic;
1461
      addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
1462
      dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
1463
  end component;
1464
 
1465 44 magro732
  signal header : std_logic_vector(31 downto 0);
1466
 
1467
  type StateType is (WAIT_PACKET, SEND_RESPONSE,
1468 39 magro732
                     WAIT_COMPLETE, RESPONSE_DONE);
1469
  signal state : StateType;
1470
 
1471 44 magro732
  signal packetIndex : natural range 0 to 68;
1472
 
1473
  signal responsePayloadIndex : std_logic_vector(4 downto 0);
1474
  signal responsePayload : std_logic_vector(15 downto 0);
1475 39 magro732
 
1476
  signal memoryEnable : std_logic;
1477
  signal memoryAddress : std_logic_vector(4 downto 0);
1478
  signal memoryDataRead : std_logic_vector(63 downto 0);
1479
 
1480
begin
1481
 
1482
  header <= x"0000" & "000000" & vc_i & crf_i & prio_i & tt_i & x"d";
1483
 
1484
  Response: process(clk, areset_n)
1485
  begin
1486
    if (areset_n = '0') then
1487 44 magro732
      state <= WAIT_PACKET;
1488 39 magro732
 
1489 44 magro732
      packetIndex <= 0;
1490
 
1491
      responsePayloadIndex <= (others=>'0');
1492
      responsePayload <= (others=>'0');
1493
 
1494 39 magro732
      memoryEnable <= '0';
1495
      memoryAddress <= (others=>'0');
1496
 
1497
      done_o <= '0';
1498
 
1499 45 magro732
      outboundCyc_o <= '0';
1500
      outboundStb_o <= '0';
1501
      outboundDat_o <= (others=>'0');
1502 39 magro732
    elsif (clk'event and clk = '1') then
1503
      if (enable = '1') then
1504
        case state is
1505
          when WAIT_PACKET =>
1506
            -------------------------------------------------------------------
1507
            -- 
1508
            -------------------------------------------------------------------
1509
            if (ready_i = '1') then
1510 45 magro732
              outboundCyc_o <= '1';
1511
              outboundStb_o <= '1';
1512
              outboundDat_o <= header;
1513 39 magro732
 
1514
              packetIndex <= 1;
1515 44 magro732
              responsePayloadIndex <= (others=>'0');
1516 39 magro732
 
1517
              memoryEnable <= '1';
1518
              memoryAddress <= (others=>'0');
1519
 
1520
              state <= SEND_RESPONSE;
1521 6 magro732
            end if;
1522 39 magro732
 
1523
          when SEND_RESPONSE =>
1524
            ---------------------------------------------------------------------
1525
            -- 
1526
            ---------------------------------------------------------------------
1527 45 magro732
            if (outboundAck_i = '1') then
1528 39 magro732
              case (packetIndex) is
1529
                when 1 =>
1530
                  -- destination
1531 45 magro732
                  outboundDat_o <= dstId_i;
1532 39 magro732
                  packetIndex <= packetIndex + 1;
1533
                when 2 =>
1534
                  -- source 
1535 45 magro732
                  outboundDat_o <= srcId_i;
1536 39 magro732
                  packetIndex <= packetIndex + 1;
1537
                when 3 =>
1538
                  -- transaction & status & targetTID & double-word0(63:48)
1539
                  if (error_i = '0') then
1540
                    if (payloadPresent_i = '0') then
1541 45 magro732
                      outboundDat_o <= "0000" & "0000" & tid_i & x"0000";
1542 39 magro732
                      state <= WAIT_COMPLETE;
1543
                    else
1544 45 magro732
                      outboundDat_o <= "1000" & "0000" & tid_i & memoryDataRead(63 downto 48);
1545 39 magro732
                    end if;
1546
                  else
1547 45 magro732
                    outboundDat_o <= "0000" & "0111" & tid_i & x"0000";
1548 39 magro732
                    state <= WAIT_COMPLETE;
1549
                  end if;
1550
                  packetIndex <= packetIndex + 1;
1551
                when 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 |
1552
                  36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 =>
1553
                  -- double-wordN(47:16)
1554 45 magro732
                  outboundDat_o <= memoryDataRead(47 downto 16);
1555 39 magro732
                  responsePayload <= memoryDataRead(15 downto 0);
1556
                  memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
1557
                  packetIndex <= packetIndex + 1;
1558
                when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 33 | 35 |
1559
                  37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 59 | 61 | 63 | 65 | 67 =>
1560
                  -- double-wordN(15:0) & double-wordN(63:48)
1561 45 magro732
                  outboundDat_o <= responsePayload & memoryDataRead(63 downto 48);
1562 39 magro732
                  packetIndex <= packetIndex + 1;
1563
 
1564
                  responsePayloadIndex <=
1565
                    std_logic_vector(unsigned(responsePayloadIndex) + 1);
1566
 
1567 44 magro732
                  if (responsePayloadIndex = payloadLength_i) then
1568 39 magro732
                    state <= WAIT_COMPLETE;
1569
                  else
1570
                    packetIndex <= packetIndex + 1;
1571
                  end if;
1572
                when others =>
1573
                  -- Unallowed response length.
1574
                  -- Dont do anything.
1575
              end case;
1576 6 magro732
            end if;
1577 39 magro732
 
1578
          when WAIT_COMPLETE =>
1579
            -------------------------------------------------------------------
1580
            -- 
1581
            -------------------------------------------------------------------
1582 45 magro732
            if (outboundAck_i = '1') then
1583
              outboundCyc_o <= '0';
1584
              outboundStb_o <= '0';
1585 39 magro732
              state <= RESPONSE_DONE;
1586
            end if;
1587
 
1588
          when RESPONSE_DONE =>
1589
            ---------------------------------------------------------------------
1590
            -- 
1591
            ---------------------------------------------------------------------
1592
            memoryEnable <= '0';
1593
            if (ready_i = '0') then
1594
              state <= WAIT_PACKET;
1595
              done_o <= '0';
1596 6 magro732
            else
1597 39 magro732
              done_o <= '1';
1598 6 magro732
            end if;
1599 39 magro732
 
1600 6 magro732
          when others =>
1601 39 magro732
            ---------------------------------------------------------------------
1602
            -- 
1603
            ---------------------------------------------------------------------
1604
            state <= WAIT_PACKET;
1605
 
1606 6 magro732
        end case;
1607
      end if;
1608
    end if;
1609
  end process;
1610
 
1611
  -----------------------------------------------------------------------------
1612 39 magro732
  -- Payload content memory.
1613 6 magro732
  -----------------------------------------------------------------------------
1614 39 magro732
  PayloadMemory: MemorySimpleDualPort
1615
    generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>64)
1616
    port map(clkA_i=>clk,
1617
             enableA_i=>payloadWrite_i,
1618
             addressA_i=>payloadIndex_i,
1619
             dataA_i=>payload_i,
1620
             clkB_i=>clk,
1621
             enableB_i=>memoryEnable,
1622
             addressB_i=>memoryAddress,
1623
             dataB_o=>memoryDataRead);
1624 6 magro732
 
1625
end architecture;

powered by: WebSVN 2.1.0

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