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

Subversion Repositories rio

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

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

Line No. Rev Author Line
1 2 magro732
-------------------------------------------------------------------------------
2
-- 
3
-- RapidIO IP Library Core
4
-- 
5
-- This file is part of the RapidIO IP library project
6
-- http://www.opencores.org/cores/rio/
7
-- 
8
-- Description
9
-- Containing RapidIO packet switching functionality contained in the top
10
-- entity RioSwitch.
11
-- 
12
-- To Do:
13 46 magro732
-- - Add configAck to external interface.
14
-- - Complete forwarding of maintenance packets.
15
-- - Remove all common component-declarations and move them to RioCommon.
16
-- - Add support for longer maintenance packets.
17
-- - Add support for portWrite maintenance packets.
18
-- - Add a real crossbar as interconnect.
19
-- - Change the internal addressing to one-hot.
20
-- - Remove acknowledge cycle when transfering packets between ports to double
21
--   the bandwidth.
22
-- - Add hot-swap.
23
-- - Connect linkInitialized to all ports and read it from the source port
24
--   using the interconnect. This will allow alternative routes since the
25
--   sending port can see if a receiving port is up or not.
26
-- - Add support for extended route.
27
-- - Add validity-bit to know if a route has been activly set for a particular
28
--   deviceId.
29 2 magro732
-- 
30
-- Author(s): 
31
-- - Magnus Rosenius, magro732@opencores.org 
32
-- 
33
-------------------------------------------------------------------------------
34
-- 
35
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
36
-- 
37
-- This source file may be used and distributed without 
38
-- restriction provided that this copyright statement is not 
39
-- removed from the file and that any derivative work contains 
40
-- the original copyright notice and the associated disclaimer. 
41
-- 
42
-- This source file is free software; you can redistribute it 
43
-- and/or modify it under the terms of the GNU Lesser General 
44
-- Public License as published by the Free Software Foundation; 
45
-- either version 2.1 of the License, or (at your option) any 
46
-- later version. 
47
-- 
48
-- This source is distributed in the hope that it will be 
49
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
50
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
51
-- PURPOSE. See the GNU Lesser General Public License for more 
52
-- details. 
53
-- 
54
-- You should have received a copy of the GNU Lesser General 
55
-- Public License along with this source; if not, download it 
56
-- from http://www.opencores.org/lgpl.shtml 
57
-- 
58
-------------------------------------------------------------------------------
59
 
60
 
61
-------------------------------------------------------------------------------
62
-- RioSwitch
63
-------------------------------------------------------------------------------
64
 
65
library ieee;
66
use ieee.std_logic_1164.all;
67
use ieee.numeric_std.all;
68
use work.rio_common.all;
69
 
70
-------------------------------------------------------------------------------
71
-- Entity for RioSwitch.
72
-------------------------------------------------------------------------------
73
entity RioSwitch is
74
  generic(
75
    SWITCH_PORTS : natural range 3 to 255 := 4;
76
    DEVICE_IDENTITY : std_logic_vector(15 downto 0);
77
    DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
78
    DEVICE_REV : std_logic_vector(31 downto 0);
79
    ASSY_IDENTITY : std_logic_vector(15 downto 0);
80
    ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
81
    ASSY_REV : std_logic_vector(15 downto 0));
82
  port(
83
    clk : in std_logic;
84
    areset_n : in std_logic;
85
 
86
    writeFrameFull_i : in Array1(SWITCH_PORTS-1 downto 0);
87
    writeFrame_o : out Array1(SWITCH_PORTS-1 downto 0);
88
    writeFrameAbort_o : out Array1(SWITCH_PORTS-1 downto 0);
89
    writeContent_o : out Array1(SWITCH_PORTS-1 downto 0);
90
    writeContentData_o : out Array32(SWITCH_PORTS-1 downto 0);
91
 
92
    readFrameEmpty_i : in Array1(SWITCH_PORTS-1 downto 0);
93
    readFrame_o : out Array1(SWITCH_PORTS-1 downto 0);
94
    readFrameRestart_o : out Array1(SWITCH_PORTS-1 downto 0);
95
    readFrameAborted_i : in Array1(SWITCH_PORTS-1 downto 0);
96
    readContentEmpty_i : in Array1(SWITCH_PORTS-1 downto 0);
97
    readContent_o : out Array1(SWITCH_PORTS-1 downto 0);
98
    readContentEnd_i : in Array1(SWITCH_PORTS-1 downto 0);
99
    readContentData_i : in Array32(SWITCH_PORTS-1 downto 0);
100
 
101
    portLinkTimeout_o : out std_logic_vector(23 downto 0);
102
 
103
    linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0);
104
    outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
105
    inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
106
 
107
    localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0);
108
    clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0);
109
    inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
110
    outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
111
    outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
112
    inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
113
    outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
114
    outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
115
 
116
    configStb_o : out std_logic;
117
    configWe_o : out std_logic;
118
    configAddr_o : out std_logic_vector(23 downto 0);
119
    configData_o : out std_logic_vector(31 downto 0);
120
    configData_i : in std_logic_vector(31 downto 0));
121
end entity;
122
 
123
 
124
-------------------------------------------------------------------------------
125
-- Architecture for RioSwitch.
126
-------------------------------------------------------------------------------
127
architecture RioSwitchImpl of RioSwitch is
128
 
129
  component RouteTableInterconnect is
130
    generic(
131
      WIDTH : natural range 1 to 256 := 8);
132
    port(
133
      clk : in std_logic;
134
      areset_n : in std_logic;
135
 
136
      stb_i : in Array1(WIDTH-1 downto 0);
137
      addr_i : in Array16(WIDTH-1 downto 0);
138
      dataM_o : out Array8(WIDTH-1 downto 0);
139
      ack_o : out Array1(WIDTH-1 downto 0);
140
 
141
      stb_o : out std_logic;
142
      addr_o : out std_logic_vector(15 downto 0);
143
      dataS_i : in std_logic_vector(7 downto 0);
144
      ack_i : in std_logic);
145
  end component;
146
 
147
  component SwitchPortInterconnect is
148
    generic(
149
      WIDTH : natural range 1 to 256 := 8);
150
    port(
151
      clk : in std_logic;
152
      areset_n : in std_logic;
153
 
154
      masterCyc_i : in Array1(WIDTH-1 downto 0);
155
      masterStb_i : in Array1(WIDTH-1 downto 0);
156
      masterWe_i : in Array1(WIDTH-1 downto 0);
157
      masterAddr_i : in Array10(WIDTH-1 downto 0);
158
      masterData_i : in Array32(WIDTH-1 downto 0);
159
      masterData_o : out Array1(WIDTH-1 downto 0);
160
      masterAck_o : out Array1(WIDTH-1 downto 0);
161
 
162
      slaveCyc_o : out Array1(WIDTH-1 downto 0);
163
      slaveStb_o : out Array1(WIDTH-1 downto 0);
164
      slaveWe_o : out Array1(WIDTH-1 downto 0);
165
      slaveAddr_o : out Array10(WIDTH-1 downto 0);
166
      slaveData_o : out Array32(WIDTH-1 downto 0);
167
      slaveData_i : in Array1(WIDTH-1 downto 0);
168
      slaveAck_i : in Array1(WIDTH-1 downto 0));
169
  end component;
170
 
171
  component SwitchPortMaintenance is
172
    generic(
173
      SWITCH_PORTS : natural range 0 to 255;
174
      DEVICE_IDENTITY : std_logic_vector(15 downto 0);
175
      DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
176
      DEVICE_REV : std_logic_vector(31 downto 0);
177
      ASSY_IDENTITY : std_logic_vector(15 downto 0);
178
      ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
179
      ASSY_REV : std_logic_vector(15 downto 0));
180
    port(
181
      clk : in std_logic;
182
      areset_n : in std_logic;
183
 
184
      lookupStb_i : in std_logic;
185
      lookupAddr_i : in std_logic_vector(15 downto 0);
186
      lookupData_o : out std_logic_vector(7 downto 0);
187
      lookupAck_o : out std_logic;
188
 
189
      masterCyc_o : out std_logic;
190
      masterStb_o : out std_logic;
191
      masterWe_o : out std_logic;
192
      masterAddr_o : out std_logic_vector(9 downto 0);
193
      masterData_o : out std_logic_vector(31 downto 0);
194
      masterData_i : in std_logic;
195
      masterAck_i : in std_logic;
196
 
197
      slaveCyc_i : in std_logic;
198
      slaveStb_i : in std_logic;
199
      slaveWe_i : in std_logic;
200
      slaveAddr_i : in std_logic_vector(9 downto 0);
201
      slaveData_i : in std_logic_vector(31 downto 0);
202
      slaveData_o : out std_logic;
203
      slaveAck_o : out std_logic;
204
 
205
      lookupStb_o : out std_logic;
206
      lookupAddr_o : out std_logic_vector(15 downto 0);
207
      lookupData_i : in std_logic_vector(7 downto 0);
208
      lookupAck_i : in std_logic;
209
 
210
      portLinkTimeout_o : out std_logic_vector(23 downto 0);
211
 
212
      linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0);
213
      outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
214
      inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
215
      localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0);
216
      clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0);
217
      inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
218
      outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
219
      outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
220
      inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
221
      outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
222
      outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
223
 
224
      configStb_o : out std_logic;
225
      configWe_o : out std_logic;
226
      configAddr_o : out std_logic_vector(23 downto 0);
227
      configData_o : out std_logic_vector(31 downto 0);
228
      configData_i : in std_logic_vector(31 downto 0));
229
  end component;
230
 
231
  component SwitchPort is
232
    generic(
233 46 magro732
      MAINTENANCE_LOOKUP : boolean;
234 2 magro732
      PORT_INDEX : natural);
235
    port(
236
      clk : in std_logic;
237
      areset_n : in std_logic;
238
 
239
      masterCyc_o : out std_logic;
240
      masterStb_o : out std_logic;
241
      masterWe_o : out std_logic;
242
      masterAddr_o : out std_logic_vector(9 downto 0);
243
      masterData_o : out std_logic_vector(31 downto 0);
244
      masterData_i : in std_logic;
245
      masterAck_i : in std_logic;
246
 
247
      slaveCyc_i : in std_logic;
248
      slaveStb_i : in std_logic;
249
      slaveWe_i : in std_logic;
250
      slaveAddr_i : in std_logic_vector(9 downto 0);
251
      slaveData_i : in std_logic_vector(31 downto 0);
252
      slaveData_o : out std_logic;
253
      slaveAck_o : out std_logic;
254
 
255
      lookupStb_o : out std_logic;
256
      lookupAddr_o : out std_logic_vector(15 downto 0);
257
      lookupData_i : in std_logic_vector(7 downto 0);
258
      lookupAck_i : in std_logic;
259
 
260
      readFrameEmpty_i : in std_logic;
261
      readFrame_o : out std_logic;
262
      readFrameRestart_o : out std_logic;
263
      readFrameAborted_i : in std_logic;
264
      readContentEmpty_i : in std_logic;
265
      readContent_o : out std_logic;
266
      readContentEnd_i : in std_logic;
267
      readContentData_i : in std_logic_vector(31 downto 0);
268 46 magro732
      writeFramePort_o : out std_logic_vector(9 downto 0);
269 2 magro732
      writeFrameFull_i : in std_logic;
270
      writeFrame_o : out std_logic;
271
      writeFrameAbort_o : out std_logic;
272
      writeContent_o : out std_logic;
273
      writeContentData_o : out std_logic_vector(31 downto 0));
274
  end component;
275
 
276
  signal masterLookupStb : Array1(SWITCH_PORTS downto 0);
277
  signal masterLookupAddr : Array16(SWITCH_PORTS downto 0);
278
  signal masterLookupData : Array8(SWITCH_PORTS downto 0);
279
  signal masterLookupAck : Array1(SWITCH_PORTS downto 0);
280
 
281
  signal slaveLookupStb : std_logic;
282
  signal slaveLookupAddr : std_logic_vector(15 downto 0);
283
  signal slaveLookupData : std_logic_vector(7 downto 0);
284
  signal slaveLookupAck : std_logic;
285
 
286
  signal masterCyc : Array1(SWITCH_PORTS downto 0);
287
  signal masterStb : Array1(SWITCH_PORTS downto 0);
288
  signal masterWe : Array1(SWITCH_PORTS downto 0);
289
  signal masterAddr : Array10(SWITCH_PORTS downto 0);
290
  signal masterDataWrite : Array32(SWITCH_PORTS downto 0);
291
  signal masterDataRead : Array1(SWITCH_PORTS downto 0);
292
  signal masterAck : Array1(SWITCH_PORTS downto 0);
293
 
294
  signal slaveCyc : Array1(SWITCH_PORTS downto 0);
295
  signal slaveStb : Array1(SWITCH_PORTS downto 0);
296
  signal slaveWe : Array1(SWITCH_PORTS downto 0);
297
  signal slaveAddr : Array10(SWITCH_PORTS downto 0);
298
  signal slaveDataWrite : Array32(SWITCH_PORTS downto 0);
299
  signal slaveDataRead : Array1(SWITCH_PORTS downto 0);
300
  signal slaveAck : Array1(SWITCH_PORTS downto 0);
301
 
302
begin
303
 
304
  -----------------------------------------------------------------------------
305
  -- The routing table interconnect.
306
  -----------------------------------------------------------------------------
307
  RouteInterconnect: RouteTableInterconnect
308
    generic map(
309
      WIDTH=>SWITCH_PORTS+1)
310
    port map(
311
      clk=>clk, areset_n=>areset_n,
312
      stb_i=>masterLookupStb, addr_i=>masterLookupAddr,
313
      dataM_o=>masterLookupData, ack_o=>masterLookupAck,
314
      stb_o=>slaveLookupStb, addr_o=>slaveLookupAddr,
315
      dataS_i=>slaveLookupData, ack_i=>slaveLookupAck);
316
 
317
  -----------------------------------------------------------------------------
318
  -- The port interconnect.
319
  -----------------------------------------------------------------------------
320
  PortInterconnect: SwitchPortInterconnect
321
    generic map(
322
      WIDTH=>SWITCH_PORTS+1)
323
    port map(
324
      clk=>clk, areset_n=>areset_n,
325
      masterCyc_i=>masterCyc, masterStb_i=>masterStb, masterWe_i=>masterWe, masterAddr_i=>masterAddr,
326
      masterData_i=>masterDataWrite, masterData_o=>masterDataRead, masterAck_o=>masterAck,
327
      slaveCyc_o=>slaveCyc, slaveStb_o=>slaveStb, slaveWe_o=>slaveWe, slaveAddr_o=>slaveAddr,
328
      slaveData_o=>slaveDataWrite, slaveData_i=>slaveDataRead, slaveAck_i=>slaveAck);
329
 
330
  -----------------------------------------------------------------------------
331
  -- Data relaying port instantiation.
332
  -----------------------------------------------------------------------------
333
  PortGeneration: for portIndex in 0 to SWITCH_PORTS-1 generate
334
    PortInst: SwitchPort
335
      generic map(
336 46 magro732
        MAINTENANCE_LOOKUP=>false,
337 2 magro732
        PORT_INDEX=>portIndex)
338
      port map(
339
        clk=>clk, areset_n=>areset_n,
340
        masterCyc_o=>masterCyc(portIndex), masterStb_o=>masterStb(portIndex),
341
        masterWe_o=>masterWe(portIndex), masterAddr_o=>masterAddr(portIndex),
342
        masterData_o=>masterDataWrite(portIndex),
343
        masterData_i=>masterDataRead(portIndex), masterAck_i=>masterAck(portIndex),
344
        slaveCyc_i=>slaveCyc(portIndex), slaveStb_i=>slaveStb(portIndex),
345
        slaveWe_i=>slaveWe(portIndex), slaveAddr_i=>slaveAddr(portIndex),
346
        slaveData_i=>slaveDataWrite(portIndex),
347
        slaveData_o=>slaveDataRead(portIndex), slaveAck_o=>slaveAck(portIndex),
348
        lookupStb_o=>masterLookupStb(portIndex),
349
        lookupAddr_o=>masterLookupAddr(portIndex),
350
        lookupData_i=>masterLookupData(portIndex), lookupAck_i=>masterLookupAck(portIndex),
351
        readFrameEmpty_i=>readFrameEmpty_i(portIndex), readFrame_o=>readFrame_o(portIndex),
352
        readFrameRestart_o=>readFrameRestart_o(portIndex),
353
        readFrameAborted_i=>readFrameAborted_i(portIndex),
354
        readContentEmpty_i=>readContentEmpty_i(portIndex), readContent_o=>readContent_o(portIndex),
355
        readContentEnd_i=>readContentEnd_i(portIndex), readContentData_i=>readContentData_i(portIndex),
356 46 magro732
        writeFramePort_o=>open,
357 2 magro732
        writeFrameFull_i=>writeFrameFull_i(portIndex), writeFrame_o=>writeFrame_o(portIndex),
358
        writeFrameAbort_o=>writeFrameAbort_o(portIndex), writeContent_o=>writeContent_o(portIndex),
359
        writeContentData_o=>writeContentData_o(portIndex));
360
  end generate;
361
 
362
  -----------------------------------------------------------------------------
363
  -- Maintenance port instantiation.
364
  -----------------------------------------------------------------------------
365
  MaintenancePort: SwitchPortMaintenance
366
    generic map(
367
      SWITCH_PORTS=>SWITCH_PORTS,
368
      DEVICE_IDENTITY=>DEVICE_IDENTITY,
369
      DEVICE_VENDOR_IDENTITY=>DEVICE_VENDOR_IDENTITY,
370
      DEVICE_REV=>DEVICE_REV,
371
      ASSY_IDENTITY=>ASSY_IDENTITY,
372
      ASSY_VENDOR_IDENTITY=>ASSY_VENDOR_IDENTITY,
373
      ASSY_REV=>ASSY_REV)
374
    port map(
375
      clk=>clk, areset_n=>areset_n,
376
      lookupStb_i=>slaveLookupStb, lookupAddr_i=>slaveLookupAddr,
377
      lookupData_o=>slaveLookupData, lookupAck_o=>slaveLookupAck,
378
      masterCyc_o=>masterCyc(SWITCH_PORTS), masterStb_o=>masterStb(SWITCH_PORTS),
379
      masterWe_o=>masterWe(SWITCH_PORTS), masterAddr_o=>masterAddr(SWITCH_PORTS),
380
      masterData_o=>masterDataWrite(SWITCH_PORTS),
381
      masterData_i=>masterDataRead(SWITCH_PORTS), masterAck_i=>masterAck(SWITCH_PORTS),
382
      slaveCyc_i=>slaveCyc(SWITCH_PORTS), slaveStb_i=>slaveStb(SWITCH_PORTS),
383
      slaveWe_i=>slaveWe(SWITCH_PORTS), slaveAddr_i=>slaveAddr(SWITCH_PORTS),
384
      slaveData_i=>slaveDataWrite(SWITCH_PORTS),
385
      slaveData_o=>slaveDataRead(SWITCH_PORTS), slaveAck_o=>slaveAck(SWITCH_PORTS),
386
      lookupStb_o=>masterLookupStb(SWITCH_PORTS),
387
      lookupAddr_o=>masterLookupAddr(SWITCH_PORTS),
388
      lookupData_i=>masterLookupData(SWITCH_PORTS), lookupAck_i=>masterLookupAck(SWITCH_PORTS),
389
      portLinkTimeout_o=>portLinkTimeout_o,
390
      linkInitialized_i=>linkInitialized_i,
391
      outputPortEnable_o=>outputPortEnable_o, inputPortEnable_o=>inputPortEnable_o,
392
      localAckIdWrite_o=>localAckIdWrite_o, clrOutstandingAckId_o=>clrOutstandingAckId_o,
393
      inboundAckId_o=>inboundAckId_o, outstandingAckId_o=>outstandingAckId_o,
394
      outboundAckId_o=>outboundAckId_o, inboundAckId_i=>inboundAckId_i,
395
      outstandingAckId_i=>outstandingAckId_i, outboundAckId_i=>outboundAckId_i,
396
      configStb_o=>configStb_o, configWe_o=>configWe_o, configAddr_o=>configAddr_o,
397
      configData_o=>configData_o, configData_i=>configData_i);
398
 
399
end architecture;
400
 
401
 
402
 
403
-------------------------------------------------------------------------------
404 46 magro732
-- SwitchPort.
405 2 magro732
-------------------------------------------------------------------------------
406
library ieee;
407
use ieee.std_logic_1164.all;
408
use ieee.numeric_std.all;
409
use work.rio_common.all;
410
 
411
 
412
-------------------------------------------------------------------------------
413
-- Entity for SwitchPort.
414
-------------------------------------------------------------------------------
415
entity SwitchPort is
416
  generic(
417 46 magro732
    MAINTENANCE_LOOKUP : boolean;
418 2 magro732
    PORT_INDEX : natural);
419
  port(
420
    clk : in std_logic;
421
    areset_n : in std_logic;
422
 
423
    -- Master port signals.
424
    -- Write frames to other ports.
425
    masterCyc_o : out std_logic;
426
    masterStb_o : out std_logic;
427
    masterWe_o : out std_logic;
428
    masterAddr_o : out std_logic_vector(9 downto 0);
429
    masterData_o : out std_logic_vector(31 downto 0);
430
    masterData_i : in std_logic;
431
    masterAck_i : in std_logic;
432
 
433
    -- Slave port signals.
434
    -- Receives frames from other ports.
435
    slaveCyc_i : in std_logic;
436
    slaveStb_i : in std_logic;
437
    slaveWe_i : in std_logic;
438
    slaveAddr_i : in std_logic_vector(9 downto 0);
439
    slaveData_i : in std_logic_vector(31 downto 0);
440
    slaveData_o : out std_logic;
441
    slaveAck_o : out std_logic;
442
 
443
    -- Address-lookup interface.
444
    lookupStb_o : out std_logic;
445
    lookupAddr_o : out std_logic_vector(15 downto 0);
446
    lookupData_i : in std_logic_vector(7 downto 0);
447
    lookupAck_i : in std_logic;
448
 
449
    -- Physical port frame buffer interface.
450
    readFrameEmpty_i : in std_logic;
451
    readFrame_o : out std_logic;
452
    readFrameRestart_o : out std_logic;
453
    readFrameAborted_i : in std_logic;
454
    readContentEmpty_i : in std_logic;
455
    readContent_o : out std_logic;
456
    readContentEnd_i : in std_logic;
457
    readContentData_i : in std_logic_vector(31 downto 0);
458 46 magro732
    writeFramePort_o : out std_logic_vector(7 downto 0);
459 2 magro732
    writeFrameFull_i : in std_logic;
460
    writeFrame_o : out std_logic;
461
    writeFrameAbort_o : out std_logic;
462
    writeContent_o : out std_logic;
463
    writeContentData_o : out std_logic_vector(31 downto 0));
464
end entity;
465
 
466
 
467
-------------------------------------------------------------------------------
468
-- Architecture for SwitchPort.
469
-------------------------------------------------------------------------------
470
architecture SwitchPortImpl of SwitchPort is
471
 
472
  type MasterStateType is (STATE_IDLE,
473
                           STATE_WAIT_HEADER_0, STATE_READ_HEADER_0,
474
                           STATE_READ_PORT_LOOKUP,
475
                           STATE_READ_TARGET_PORT,
476
                           STATE_WAIT_TARGET_PORT,
477
                           STATE_WAIT_TARGET_WRITE,
478
                           STATE_WAIT_COMPLETE);
479
  signal masterState : MasterStateType;
480 46 magro732
  alias ftype : std_logic_vector(3 downto 0) is readContentData_i(19 downto 16);
481
  alias tt : std_logic_vector(1 downto 0) is readContentData_i(21 downto 20);
482
 
483 2 magro732
  type SlaveStateType is (STATE_IDLE, STATE_SEND_ACK);
484
  signal slaveState : SlaveStateType;
485
 
486
begin
487
 
488
  -----------------------------------------------------------------------------
489
  -- Master interface process.
490
  -----------------------------------------------------------------------------
491
  Master: process(clk, areset_n)
492
  begin
493
    if (areset_n = '0') then
494
      masterState <= STATE_IDLE;
495
 
496
      lookupStb_o <= '0';
497
      lookupAddr_o <= (others => '0');
498
 
499
      masterCyc_o <= '0';
500
      masterStb_o <= '0';
501
      masterWe_o <= '0';
502
      masterAddr_o <= (others => '0');
503
      masterData_o <= (others => '0');
504
 
505
      readContent_o <= '0';
506
      readFrame_o <= '0';
507
      readFrameRestart_o <= '0';
508
    elsif (clk'event and clk = '1') then
509
      readContent_o <= '0';
510
      readFrame_o <= '0';
511
      readFrameRestart_o <= '0';
512
 
513
      -- REMARK: Add support for aborted frames...
514
      case masterState is
515
 
516
        when STATE_IDLE =>
517
          ---------------------------------------------------------------------
518
          -- Wait for a new packet or content of a new packet.
519
          ---------------------------------------------------------------------
520
 
521
          -- Reset bus signals.
522
          masterCyc_o <= '0';
523
          masterStb_o <= '0';
524
 
525
          -- Wait for frame content to be available.
526
          -- Use different signals to trigger the forwarding of packets depending
527
          -- on the switch philosofy.
528
          if (readFrameEmpty_i = '0') then
529
            readContent_o <= '1';
530
            masterState <= STATE_WAIT_HEADER_0;
531
          end if;
532
 
533
        when STATE_WAIT_HEADER_0 =>
534
          ---------------------------------------------------------------------
535
          -- Wait for the frame buffer output to be updated.
536
          ---------------------------------------------------------------------
537
 
538
          -- Wait for frame buffer output to be updated.
539
          masterState <= STATE_READ_HEADER_0;
540
 
541
        when STATE_READ_HEADER_0 =>
542
          ---------------------------------------------------------------------
543
          -- Check the FTYPE and forward it to the maintenance port if it is a
544
          -- maintenance packet. Otherwise, initiate an address lookup and wait
545
          -- for the result.
546
          ---------------------------------------------------------------------
547
 
548
          -- Check if the frame has ended.
549
          if (readContentEnd_i = '0') then
550
            -- The frame has not ended.
551
            -- This word contains the header and the source id.
552
 
553
            -- Read the tt-field to check the source and destination id size.
554
            if (tt = "01") then
555
              -- This frame contains 16-bit addresses.
556
 
557
              -- Read the new content.
558
              readContent_o <= '1';
559
 
560
              -- Save the content of the header and destination.
561
              masterData_o <= readContentData_i;
562
 
563
              -- Check if this is a maintenance frame.
564 46 magro732
              if ((not MAINTENANCE_LOOKUP) and (ftype = FTYPE_MAINTENANCE_CLASS)) then
565 2 magro732
                -- This is a maintenance frame.
566
 
567
                -- Always route these frames to the maintenance module in the
568
                -- switch by setting the MSB bit of the port address.
569
                masterAddr_o <= '1' & std_logic_vector(to_unsigned(PORT_INDEX, 8)) & '0';
570
 
571
                -- Start an access to the maintenance port.
572
                masterState <= STATE_READ_TARGET_PORT;
573
              else
574
                -- This is not a maintenance frame.
575
 
576
                -- Lookup the destination address and proceed to wait for the
577
                -- result.
578
                lookupStb_o <= '1';
579
                lookupAddr_o <= readContentData_i(15 downto 0);
580
 
581
                -- Wait for the port lookup to return a result.
582
                masterState <= STATE_READ_PORT_LOOKUP;
583
              end if;
584
            else
585
              -- Unsupported tt-value, discard the frame.
586
              readFrame_o <= '1';
587
              masterState <= STATE_IDLE;
588
            end if;
589
          else
590
            -- End of frame.
591
            -- The frame is too short to contain a valid frame. Discard it.
592
            readFrame_o <= '1';
593
            masterState <= STATE_IDLE;
594
          end if;
595
 
596
        when STATE_READ_PORT_LOOKUP =>
597
          ---------------------------------------------------------------------
598
          -- Wait for the address lookup to be complete.
599
          ---------------------------------------------------------------------
600
 
601
          -- Wait for the routing table to complete the request.
602
          if (lookupAck_i = '1') then
603
            -- The address lookup is complete.
604
 
605
            -- Terminate the lookup cycle.
606
            lookupStb_o <= '0';
607
 
608
            -- Proceed to read the target port.
609
            masterAddr_o <= '0' & lookupData_i & '0';
610
            masterState <= STATE_READ_TARGET_PORT;
611
          else
612
            -- Wait until the address lookup is complete.
613
            -- REMARK: Timeout here???
614
          end if;
615
 
616
        when STATE_READ_TARGET_PORT =>
617
          ---------------------------------------------------------------------
618
          -- Initiate an access to the target port.
619
          ---------------------------------------------------------------------
620
 
621
          -- Read the status of the target port using the result from the
622
          -- lookup in the routing table.
623
          masterCyc_o <= '1';
624
          masterStb_o <= '1';
625
          masterWe_o <= '0';
626
          masterState <= STATE_WAIT_TARGET_PORT;
627
 
628
        when STATE_WAIT_TARGET_PORT =>
629
          ---------------------------------------------------------------------
630
          -- Wait to get access to the target port. When the port is ready
631
          -- check if it is ready to accept a new frame. If it cannot accept a
632
          -- new frame, terminate the access and go back and start a new one.
633
          -- This is to free the interconnect to let other ports access it if
634
          -- it is a shared bus. If the port is ready, initiate a write access
635
          -- to the selected port.
636
          ---------------------------------------------------------------------
637
 
638
          -- Wait for the target port to complete the request.
639
          if (masterAck_i = '1') then
640
            -- Target port has completed the request.
641
 
642
            -- Check the status of the target port.
643
            if (masterData_i = '0') then
644
              -- The target port has empty buffers to receive the frame.
645
 
646
              -- Hold the bus with cyc until the cycle is complete.
647
              -- Write the first word of the frame to the target port.
648
              -- The masterData_o has already been assigned.
649
              masterCyc_o <= '1';
650
              masterStb_o <= '1';
651
              masterWe_o <= '1';
652
              masterAddr_o(0) <= '1';
653
 
654
              -- Change state to transfer the frame.
655
              masterState <= STATE_WAIT_TARGET_WRITE;
656
            else
657
              -- The target port has no empty buffer to receive the frame.
658
              -- Terminate the cycle and retry later.
659
              masterCyc_o <= '0';
660
              masterStb_o <= '0';
661
              masterState <= STATE_READ_TARGET_PORT;
662
            end if;
663
          else
664
            -- Target port has not completed the request.
665
            -- Dont to anything.
666
          end if;
667
 
668
        when STATE_WAIT_TARGET_WRITE =>
669
          ---------------------------------------------------------------------
670
          -- Wait for the write access to complete. When complete, write the
671
          -- next content and update the content to the next. If the frame does
672
          -- not have any more data ready, terminate the access but keep the
673
          -- cycle active and proceed to wait for new data.
674
          ---------------------------------------------------------------------
675
 
676
          -- Wait for the target port to complete the request.
677
          -- REMARK: Remove the ack-condition, we know that the write takes one
678
          -- cycle...
679
          if (masterAck_i = '1') then
680
            -- The target port is ready.
681
 
682
            -- Check if the frame has ended.
683
            if (readContentEnd_i = '0') then
684
              -- The frame has not ended.
685
 
686
              -- There are more data to transfer.
687
              masterData_o <= readContentData_i;
688
              readContent_o <= '1';
689
            else
690
              -- There are no more data to transfer.
691
 
692
              -- Update to the next frame.
693
              readFrame_o <= '1';
694
 
695
              -- Tell the target port that the frame is complete.
696
              masterWe_o <= '1';
697
              masterAddr_o(0) <= '0';
698
              masterData_o <= x"00000001";
699
 
700
              -- Change state to wait for the target port to finalize the write
701
              -- of the full frame.
702
              masterState <= STATE_WAIT_COMPLETE;
703
            end if;
704
          else
705
            -- Wait for the target port to reply.
706
            -- Dont do anything.
707
          end if;
708
 
709
        when STATE_WAIT_COMPLETE =>
710
          ---------------------------------------------------------------------
711
          -- Wait for the target port to signal that the frame has been
712
          -- completed.
713
          ---------------------------------------------------------------------
714
 
715
          -- Wait for the target port to complete the final request.
716
          if (masterAck_i = '1') then
717
            -- The target port has finalized the write of the frame.
718
 
719
            -- Reset master bus signals.
720
            masterCyc_o <= '0';
721
            masterStb_o <= '0';
722
            masterState <= STATE_IDLE;
723
          else
724
            -- Wait for the target port to reply.
725
            -- REMARK: Timeout here???
726
          end if;
727
 
728
        when others =>
729
          ---------------------------------------------------------------------
730
          -- 
731
          ---------------------------------------------------------------------
732
      end case;
733
    end if;
734
  end process;
735
 
736
  -----------------------------------------------------------------------------
737
  -- Slave interface process.
738
  -- Addr |  Read  | Write
739
  --    0 |  full  | abort & complete
740
  --    1 |  full  | frameData
741 46 magro732
  -----------------------------------------------------------------------------
742 2 magro732
  writeContentData_o <= slaveData_i;
743
  Slave: process(clk, areset_n)
744
  begin
745
    if (areset_n = '0') then
746
      slaveState <= STATE_IDLE;
747
 
748
      slaveData_o <= '0';
749
 
750 46 magro732
      writeFramePort_o <= (others=>'0');
751 2 magro732
      writeFrame_o <= '0';
752
      writeFrameAbort_o <= '0';
753
      writeContent_o <= '0';
754
    elsif (clk'event and clk = '1') then
755
      writeFrame_o <= '0';
756
      writeFrameAbort_o <= '0';
757
      writeContent_o <= '0';
758
 
759
      case slaveState is
760
 
761
        when STATE_IDLE =>
762
          ---------------------------------------------------------------------
763
          -- Wait for an access from a master.
764
          ---------------------------------------------------------------------
765
 
766
          -- Check if any cycle is active.
767
          if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then
768
            -- Cycle is active.
769
 
770
            -- Check if the cycle is accessing the status- or data address.
771
            if (slaveAddr_i(0) = '0') then
772
              -- Accessing port status address.
773
 
774
              -- Check if writing.
775
              if (slaveWe_i = '1') then
776
                -- Writing the status address.
777
                -- Update the buffering output signals according to the input
778
                -- data.
779 46 magro732
                writeFramePort_o <= slaveAddr_i(8 downto 1);
780 2 magro732
                writeFrame_o <= slaveData_i(0);
781
                writeFrameAbort_o <= slaveData_i(1);
782
              else
783
                -- Reading the status address.
784
                slaveData_o <= writeFrameFull_i;
785
              end if;
786
            else
787
              -- Accessing port data address.
788
 
789
              -- Check if writing.
790
              if (slaveWe_i = '1') then
791
                -- Write frame content into the frame buffer.
792
                writeContent_o <= '1';
793
              else
794
                slaveData_o <= writeFrameFull_i;
795
              end if;
796
            end if;
797
 
798
            -- Change state to send an ack to the master.
799
            slaveState <= STATE_SEND_ACK;
800
          end if;
801
 
802
        when STATE_SEND_ACK =>
803
          ---------------------------------------------------------------------
804
          -- Wait for acknowledge to be received by the master.
805
          ---------------------------------------------------------------------
806
 
807
          -- Go back to the idle state and wait for a new cycle.
808
          slaveState <= STATE_IDLE;
809
 
810
        when others =>
811
          ---------------------------------------------------------------------
812
          -- 
813
          ---------------------------------------------------------------------
814
          null;
815
 
816
      end case;
817
    end if;
818
  end process;
819
 
820
  -- Assign the acknowledge depending on the current slave state.
821
  slaveAck_o <= '1' when (slaveState = STATE_SEND_ACK) else '0';
822
 
823
end architecture;
824
 
825
 
826
 
827 46 magro732
 
828
 
829 2 magro732
-------------------------------------------------------------------------------
830
-- SwitchPortMaintenance
831
-------------------------------------------------------------------------------
832
 
833
library ieee;
834
use ieee.std_logic_1164.all;
835
use ieee.numeric_std.all;
836
use work.rio_common.all;
837
 
838
 
839
-------------------------------------------------------------------------------
840
-- Entity for SwitchPortMaintenance.
841
-------------------------------------------------------------------------------
842
entity SwitchPortMaintenance is
843
  generic(
844
    SWITCH_PORTS : natural range 0 to 255;
845
    DEVICE_IDENTITY : std_logic_vector(15 downto 0);
846
    DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
847
    DEVICE_REV : std_logic_vector(31 downto 0);
848
    ASSY_IDENTITY : std_logic_vector(15 downto 0);
849
    ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
850
    ASSY_REV : std_logic_vector(15 downto 0));
851
  port(
852
    clk : in std_logic;
853
    areset_n : in std_logic;
854
 
855
    -- Routing table port lookup signals.
856
    lookupStb_i : in std_logic;
857
    lookupAddr_i : in std_logic_vector(15 downto 0);
858
    lookupData_o : out std_logic_vector(7 downto 0);
859
    lookupAck_o : out std_logic;
860
 
861
    -- Master port signals.
862
    -- Write frames to other ports.
863
    masterCyc_o : out std_logic;
864
    masterStb_o : out std_logic;
865
    masterWe_o : out std_logic;
866
    masterAddr_o : out std_logic_vector(9 downto 0);
867
    masterData_o : out std_logic_vector(31 downto 0);
868
    masterData_i : in std_logic;
869
    masterAck_i : in std_logic;
870
 
871
    -- Slave port signals.
872
    -- Receives frames from other ports.
873
    slaveCyc_i : in std_logic;
874
    slaveStb_i : in std_logic;
875
    slaveWe_i : in std_logic;
876
    slaveAddr_i : in std_logic_vector(9 downto 0);
877
    slaveData_i : in std_logic_vector(31 downto 0);
878
    slaveData_o : out std_logic;
879
    slaveAck_o : out std_logic;
880
 
881
    -- Address-lookup interface.
882
    lookupStb_o : out std_logic;
883
    lookupAddr_o : out std_logic_vector(15 downto 0);
884
    lookupData_i : in std_logic_vector(7 downto 0);
885
    lookupAck_i : in std_logic;
886
 
887
    -- Port common access interface.
888
    portLinkTimeout_o : out std_logic_vector(23 downto 0);
889
 
890
    -- Port specific access interface.
891
    linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0);
892
    outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
893
    inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
894
    localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0);
895
    clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0);
896
    inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
897
    outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
898
    outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
899
    inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
900
    outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
901
    outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
902
 
903
    -- Configuration space for implementation-defined space.
904
    configStb_o : out std_logic;
905
    configWe_o : out std_logic;
906
    configAddr_o : out std_logic_vector(23 downto 0);
907
    configData_o : out std_logic_vector(31 downto 0);
908
    configData_i : in std_logic_vector(31 downto 0));
909
end entity;
910
 
911
 
912
-------------------------------------------------------------------------------
913
-- Architecture for SwitchPort.
914
-------------------------------------------------------------------------------
915
architecture SwitchPortMaintenanceImpl of SwitchPortMaintenance is
916
 
917 46 magro732
  component SwitchPort is
918 2 magro732
    generic(
919 46 magro732
      MAINTENANCE_LOOKUP : boolean;
920
      PORT_INDEX : natural);
921 2 magro732
    port(
922 46 magro732
      clk : in std_logic;
923
      areset_n : in std_logic;
924 2 magro732
 
925 46 magro732
      masterCyc_o : out std_logic;
926
      masterStb_o : out std_logic;
927
      masterWe_o : out std_logic;
928
      masterAddr_o : out std_logic_vector(9 downto 0);
929
      masterData_o : out std_logic_vector(31 downto 0);
930
      masterData_i : in std_logic;
931
      masterAck_i : in std_logic;
932
 
933
      slaveCyc_i : in std_logic;
934
      slaveStb_i : in std_logic;
935
      slaveWe_i : in std_logic;
936
      slaveAddr_i : in std_logic_vector(9 downto 0);
937
      slaveData_i : in std_logic_vector(31 downto 0);
938
      slaveData_o : out std_logic;
939
      slaveAck_o : out std_logic;
940
 
941
      lookupStb_o : out std_logic;
942
      lookupAddr_o : out std_logic_vector(15 downto 0);
943
      lookupData_i : in std_logic_vector(7 downto 0);
944
      lookupAck_i : in std_logic;
945
 
946
      readFrameEmpty_i : in std_logic;
947
      readFrame_o : out std_logic;
948
      readFrameRestart_o : out std_logic;
949
      readFrameAborted_i : in std_logic;
950
      readContentEmpty_i : in std_logic;
951
      readContent_o : out std_logic;
952
      readContentEnd_i : in std_logic;
953
      readContentData_i : in std_logic_vector(31 downto 0);
954
      writeFramePort_o : out std_logic_vector(7 downto 0);
955
      writeFrameFull_i : in std_logic;
956
      writeFrame_o : out std_logic;
957
      writeFrameAbort_o : out std_logic;
958
      writeContent_o : out std_logic;
959
      writeContentData_o : out std_logic_vector(31 downto 0));
960 2 magro732
  end component;
961 46 magro732
 
962
  -----------------------------------------------------------------------------
963
  -- Signals between the port and the packet-queue.
964
  -----------------------------------------------------------------------------
965 2 magro732
 
966 46 magro732
  signal outboundFramePort : std_logic_vector(7 downto 0);
967
  signal outboundReadFrameEmpty : std_logic;
968
  signal outboundReadFrame : std_logic;
969
  signal outboundReadContent : std_logic;
970
  signal outboundReadContentEnd : std_logic;
971
  signal outboundReadContentData : std_logic_vector(31 downto 0);
972
  signal inboundFramePort : std_logic_vector(7 downto 0);
973
  signal inboundWriteFrameFull : std_logic;
974
  signal inboundWriteFrame : std_logic;
975
  signal inboundWriteFrameAbort : std_logic;
976
  signal inboundWriteContent : std_logic;
977
  signal inboundWriteContentData : std_logic_vector(31 downto 0);
978 2 magro732
 
979 46 magro732
  -----------------------------------------------------------------------------
980
  -- Signals between the packet-queue and RioLogicalCommon.
981
  -----------------------------------------------------------------------------
982 2 magro732
 
983 46 magro732
  signal inboundReadFrameEmpty : std_logic;
984
  signal inboundReadFrame : std_logic;
985
  signal inboundReadContent : std_logic;
986
  signal inboundReadContentEnd : std_logic;
987
  signal inboundReadContentData : std_logic_vector(31 downto 0);
988
  signal outboundWriteFrameFull : std_logic;
989
  signal outboundWriteFrame : std_logic;
990
  signal outboundWriteFrameAbort : std_logic;
991
  signal outboundWriteContent : std_logic;
992
  signal outboundWriteContentData : std_logic_vector(31 downto 0);
993 2 magro732
 
994 46 magro732
  -----------------------------------------------------------------------------
995
  -- Signals between RioLogicalCommon and PacketHandler.
996
  -----------------------------------------------------------------------------
997 2 magro732
 
998 46 magro732
  signal inboundCyc : std_logic;
999
  signal inboundStb : std_logic;
1000
  signal inboundAdr : std_logic_vector(7 downto 0);
1001
  signal inboundDat : std_logic_vector(31 downto 0);
1002
  signal inboundAck : std_logic;
1003
  signal outboundCyc : std_logic_vector(0 downto 0);
1004
  signal outboundStb : std_logic_vector(0 downto 0);
1005
  signal outboundDat : std_logic_vector(31 downto 0);
1006
  signal outboundAck : std_logic_vector(0 downto 0);
1007 2 magro732
 
1008 46 magro732
  -----------------------------------------------------------------------------
1009
  -- Signals between PacketHandlers and maintenance controllers.
1010
  -----------------------------------------------------------------------------
1011 2 magro732
 
1012
  signal vc : std_logic;
1013
  signal crf : std_logic;
1014
  signal prio : std_logic_vector(1 downto 0);
1015
  signal tt : std_logic_vector(1 downto 0);
1016 46 magro732
  signal tid : std_logic_vector(7 downto 0);
1017 2 magro732
 
1018 46 magro732
  signal readRequestInbound : std_logic;
1019
  signal writeRequestInbound : std_logic;
1020
  signal readResponseInbound : std_logic;
1021
  signal writeResponseInbound : std_logic;
1022
  signal portWriteInbound : std_logic;
1023
  signal dstIdInbound : std_logic_vector(31 downto 0);
1024
  signal srcIdInbound : std_logic_vector(31 downto 0);
1025
  signal hopInbound : std_logic_vector(7 downto 0);
1026
  signal offsetInbound : std_logic_vector(20 downto 0);
1027
  signal wdptrInbound: std_logic;
1028
  signal payloadLengthInbound : std_logic_vector(3 downto 0);
1029
  signal payloadIndexInbound : std_logic_vector(3 downto 0);
1030
  signal payloadInbound : std_logic_vector(31 downto 0);
1031
  signal doneInbound : std_logic;
1032
 
1033
  signal readRequestOutbound : std_logic;
1034
  signal writeRequestOutbound : std_logic;
1035
  signal readResponseOutbound : std_logic;
1036
  signal writeResponseOutbound : std_logic;
1037
  signal portWriteOutbound : std_logic;
1038
  signal dstIdOutbound : std_logic_vector(31 downto 0);
1039
  signal srcIdOutbound : std_logic_vector(31 downto 0);
1040
  signal hopOutbound : std_logic_vector(7 downto 0);
1041
  signal wdptrOutbound: std_logic;
1042
  signal payloadLengthOutbound : std_logic_vector(3 downto 0);
1043
  signal payloadIndexOutbound : std_logic_vector(3 downto 0);
1044
  signal payloadOutbound : std_logic_vector(31 downto 0);
1045
  signal doneOutbound : std_logic;
1046
 
1047
  signal readRequestMaint : std_logic;
1048
  signal writeRequestMaint : std_logic;
1049
  signal readResponseMaint : std_logic;
1050
  signal writeResponseMaint : std_logic;
1051
  signal wdptrMaint : std_logic;
1052
  signal payloadLengthMaint : std_logic_vector(3 downto 0);
1053
  signal payloadIndexMaint : std_logic_vector(3 downto 0);
1054
  signal payloadMaint : std_logic_vector(31 downto 0);
1055
  signal doneMaint : std_logic;
1056
 
1057 2 magro732
  -----------------------------------------------------------------------------
1058 46 magro732
  -- 
1059
  -----------------------------------------------------------------------------
1060
 
1061
  signal sendPacket : std_logic;
1062
  signal forwardPacket : std_logic;
1063
 
1064
  -----------------------------------------------------------------------------
1065 2 magro732
  -- Route table access signals.
1066
  -----------------------------------------------------------------------------
1067
 
1068
  signal lookupEnable : std_logic;
1069
  signal lookupAddress : std_logic_vector(10 downto 0);
1070
  signal lookupData : std_logic_vector(7 downto 0);
1071
  signal lookupAck : std_logic;
1072
 
1073
  signal routeTableEnable : std_logic;
1074
  signal routeTableWrite : std_logic;
1075
  signal routeTableAddress : std_logic_vector(10 downto 0);
1076
  signal routeTablePortWrite : std_logic_vector(7 downto 0);
1077
  signal routeTablePortRead : std_logic_vector(7 downto 0);
1078
 
1079
  signal routeTablePortDefault : std_logic_vector(7 downto 0);
1080
 
1081
  -----------------------------------------------------------------------------
1082
  -- Configuration space signals.
1083
  -----------------------------------------------------------------------------
1084 46 magro732
 
1085
  signal configStb : std_logic;
1086
  signal configWe : std_logic;
1087
  signal configAdr : std_logic_vector(23 downto 0);
1088
  signal configDataWrite : std_logic_vector(31 downto 0);
1089
  signal configDataRead, configDataReadInternal : std_logic_vector(31 downto 0);
1090
  signal configAck : std_logic;
1091
 
1092
  -- REMARK: Make these variables instead...
1093 2 magro732
  signal discovered : std_logic;
1094
  signal hostBaseDeviceIdLocked : std_logic;
1095
  signal hostBaseDeviceId : std_logic_vector(15 downto 0);
1096
  signal componentTag : std_logic_vector(31 downto 0);
1097
  signal portLinkTimeout : std_logic_vector(23 downto 0);
1098
  signal outputPortEnable : Array1(SWITCH_PORTS-1 downto 0);
1099
  signal inputPortEnable : Array1(SWITCH_PORTS-1 downto 0);
1100
 
1101
begin
1102
 
1103
  -----------------------------------------------------------------------------
1104 46 magro732
  -- Normal switch port instance interfacing the switch interconnect.
1105 2 magro732
  -----------------------------------------------------------------------------
1106 46 magro732
  -- REMARK: PORT_INDEX is not used in this instantiation.
1107
  -- REMARK: Add generic to disable the maintenance routing to this port...
1108
  PortInst: SwitchPort
1109 2 magro732
    generic map(
1110 46 magro732
      MAINTENANCE_LOOKUP=>true,
1111
      PORT_INDEX=>0)
1112 2 magro732
    port map(
1113 46 magro732
      clk=>clk, areset_n=>areset_n,
1114
      masterCyc_o=>masterCyc_o,
1115
      masterStb_o=>masterStb_o,
1116
      masterWe_o=>masterWe_o,
1117
      masterAddr_o=>masterAddr_o,
1118
      masterData_o=>masterData_o,
1119
      masterData_i=>masterData_i,
1120
      masterAck_i=>masterAck_i,
1121
      slaveCyc_i=>slaveCyc_i,
1122
      slaveStb_i=>slaveStb_i,
1123
      slaveWe_i=>slaveWe_i,
1124
      slaveAddr_i=>slaveAddr_i,
1125
      slaveData_i=>slaveData_i,
1126
      slaveData_o=>slaveData_o,
1127
      slaveAck_o=>slaveAck_o,
1128
      lookupStb_o=>open,
1129
      lookupAddr_o=>open,
1130
      lookupData_i=>outboundFramePort,
1131
      lookupAck_i=>'1',
1132
      readFrameEmpty_i=>outboundReadFrameEmpty,
1133
      readFrame_o=>outboundReadFrame,
1134
      readFrameRestart_o=>open,
1135
      readFrameAborted_i=>'0',
1136
      readContentEmpty_i=>'0',
1137
      readContent_o=>outboundReadContent,
1138
      readContentEnd_i=>outboundReadContentEnd,
1139
      readContentData_i=>outboundReadContentData,
1140
      writeFramePort_o=>inboundFramePort,
1141
      writeFrameFull_i=>inboundWriteFrameFull,
1142
      writeFrame_o=>inboundWriteFrame,
1143
      writeFrameAbort_o=>inboundWriteFrameAbort,
1144
      writeContent_o=>inboundWriteContent,
1145
      writeContentData_o=>inboundWriteContentData);
1146
 
1147
  -----------------------------------------------------------------------------
1148
  -- Packet queue.
1149
  -- This queue should only contain one packet.
1150
  -----------------------------------------------------------------------------
1151
  -- REMARK: Use a packet-buffer with a configurable maximum sized packet...
1152
  PacketQueue: RioPacketBuffer
1153
    generic map(SIZE_ADDRESS_WIDTH=>1, CONTENT_ADDRESS_WIDTH=>7)
1154
    port map(
1155
      clk=>clk, areset_n=>areset_n,
1156
      inboundWriteFrameFull_o=>inboundWriteFrameFull,
1157
      inboundWriteFrame_i=>inboundWriteFrame,
1158
      inboundWriteFrameAbort_i=>inboundWriteFrameAbort,
1159
      inboundWriteContent_i=>inboundWriteContent,
1160
      inboundWriteContentData_i=>inboundWriteContentData,
1161
      inboundReadFrameEmpty_o=>inboundReadFrameEmpty,
1162
      inboundReadFrame_i=>inboundReadFrame,
1163
      inboundReadFrameRestart_i=>'0',
1164
      inboundReadFrameAborted_o=>open,
1165
      inboundReadContentEmpty_o=>open,
1166
      inboundReadContent_i=>inboundReadContent,
1167
      inboundReadContentEnd_o=>inboundReadContentEnd,
1168
      inboundReadContentData_o=>inboundReadContentData,
1169
      outboundWriteFrameFull_o=>outboundWriteFrameFull,
1170
      outboundWriteFrame_i=>outboundWriteFrame,
1171
      outboundWriteFrameAbort_i=>outboundWriteFrameAbort,
1172
      outboundWriteContent_i=>outboundWriteContent,
1173
      outboundWriteContentData_i=>outboundWriteContentData,
1174
      outboundReadFrameEmpty_o=>outboundReadFrameEmpty,
1175
      outboundReadFrame_i=>outboundReadFrame,
1176
      outboundReadFrameRestart_i=>'0',
1177
      outboundReadFrameAborted_o=>open,
1178
      outboundReadContentEmpty_o=>open,
1179
      outboundReadContent_i=>outboundReadContent,
1180
      outboundReadContentEnd_o=>outboundReadContentEnd,
1181
      outboundReadContentData_o=>outboundReadContentData);
1182 2 magro732
 
1183
  -----------------------------------------------------------------------------
1184 46 magro732
  -- Logical common packet parser.
1185
  -- This module removes CRC and unpack addresses in the inbound direction and
1186
  -- adds CRC and packs addresses in the outbound direction.
1187 2 magro732
  -----------------------------------------------------------------------------
1188 46 magro732
  LogicalCommon: RioLogicalCommon
1189
    generic map(PORTS=>1)
1190
    port map(
1191
      clk=>clk, areset_n=>areset_n, enable=>'1',
1192
      readFrameEmpty_i=>inboundReadFrameEmpty,
1193
      readFrame_o=>inboundReadFrame,
1194
      readContent_o=>inboundReadContent,
1195
      readContentEnd_i=>inboundReadContentEnd,
1196
      readContentData_i=>inboundReadContentData,
1197
      writeFrameFull_i=>outboundWriteFrameFull,
1198
      writeFrame_o=>outboundWriteFrame,
1199
      writeFrameAbort_o=>outboundWriteFrameAbort,
1200
      writeContent_o=>outboundWriteContent,
1201
      writeContentData_o=>outboundWriteContentData,
1202
      inboundCyc_o=>inboundCyc,
1203
      inboundStb_o=>inboundStb,
1204
      inboundAdr_o=>inboundAdr,
1205
      inboundDat_o=>inboundDat,
1206
      inboundAck_i=>inboundAck,
1207
      outboundCyc_i=>outboundCyc,
1208
      outboundStb_i=>outboundStb,
1209
      outboundDat_i=>outboundDat,
1210
      outboundAck_o=>outboundAck);
1211 2 magro732
 
1212 46 magro732
  -----------------------------------------------------------------------------
1213
  -- Inbound maintenance packet parser.
1214
  -- Unpack inbound maintenance packets.
1215
  -----------------------------------------------------------------------------
1216
  -- REMARK: add another receiver that discards all other packet types...
1217
  -- REMARK: Connect enable to something...
1218
  payloadIndexInbound <= payloadIndexOutbound when (forwardPacket = '1') else payloadIndexMaint;
1219
  doneInbound <= doneOutbound when (forwardPacket = '1') else doneMaint;
1220
  InboundPacket: MaintenanceInbound
1221 2 magro732
    port map(
1222 46 magro732
      clk=>clk, areset_n=>areset_n, enable=>'1',
1223
      readRequestReady_o=>readRequestInbound,
1224
      writeRequestReady_o=>writeRequestInbound,
1225
      readResponseReady_o=>readResponseInbound,
1226
      writeResponseReady_o=>writeResponseInbound,
1227
      portWriteReady_o=>portWriteInbound,
1228
      vc_o=>vc,
1229
      crf_o=>crf,
1230
      prio_o=>prio,
1231
      tt_o=>tt,
1232
      dstid_o=>dstIdInbound,
1233
      srcid_o=>srcIdInbound,
1234
      tid_o=>tid,
1235
      hop_o=>hopInbound,
1236
      offset_o=>offsetInbound,
1237
      wdptr_o=>wdptrInbound,
1238
      payloadLength_o=>payloadLengthInbound,
1239
      payloadIndex_i=>payloadIndexInbound,
1240
      payload_o=>payloadInbound,
1241
      done_i=>doneInbound,
1242
      inboundCyc_i=>inboundCyc,
1243
      inboundStb_i=>inboundStb,
1244
      inboundAdr_i=>inboundAdr,
1245
      inboundDat_i=>inboundDat,
1246
      inboundAck_o=>inboundAck);
1247
 
1248
  -----------------------------------------------------------------------------
1249
  -- Outbound maintenance packet generator.
1250
  -----------------------------------------------------------------------------
1251
  readRequestOutbound <= (readRequestInbound and sendPacket) when (forwardPacket = '1') else '0';
1252
  writeRequestOutbound <= (writeRequestInbound and sendPacket) when (forwardPacket = '1') else '0';
1253
  readResponseOutbound <= (readResponseInbound and sendPacket) when (forwardPacket = '1') else readResponseMaint;
1254
  writeResponseOutbound <= (writeResponseInbound and sendPacket) when (forwardPacket = '1') else writeResponseMaint;
1255
  portWriteOutbound <= (portWriteInbound and sendPacket) when (forwardPacket = '1') else '0';
1256
  srcIdOutbound <= srcIdInbound when (forwardPacket = '1') else dstIdInbound;
1257
  dstIdOutbound <= dstIdInbound when (forwardPacket = '1') else srcIdInbound;
1258
  hopOutbound <= std_logic_vector(unsigned(hopInbound)-1) when (forwardPacket = '1') else x"ff";
1259
  wdptrOutbound <= wdptrInbound when (forwardPacket = '1') else wdptrMaint;
1260
  payloadLengthOutbound <= payloadLengthInbound when (forwardPacket = '1') else payloadLengthMaint;
1261
  payloadOutbound <= payloadInbound when (forwardPacket = '1') else payloadMaint;
1262
  -- REMARK: Connect enable to something...
1263
  OutboundPacket: MaintenanceOutbound
1264 2 magro732
    port map(
1265 46 magro732
      clk=>clk, areset_n=>areset_n, enable=>'1',
1266
      readRequestReady_i=>readRequestOutbound,
1267
      writeRequestReady_i=>writeRequestOutbound,
1268
      readResponseReady_i=>readResponseOutbound,
1269
      writeResponseReady_i=>writeResponseOutbound,
1270
      portWriteReady_i=>portWriteOutbound,
1271
      vc_i=>vc,
1272
      crf_i=>crf,
1273
      prio_i=>prio,
1274
      tt_i=>tt,
1275
      dstid_i=>dstIdOutbound,
1276
      srcid_i=>srcIdOutbound,
1277
      status_i=>"0000",
1278
      tid_i=>tid,
1279
      hop_i=>hopOutbound,
1280
      offset_i=>offsetInbound,
1281
      wdptr_i=>wdptrOutbound,
1282
      payloadLength_i=>payloadLengthOutbound,
1283
      payloadIndex_o=>payloadIndexOutbound,
1284
      payload_i=>payloadOutbound,
1285
      done_o=>doneOutbound,
1286
      outboundCyc_o=>outboundCyc(0),
1287
      outboundStb_o=>outboundStb(0),
1288
      outboundDat_o=>outboundDat,
1289
      outboundAck_i=>outboundAck(0));
1290
 
1291 2 magro732
  -----------------------------------------------------------------------------
1292 46 magro732
  -- Main switch maintenance controller.
1293
  -- This controller decides when to forward packets and when to consume and
1294
  -- produce responses instead.
1295
  -- It also determines when portWrite-packets are allowed to be sent.
1296 2 magro732
  -----------------------------------------------------------------------------
1297 46 magro732
  RioSwitchMaintenance: process(clk, areset_n)
1298
    type MasterStateType is (STATE_IDLE,
1299
                             STATE_START_PORT_LOOKUP,
1300
                             STATE_READ_PORT_LOOKUP,
1301
                             STATE_WAIT_COMPLETE);
1302
    variable masterState : MasterStateType;
1303 2 magro732
  begin
1304
    if (areset_n = '0') then
1305 46 magro732
      masterState := STATE_IDLE;
1306 2 magro732
 
1307 46 magro732
      sendPacket <= '0';
1308
      forwardPacket <= '0';
1309
      outboundFramePort <= (others=>'0');
1310
 
1311 2 magro732
      lookupStb_o <= '0';
1312
      lookupAddr_o <= (others => '0');
1313
    elsif (clk'event and clk = '1') then
1314
      case masterState is
1315
 
1316
        when STATE_IDLE =>
1317
          ---------------------------------------------------------------------
1318
          -- 
1319
          ---------------------------------------------------------------------
1320 46 magro732
          -- Wait for frame to be available.
1321
          -- REMARK: Discard erronous frames.
1322
          sendPacket <= '0';
1323
          if (((readRequestInbound = '1') or (writeRequestInbound = '1')) and (hopInbound = x"00")) then
1324
            masterState := STATE_WAIT_COMPLETE;
1325
            forwardPacket <= '0';
1326
            outboundFramePort <= inboundFramePort;
1327
          elsif (((readResponseInbound = '1') or ((readRequestInbound = '1') and (hopInbound /= x"00"))) or
1328
                 ((writeResponseInbound = '1') or ((writeRequestInbound = '1') and (hopInbound /= x"00"))) or
1329
                 (portWriteInbound = '1')) then
1330
            masterState := STATE_START_PORT_LOOKUP;
1331
            forwardPacket <= '1';
1332 2 magro732
          end if;
1333
 
1334
        when STATE_START_PORT_LOOKUP =>
1335
          ---------------------------------------------------------------------
1336
          -- 
1337
          ---------------------------------------------------------------------
1338
 
1339
          -- Initiate a port-lookup of the destination address.
1340
          lookupStb_o <= '1';
1341 46 magro732
          lookupAddr_o <= dstIdInbound(15 downto 0);
1342
          masterState := STATE_READ_PORT_LOOKUP;
1343 2 magro732
 
1344
        when STATE_READ_PORT_LOOKUP =>
1345
          ---------------------------------------------------------------------
1346
          -- 
1347
          ---------------------------------------------------------------------
1348
 
1349
          -- Wait for the routing table to complete the request.
1350
          if (lookupAck_i = '1') then
1351
            -- The address lookup is complete.
1352
 
1353
            -- Terminate the lookup cycle.
1354
            lookupStb_o <= '0';
1355
 
1356
            -- Wait for the target port to reply.
1357 46 magro732
            outboundFramePort <= lookupData_i;
1358
            masterState := STATE_WAIT_COMPLETE;
1359 2 magro732
          else
1360
            -- Wait until the address lookup is complete.
1361
            -- REMARK: Timeout here???
1362
          end if;
1363
 
1364
        when STATE_WAIT_COMPLETE =>
1365
          ---------------------------------------------------------------------
1366
          -- 
1367
          ---------------------------------------------------------------------
1368 46 magro732
          -- REMARK: Wait for the packet to be fully transmitted to the target
1369
          -- port. Then reset everything for the reception of a new packet.
1370
          sendPacket <= '1';
1371
          if (doneOutbound = '1') then
1372
            masterState := STATE_IDLE;
1373 2 magro732
          end if;
1374
 
1375
        when others =>
1376
          ---------------------------------------------------------------------
1377
          -- 
1378
          ---------------------------------------------------------------------
1379
      end case;
1380
    end if;
1381
  end process;
1382
 
1383
  -----------------------------------------------------------------------------
1384 46 magro732
  -- Bridge between the inbound RapidIO maintenance packets to the internal
1385
  -- config-space bus.
1386 2 magro732
  -----------------------------------------------------------------------------
1387 46 magro732
  -- REMARK: Connect enable...
1388
  readRequestMaint <= (readRequestInbound and sendPacket) when (forwardPacket = '0') else '0';
1389
  writeRequestMaint <= (writeRequestInbound and sendPacket) when (forwardPacket = '0') else '0';
1390
  MaintenanceBridge: RioLogicalMaintenance
1391 2 magro732
    port map(
1392 46 magro732
      clk=>clk, areset_n=>areset_n, enable=>'1',
1393
      readRequestReady_i=>readRequestMaint,
1394
      writeRequestReady_i=>writeRequestMaint,
1395
      offset_i=>offsetInbound,
1396
      wdptr_i=>wdptrInbound,
1397
      payloadLength_i=>payloadLengthInbound,
1398
      payloadIndex_o=>payloadIndexMaint,
1399
      payload_i=>payloadInbound,
1400
      done_o=>doneMaint,
1401
      readResponseReady_o=>readResponseMaint,
1402
      writeResponseReady_o=>writeResponseMaint,
1403
      wdptr_o=>wdptrMaint,
1404
      payloadLength_o=>payloadLengthMaint,
1405
      payloadIndex_i=>payloadIndexOutbound,
1406
      payload_o=>payloadMaint,
1407
      done_i=>doneOutbound,
1408
      configStb_o=>configStb,
1409
      configWe_o=>configWe,
1410
      configAdr_o=>configAdr(23 downto 2),
1411
      configDat_o=>configDataWrite,
1412
      configDat_i=>configDataRead,
1413
      configAck_i=>configAck);
1414
  configAdr(1 downto 0) <= "00";
1415 2 magro732
 
1416
  -----------------------------------------------------------------------------
1417 46 magro732
  -- Switch configuration memory.
1418 2 magro732
  -----------------------------------------------------------------------------
1419
  portLinkTimeout_o <= portLinkTimeout;
1420
  outputPortEnable_o <= outputPortEnable;
1421
  inputPortEnable_o <= inputPortEnable;
1422 46 magro732
 
1423
  -- REMARK: Connect configAck...
1424
  configStb_o <= '1' when ((configStb = '1') and (configAdr(23 downto 16) /= x"00")) else '0';
1425
  configWe_o <= configWe;
1426
  configAddr_o <= configAdr;
1427 2 magro732
  configData_o <= configDataWrite;
1428 46 magro732
  configDataRead <= configData_i when (configAdr(23 downto 16) /= x"00") else
1429 2 magro732
                    configDataReadInternal;
1430
 
1431
  ConfigMemory: process(areset_n, clk)
1432
  begin
1433
    if (areset_n = '0') then
1434
      configDataReadInternal <= (others => '0');
1435 46 magro732
      configAck <= '0';
1436 2 magro732
 
1437
      routeTableEnable <= '1';
1438
      routeTableWrite <= '0';
1439
      routeTableAddress <= (others => '0');
1440
      routeTablePortWrite <= (others => '0');
1441
      routeTablePortDefault <= (others => '0');
1442
 
1443
      discovered <= '0';
1444
 
1445
      hostBaseDeviceIdLocked <= '0';
1446
      hostBaseDeviceId <= (others => '1');
1447
      componentTag <= (others => '0');
1448
 
1449
      portLinkTimeout <= (others => '1');
1450
 
1451
      -- REMARK: These should be set to zero when a port gets initialized...
1452
      outputPortEnable <= (others => '0');
1453
      inputPortEnable <= (others => '0');
1454
 
1455
      localAckIdWrite_o <= (others => '0');
1456
    elsif (clk'event and clk = '1') then
1457
      routeTableWrite <= '0';
1458
      localAckIdWrite_o <= (others => '0');
1459
 
1460 46 magro732
      if (configAck = '0') then
1461
        if (configStb = '1') then
1462
          configAck <= '1';
1463 2 magro732
 
1464 46 magro732
          -- Check if the access is into implementation defined space or if the
1465
          -- access should be handled here.
1466
          if (configAdr(23 downto 16) /= x"00") then
1467
            -- Accessing implementation defined space.
1468
            -- Make an external access and return the resonse.
1469
            configDataReadInternal <= (others=>'0');
1470
          else
1471
            -- Access should be handled here.
1472
 
1473
            case (configAdr) is
1474
              when x"000000" =>
1475
                -----------------------------------------------------------------
1476
                -- Device Identity CAR. Read-only.
1477
                -----------------------------------------------------------------
1478 2 magro732
 
1479 46 magro732
                configDataReadInternal(31 downto 16) <= DEVICE_IDENTITY;
1480
                configDataReadInternal(15 downto 0) <= DEVICE_VENDOR_IDENTITY;
1481
 
1482
              when x"000004" =>
1483
                -----------------------------------------------------------------
1484
                -- Device Information CAR. Read-only.
1485
                -----------------------------------------------------------------
1486 2 magro732
 
1487 46 magro732
                configDataReadInternal(31 downto 0) <= DEVICE_REV;
1488
 
1489
              when x"000008" =>
1490
                -----------------------------------------------------------------
1491
                -- Assembly Identity CAR. Read-only.
1492
                -----------------------------------------------------------------
1493 2 magro732
 
1494 46 magro732
                configDataReadInternal(31 downto 16) <= ASSY_IDENTITY;
1495
                configDataReadInternal(15 downto 0) <= ASSY_VENDOR_IDENTITY;
1496
 
1497
              when x"00000c" =>
1498
                -----------------------------------------------------------------
1499
                -- Assembly Informaiton CAR. Read-only.
1500
                -----------------------------------------------------------------
1501 2 magro732
 
1502 46 magro732
                configDataReadInternal(31 downto 16) <= ASSY_REV;
1503
                configDataReadInternal(15 downto 0) <= x"0100";
1504
 
1505
              when x"000010" =>
1506
                -----------------------------------------------------------------
1507
                -- Processing Element Features CAR. Read-only.
1508
                -----------------------------------------------------------------
1509
 
1510
                -- Bridge.
1511
                configDataReadInternal(31) <= '0';
1512
 
1513
                -- Memory.
1514
                configDataReadInternal(30) <= '0';
1515
 
1516
                -- Processor.
1517
                configDataReadInternal(29) <= '0';
1518
 
1519
                -- Switch.
1520
                configDataReadInternal(28) <= '1';
1521
 
1522
                -- Reserved.
1523
                configDataReadInternal(27 downto 10) <= (others => '0');
1524
 
1525
                -- Extended route table configuration support.
1526
                configDataReadInternal(9) <= '0';
1527
 
1528
                -- Standard route table configuration support.
1529
                configDataReadInternal(8) <= '1';
1530
 
1531
                -- Reserved.
1532
                configDataReadInternal(7 downto 5) <= (others => '0');
1533
 
1534
                -- Common transport large system support.
1535
                configDataReadInternal(4) <= '1';
1536
 
1537
                -- Extended features.
1538
                configDataReadInternal(3) <= '1';
1539
 
1540
                -- Extended addressing support.
1541
                -- Not a processing element.
1542
                configDataReadInternal(2 downto 0) <= "000";
1543
 
1544
              when x"000014" =>
1545
                -----------------------------------------------------------------
1546
                -- Switch Port Information CAR. Read-only.
1547
                -----------------------------------------------------------------
1548 2 magro732
 
1549 46 magro732
                -- Reserved.
1550
                configDataReadInternal(31 downto 16) <= (others => '0');
1551 2 magro732
 
1552 46 magro732
                -- PortTotal.
1553
                configDataReadInternal(15 downto 8) <=
1554
                  std_logic_vector(to_unsigned(SWITCH_PORTS, 8));
1555 2 magro732
 
1556 46 magro732
                -- PortNumber.
1557
                configDataReadInternal(7 downto 0) <= inboundFramePort;
1558
 
1559
              when x"000034" =>
1560
                -----------------------------------------------------------------
1561
                -- Switch Route Table Destination ID Limit CAR.
1562
                -----------------------------------------------------------------
1563 2 magro732
 
1564 46 magro732
                -- Max_destId.
1565
                -- Support 2048 addresses.
1566
                configDataReadInternal(15 downto 0) <= x"0800";
1567
 
1568
              when x"000068" =>
1569
                -----------------------------------------------------------------
1570
                -- Host Base Device ID Lock CSR.
1571
                -----------------------------------------------------------------
1572 2 magro732
 
1573 46 magro732
                if (configWe = '1') then
1574
                  -- Check if this field has been written before.
1575
                  if (hostBaseDeviceIdLocked = '0') then
1576
                    -- The field has not been written.
1577
                    -- Lock the field and set the host base device id.
1578
                    hostBaseDeviceIdLocked <= '1';
1579
                    hostBaseDeviceId <= configDataWrite(15 downto 0);
1580 2 magro732
                  else
1581 46 magro732
                    -- The field has been written.
1582
                    -- Check if the written data is the same as the stored.
1583
                    if (hostBaseDeviceId = configDataWrite(15 downto 0)) then
1584
                      -- Same as stored, reset the value to its initial value.
1585
                      hostBaseDeviceIdLocked <= '0';
1586
                      hostBaseDeviceId <= (others => '1');
1587
                    else
1588
                      -- Not writing the same as the stored value.
1589
                      -- Ignore the write.
1590
                    end if;
1591 2 magro732
                  end if;
1592
                end if;
1593 46 magro732
 
1594
                configDataReadInternal(31 downto 16) <= (others => '0');
1595
                configDataReadInternal(15 downto 0) <= hostBaseDeviceId;
1596
 
1597
              when x"00006c" =>
1598
                -----------------------------------------------------------------
1599
                -- Component TAG CSR.
1600
                -----------------------------------------------------------------
1601 2 magro732
 
1602 46 magro732
                if (configWe = '1') then
1603
                  componentTag <= configDataWrite;
1604
                end if;
1605
 
1606
                configDataReadInternal <= componentTag;
1607
 
1608
              when x"000070" =>
1609
                -----------------------------------------------------------------
1610
                -- Standard Route Configuration Destination ID Select CSR.
1611
                -----------------------------------------------------------------             
1612 2 magro732
 
1613 46 magro732
                if (configWe = '1') then
1614
                  -- Write the address to access the routing table.
1615
                  routeTableAddress <= configDataWrite(10 downto 0);
1616
                end if;
1617
 
1618
                configDataReadInternal(31 downto 11) <= (others => '0');
1619
                configDataReadInternal(10 downto 0) <= routeTableAddress;
1620
 
1621
              when x"000074" =>
1622
                -----------------------------------------------------------------
1623
                -- Standard Route Configuration Port Select CSR.
1624
                -----------------------------------------------------------------
1625 2 magro732
 
1626 46 magro732
                if (configWe = '1') then
1627
                  -- Write the port information for the address selected by the
1628
                  -- above register.
1629
                  routeTableWrite <= '1';
1630
                  routeTablePortWrite <= configDataWrite(7 downto 0);
1631
                end if;
1632 2 magro732
 
1633 46 magro732
                configDataReadInternal(31 downto 8) <= (others => '0');
1634
                configDataReadInternal(7 downto 0) <= routeTablePortRead;
1635
 
1636
              when x"000078" =>
1637
                -----------------------------------------------------------------
1638
                -- Standard Route Default Port CSR.
1639
                -----------------------------------------------------------------
1640 2 magro732
 
1641 46 magro732
                if (configWe = '1') then
1642
                  -- Write the default route device id.
1643
                  routeTablePortDefault <= configDataWrite(7 downto 0);
1644
                end if;
1645
 
1646
                configDataReadInternal(31 downto 8) <= (others => '0');
1647
                configDataReadInternal(7 downto 0) <= routeTablePortDefault;
1648
 
1649
              when x"000100" =>
1650
                -----------------------------------------------------------------
1651
                -- Extended features. LP-Serial Register Block Header.
1652
                -----------------------------------------------------------------
1653 2 magro732
 
1654 46 magro732
                -- One feature only, 0x0003=Generic End Point Free Device.
1655
                configDataReadInternal(31 downto 16) <= x"0000";
1656
                configDataReadInternal(15 downto 0) <= x"0003";
1657
 
1658
              when x"000120" =>
1659
                -----------------------------------------------------------------
1660
                -- Port Link Timeout Control CSR.
1661
                -----------------------------------------------------------------
1662 2 magro732
 
1663 46 magro732
                if (configWe = '1') then
1664
                  portLinkTimeout <= configDataWrite(31 downto 8);
1665
                end if;
1666
 
1667
                configDataReadInternal(31 downto 8) <= portLinkTimeout;
1668
                configDataReadInternal(7 downto 0) <= x"00";
1669
 
1670
              when x"00013c" =>
1671
                -----------------------------------------------------------------
1672
                -- Port General Control CSR.
1673
                -----------------------------------------------------------------
1674 2 magro732
 
1675 46 magro732
                if (configWe = '1') then
1676
                  discovered <= configDataWrite(29);
1677
                end if;
1678
 
1679
                configDataReadInternal(31 downto 30) <= "00";
1680
                configDataReadInternal(29) <= discovered;
1681
                configDataReadInternal(28 downto 0) <= (others => '0');
1682 2 magro732
 
1683 46 magro732
              when others =>
1684
                -----------------------------------------------------------------
1685
                -- Other port specific registers.
1686
                -----------------------------------------------------------------
1687
 
1688
                -- Make sure the output is always set to something.
1689
                configDataReadInternal <= (others=>'0');
1690 2 magro732
 
1691 46 magro732
                -- Iterate through all active ports.
1692
                for portIndex in 0 to SWITCH_PORTS-1 loop
1693 2 magro732
 
1694 46 magro732
                  if(unsigned(configAdr) = (x"000148" + (x"000020"*portIndex))) then
1695
                    -----------------------------------------------------------------
1696
                    -- Port N Local ackID CSR.
1697
                    -----------------------------------------------------------------
1698
                    if (configWe = '1') then
1699
                      localAckIdWrite_o(portIndex) <= '1';
1700
                      clrOutstandingAckId_o(portIndex) <= configDataWrite(31);
1701
                      inboundAckId_o(portIndex) <= configDataWrite(28 downto 24);
1702
                      outstandingAckId_o(portIndex) <= configDataWrite(12 downto 8);
1703
                      outboundAckId_o(portIndex) <= configDataWrite(4 downto 0);
1704
                    end if;
1705
                    configDataReadInternal(31 downto 29) <= (others => '0');
1706
                    configDataReadInternal(28 downto 24) <= inboundAckId_i(portIndex);
1707
                    configDataReadInternal(23 downto 13) <= (others => '0');
1708
                    configDataReadInternal(12 downto 8) <= outstandingAckId_i(portIndex);
1709
                    configDataReadInternal(7 downto 5) <= (others => '0');
1710
                    configDataReadInternal(4 downto 0) <= outboundAckId_i(portIndex);
1711
 
1712
                  elsif(unsigned(configAdr) = (x"000154" + (x"000020"*portIndex))) then
1713
                    -----------------------------------------------------------------
1714
                    -- Port N Control 2 CSR.
1715
                    -----------------------------------------------------------------
1716
                    configDataReadInternal <= (others => '0');
1717
 
1718
                  elsif(unsigned(configAdr) = (x"000158" + (x"000020"*portIndex))) then
1719
                    -----------------------------------------------------------------
1720
                    -- Port N Error and Status CSR.
1721
                    -----------------------------------------------------------------
1722
                    -- Idle Sequence 2 Support.
1723
                    configDataReadInternal(31) <= '0';
1724
 
1725
                    -- Idle Sequence 2 Enable.
1726
                    configDataReadInternal(30) <= '0';
1727
 
1728
                    -- Idle Sequence.
1729
                    configDataReadInternal(29) <= '0';
1730
 
1731
                    -- Reserved.
1732
                    configDataReadInternal(28) <= '0';
1733
 
1734
                    -- Flow Control Mode.
1735
                    configDataReadInternal(27) <= '0';
1736
 
1737
                    -- Reserved.
1738
                    configDataReadInternal(26 downto 21) <= (others => '0');
1739
 
1740
                    -- Output retry-encountered.
1741
                    configDataReadInternal(20) <= '0';
1742
 
1743
                    -- Output retried.
1744
                    configDataReadInternal(19) <= '0';
1745
 
1746
                    -- Output retried-stopped.
1747
                    configDataReadInternal(18) <= '0';
1748
 
1749
                    -- Output error-encountered.
1750
                    configDataReadInternal(17) <= '0';
1751
 
1752
                    -- Output error-stopped.
1753
                    configDataReadInternal(16) <= '0';
1754
 
1755
                    -- Reserved.
1756
                    configDataReadInternal(15 downto 11) <= (others => '0');
1757
 
1758
                    -- Input retry-stopped.
1759
                    configDataReadInternal(10) <= '0';
1760
 
1761
                    -- Input error-encountered.
1762
                    configDataReadInternal(9) <= '0';
1763
 
1764
                    -- Input error-stopped.
1765
                    configDataReadInternal(8) <= '0';
1766 2 magro732
 
1767 46 magro732
                    -- Reserved.
1768
                    configDataReadInternal(7 downto 5) <= (others => '0');
1769 2 magro732
 
1770 46 magro732
                    -- Port-write pending.
1771
                    configDataReadInternal(4) <= '0';
1772
 
1773
                    -- Port unavailable.
1774
                    configDataReadInternal(3) <= '0';
1775
 
1776
                    -- Port error.
1777
                    configDataReadInternal(2) <= '0';
1778
 
1779
                    -- Port OK.
1780
                    configDataReadInternal(1) <= linkInitialized_i(portIndex);
1781
 
1782
                    -- Port uninitialized.
1783
                    configDataReadInternal(0) <= not linkInitialized_i(portIndex);
1784
 
1785
                  elsif(unsigned(configAdr) = (x"00015c" + (x"000020"*portIndex))) then
1786
                    -----------------------------------------------------------------
1787
                    -- Port N Control CSR.
1788
                    -----------------------------------------------------------------
1789
 
1790
                    -- Port Width Support.
1791
                    configDataReadInternal(31 downto 30) <= (others=>'0');
1792 2 magro732
 
1793 46 magro732
                    -- Initialized Port Width.
1794
                    configDataReadInternal(29 downto 27) <= (others=>'0');
1795 2 magro732
 
1796 46 magro732
                    -- Port Width Override.
1797
                    configDataReadInternal(26 downto 24) <= (others=>'0');
1798 2 magro732
 
1799 46 magro732
                    -- Port disable.
1800
                    configDataReadInternal(23) <= '0';
1801
 
1802
                    -- Output Port Enable.
1803
                    if (configWe = '1') then
1804
                      outputPortEnable(portIndex) <= configDataWrite(22);
1805
                    end if;
1806
                    configDataReadInternal(22) <= outputPortEnable(portIndex);
1807
 
1808
                    -- Input Port Enable.
1809
                    if (configWe = '1') then
1810
                      inputPortEnable(portIndex) <= configDataWrite(21);
1811
                    end if;
1812
                    configDataReadInternal(21) <= inputPortEnable(portIndex);
1813 2 magro732
 
1814 46 magro732
                    -- Error Checking Disabled.
1815
                    configDataReadInternal(20) <= '0';
1816
 
1817
                    -- Multicast-event Participant.
1818
                    configDataReadInternal(19) <= '0';
1819
 
1820
                    -- Reserved.
1821
                    configDataReadInternal(18) <= '0';
1822
 
1823
                    -- Enumeration Boundry.
1824
                    configDataReadInternal(17) <= '0';
1825 2 magro732
 
1826 46 magro732
                    -- Reserved.
1827
                    configDataReadInternal(16) <= '0';
1828 2 magro732
 
1829 46 magro732
                    -- Extended Port Width Override.
1830
                    configDataReadInternal(15 downto 14) <= (others=>'0');
1831 2 magro732
 
1832 46 magro732
                    -- Extended Port Width Support.
1833
                    configDataReadInternal(13 downto 12) <= (others=>'0');
1834
 
1835
                    -- Implementation defined.
1836
                    configDataReadInternal(11 downto 4) <= (others=>'0');
1837 2 magro732
 
1838 46 magro732
                    -- Reserved.
1839
                    configDataReadInternal(3 downto 1) <= (others=>'0');
1840 2 magro732
 
1841 46 magro732
                    -- Port Type.
1842
                    configDataReadInternal(0) <= '1';
1843
                  end if;
1844
                end loop;
1845 2 magro732
 
1846 46 magro732
            end case;
1847
          end if;
1848
        else
1849
          -- Config memory not enabled.
1850 2 magro732
        end if;
1851
      else
1852 46 magro732
        configAck <= '0';
1853 2 magro732
      end if;
1854
    end if;
1855
  end process;
1856
 
1857 46 magro732
  -----------------------------------------------------------------------------
1858
  -- Logic implementing the routing table access.
1859
  -----------------------------------------------------------------------------
1860
 
1861
  -- Lookup interface port memory signals.
1862
  lookupEnable <= '1' when (lookupStb_i = '1') and (lookupAddr_i(15 downto 11) = "00000") else '0';
1863
  lookupAddress <= lookupAddr_i(10 downto 0);
1864
  lookupData_o <= lookupData when (lookupEnable = '1') else routeTablePortDefault;
1865
  lookupAck_o <= lookupAck;
1866
  LookupProcess: process(clk, areset_n)
1867
  begin
1868
    if (areset_n = '0') then
1869
      lookupAck <= '0';
1870
    elsif (clk'event and clk = '1') then
1871
      if ((lookupStb_i = '1') and (lookupAck = '0')) then
1872
        lookupAck <= '1';
1873
      else
1874
        lookupAck <= '0';
1875
      end if;
1876
    end if;
1877
  end process;
1878
 
1879
  -- Dual port memory containing the routing table.
1880
  RoutingTable: MemoryDualPort
1881
    generic map(
1882
      ADDRESS_WIDTH=>11, DATA_WIDTH=>8)
1883
    port map(
1884
      clkA_i=>clk, enableA_i=>routeTableEnable, writeEnableA_i=>routeTableWrite,
1885
      addressA_i=>routeTableAddress,
1886
      dataA_i=>routeTablePortWrite, dataA_o=>routeTablePortRead,
1887
      clkB_i=>clk, enableB_i=>lookupEnable,
1888
      addressB_i=>lookupAddress, dataB_o=>lookupData);
1889
 
1890 2 magro732
end architecture;
1891
 
1892
 
1893
-------------------------------------------------------------------------------
1894
-- 
1895
-------------------------------------------------------------------------------
1896
 
1897
library ieee;
1898
use ieee.std_logic_1164.all;
1899
use ieee.numeric_std.all;
1900
use work.rio_common.all;
1901
 
1902
 
1903
-------------------------------------------------------------------------------
1904
-- 
1905
-------------------------------------------------------------------------------
1906
entity RouteTableInterconnect is
1907
  generic(
1908
    WIDTH : natural range 1 to 256 := 8);
1909
  port(
1910
    clk : in std_logic;
1911
    areset_n : in std_logic;
1912
 
1913
    stb_i : in Array1(WIDTH-1 downto 0);
1914
    addr_i : in Array16(WIDTH-1 downto 0);
1915
    dataM_o : out Array8(WIDTH-1 downto 0);
1916
    ack_o : out Array1(WIDTH-1 downto 0);
1917
 
1918
    stb_o : out std_logic;
1919
    addr_o : out std_logic_vector(15 downto 0);
1920
    dataS_i : in std_logic_vector(7 downto 0);
1921
    ack_i : in std_logic);
1922
end entity;
1923
 
1924
 
1925
-------------------------------------------------------------------------------
1926
-- 
1927
-------------------------------------------------------------------------------
1928
architecture RouteTableInterconnectImpl of RouteTableInterconnect is
1929
  signal activeCycle : std_logic;
1930
  signal selectedMaster : natural range 0 to WIDTH-1;
1931
begin
1932
 
1933
  -----------------------------------------------------------------------------
1934
  -- Arbitration.
1935
  -----------------------------------------------------------------------------
1936
  Arbiter: process(areset_n, clk)
1937
  begin
1938
    if (areset_n = '0') then
1939
      activeCycle <= '0';
1940
      selectedMaster <= 0;
1941
    elsif (clk'event and clk = '1') then
1942
      if (activeCycle = '0') then
1943
        for i in 0 to WIDTH-1 loop
1944
          if (stb_i(i) = '1') then
1945
            activeCycle <= '1';
1946
            selectedMaster <= i;
1947
          end if;
1948
        end loop;
1949
      else
1950
        if (stb_i(selectedMaster) = '0') then
1951
          activeCycle <= '0';
1952
        end if;
1953
      end if;
1954
    end if;
1955
  end process;
1956
 
1957
  -----------------------------------------------------------------------------
1958
  -- Interconnection.
1959
  -----------------------------------------------------------------------------
1960
  stb_o <= stb_i(selectedMaster);
1961
  addr_o <= addr_i(selectedMaster);
1962
 
1963
  Interconnect: for i in 0 to WIDTH-1 generate
1964
    dataM_o(i) <= dataS_i;
1965
    ack_o(i) <= ack_i when (selectedMaster = i) else '0';
1966
  end generate;
1967
 
1968
end architecture;
1969
 
1970
 
1971
-------------------------------------------------------------------------------
1972
-- 
1973
-------------------------------------------------------------------------------
1974
 
1975
library ieee;
1976
use ieee.std_logic_1164.all;
1977
use ieee.numeric_std.all;
1978
use work.rio_common.all;
1979
 
1980
 
1981
-------------------------------------------------------------------------------
1982
-- 
1983
-------------------------------------------------------------------------------
1984
entity SwitchPortInterconnect is
1985
  generic(
1986
    WIDTH : natural range 1 to 256 := 8);
1987
  port(
1988
    clk : in std_logic;
1989
    areset_n : in std_logic;
1990
 
1991
    masterCyc_i : in Array1(WIDTH-1 downto 0);
1992
    masterStb_i : in Array1(WIDTH-1 downto 0);
1993
    masterWe_i : in Array1(WIDTH-1 downto 0);
1994
    masterAddr_i : in Array10(WIDTH-1 downto 0);
1995
    masterData_i : in Array32(WIDTH-1 downto 0);
1996
    masterData_o : out Array1(WIDTH-1 downto 0);
1997
    masterAck_o : out Array1(WIDTH-1 downto 0);
1998
 
1999
    slaveCyc_o : out Array1(WIDTH-1 downto 0);
2000
    slaveStb_o : out Array1(WIDTH-1 downto 0);
2001
    slaveWe_o : out Array1(WIDTH-1 downto 0);
2002
    slaveAddr_o : out Array10(WIDTH-1 downto 0);
2003
    slaveData_o : out Array32(WIDTH-1 downto 0);
2004
    slaveData_i : in Array1(WIDTH-1 downto 0);
2005
    slaveAck_i : in Array1(WIDTH-1 downto 0));
2006
end entity;
2007
 
2008
 
2009
-------------------------------------------------------------------------------
2010
-- 
2011
-------------------------------------------------------------------------------
2012
architecture SwitchPortInterconnectImpl of SwitchPortInterconnect is
2013
  --component ChipscopeIcon1 is
2014
  --  port (
2015
  --    CONTROL0 : inout STD_LOGIC_VECTOR ( 35 downto 0 )
2016
  --    );
2017
  --end component;
2018
  --component ChipscopeIlaWb is
2019
  --  port (
2020
  --    CLK : in STD_LOGIC := 'X';
2021
  --    TRIG0 : in STD_LOGIC_VECTOR ( 46 downto 0);
2022
  --    CONTROL : inout STD_LOGIC_VECTOR ( 35 downto 0 ) 
2023
  --    );
2024
  --end component;
2025
  --signal control : std_logic_vector(35 downto 0);
2026
  --signal trig : std_logic_vector(46 downto 0);
2027
 
2028
  signal activeCycle : std_logic;
2029
  signal selectedMaster : natural range 0 to WIDTH-1;
2030
  signal selectedSlave : natural range 0 to WIDTH-1;
2031
 
2032
begin
2033
 
2034
  -----------------------------------------------------------------------------
2035
  -- Arbitration process.
2036
  -----------------------------------------------------------------------------
2037
 
2038
  RoundRobinArbiter: process(areset_n, clk)
2039
    variable index : natural range 0 to WIDTH-1;
2040
  begin
2041
    if (areset_n = '0') then
2042
      activeCycle <= '0';
2043
      selectedMaster <= 0;
2044
    elsif (clk'event and clk = '1') then
2045
      -- Check if a cycle is ongoing.
2046
      if (activeCycle = '0') then
2047
        -- No ongoing cycles.
2048
 
2049
        -- Iterate through all ports and check if any new cycle has started.
2050
        for i in 0 to WIDTH-1 loop
2051
          if ((selectedMaster+i) >= WIDTH) then
2052
            index := (selectedMaster+i) - WIDTH;
2053
          else
2054
            index := (selectedMaster+i);
2055
          end if;
2056
 
2057
          if (masterCyc_i(index) = '1') then
2058
            activeCycle <= '1';
2059
            selectedMaster <= index;
2060
          end if;
2061
        end loop;
2062
      else
2063
        -- Ongoing cycle.
2064
 
2065
        -- Check if the cycle has ended.
2066
        if (masterCyc_i(selectedMaster) = '0') then
2067
          -- Cycle has ended.
2068
          activeCycle <= '0';
2069
 
2070
          -- Check if a new cycle has started from another master.
2071
          -- Start to check from the one that ended its cycle, this way, the
2072
          -- ports will be scheduled like round-robin.
2073
          for i in 0 to WIDTH-1 loop
2074
            if ((selectedMaster+i) >= WIDTH) then
2075
              index := (selectedMaster+i) - WIDTH;
2076
            else
2077
              index := (selectedMaster+i);
2078
            end if;
2079
 
2080
            if (masterCyc_i(index) = '1') then
2081
              activeCycle <= '1';
2082
              selectedMaster <= index;
2083
            end if;
2084
          end loop;
2085
        end if;
2086
      end if;
2087
    end if;
2088
  end process;
2089
 
2090
  -----------------------------------------------------------------------------
2091
  -- Address decoding.
2092
  -----------------------------------------------------------------------------
2093
 
2094
  -- Select the last port when the top bit is set.
2095
  -- The last port must be the maintenance slave port.
2096
  selectedSlave <= WIDTH-1 when masterAddr_i(selectedMaster)(9) = '1' else
2097
                   to_integer(unsigned(masterAddr_i(selectedMaster)(8 downto 1)));
2098
 
2099
  -----------------------------------------------------------------------------
2100
  -- Interconnection matrix.
2101
  -----------------------------------------------------------------------------
2102
  Interconnect: for i in 0 to WIDTH-1 generate
2103
    slaveCyc_o(i) <= masterCyc_i(selectedMaster) when (selectedSlave = i) else '0';
2104
    slaveStb_o(i) <= masterStb_i(selectedMaster) when (selectedSlave = i) else '0';
2105
    slaveWe_o(i) <= masterWe_i(selectedMaster);
2106
    slaveAddr_o(i) <= masterAddr_i(selectedMaster);
2107
    slaveData_o(i) <= masterData_i(selectedMaster);
2108
    masterData_o(i) <= slaveData_i(selectedSlave);
2109
    masterAck_o(i) <= slaveAck_i(selectedSlave) when (selectedMaster = i) else '0';
2110
  end generate;
2111
 
2112
  -----------------------------------------------------------------------------
2113
  -- Chipscope debugging probe.
2114
  -----------------------------------------------------------------------------
2115
  --trig <= masterCyc_i(selectedMaster) & masterStb_i(selectedMaster) &
2116
  --        masterWe_i(selectedMaster) &  masterAddr_i(selectedMaster) &
2117
  --        masterData_i(selectedMaster) & slaveData_i(selectedSlave) &
2118
  --        slaveAck_i(selectedSlave);
2119
  --ChipscopeIconInst: ChipscopeIcon1
2120
  --  port map(CONTROL0=>control);
2121
  --ChipscopeIlaInst: ChipscopeIlaWb
2122
  --  port map(CLK=>clk, TRIG0=>trig, CONTROL=>control);
2123
 
2124
end architecture;
2125
 
2126
 
2127
 

powered by: WebSVN 2.1.0

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