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

Subversion Repositories rio

[/] [rio/] [trunk/] [rtl/] [vhdl/] [RioSwitch.vhd] - Blame information for rev 9

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
-- -
14
-- 
15
-- Author(s): 
16
-- - Magnus Rosenius, magro732@opencores.org 
17
-- 
18
-------------------------------------------------------------------------------
19
-- 
20
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
21
-- 
22
-- This source file may be used and distributed without 
23
-- restriction provided that this copyright statement is not 
24
-- removed from the file and that any derivative work contains 
25
-- the original copyright notice and the associated disclaimer. 
26
-- 
27
-- This source file is free software; you can redistribute it 
28
-- and/or modify it under the terms of the GNU Lesser General 
29
-- Public License as published by the Free Software Foundation; 
30
-- either version 2.1 of the License, or (at your option) any 
31
-- later version. 
32
-- 
33
-- This source is distributed in the hope that it will be 
34
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
35
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
36
-- PURPOSE. See the GNU Lesser General Public License for more 
37
-- details. 
38
-- 
39
-- You should have received a copy of the GNU Lesser General 
40
-- Public License along with this source; if not, download it 
41
-- from http://www.opencores.org/lgpl.shtml 
42
-- 
43
-------------------------------------------------------------------------------
44
 
45
 
46
-------------------------------------------------------------------------------
47
-- RioSwitch
48
-------------------------------------------------------------------------------
49
 
50
library ieee;
51
use ieee.std_logic_1164.all;
52
use ieee.numeric_std.all;
53
use work.rio_common.all;
54
 
55
-------------------------------------------------------------------------------
56
-- Entity for RioSwitch.
57
-------------------------------------------------------------------------------
58
entity RioSwitch is
59
  generic(
60
    SWITCH_PORTS : natural range 3 to 255 := 4;
61
    DEVICE_IDENTITY : std_logic_vector(15 downto 0);
62
    DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
63
    DEVICE_REV : std_logic_vector(31 downto 0);
64
    ASSY_IDENTITY : std_logic_vector(15 downto 0);
65
    ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
66
    ASSY_REV : std_logic_vector(15 downto 0));
67
  port(
68
    clk : in std_logic;
69
    areset_n : in std_logic;
70
 
71
    writeFrameFull_i : in Array1(SWITCH_PORTS-1 downto 0);
72
    writeFrame_o : out Array1(SWITCH_PORTS-1 downto 0);
73
    writeFrameAbort_o : out Array1(SWITCH_PORTS-1 downto 0);
74
    writeContent_o : out Array1(SWITCH_PORTS-1 downto 0);
75
    writeContentData_o : out Array32(SWITCH_PORTS-1 downto 0);
76
 
77
    readFrameEmpty_i : in Array1(SWITCH_PORTS-1 downto 0);
78
    readFrame_o : out Array1(SWITCH_PORTS-1 downto 0);
79
    readFrameRestart_o : out Array1(SWITCH_PORTS-1 downto 0);
80
    readFrameAborted_i : in Array1(SWITCH_PORTS-1 downto 0);
81
    readContentEmpty_i : in Array1(SWITCH_PORTS-1 downto 0);
82
    readContent_o : out Array1(SWITCH_PORTS-1 downto 0);
83
    readContentEnd_i : in Array1(SWITCH_PORTS-1 downto 0);
84
    readContentData_i : in Array32(SWITCH_PORTS-1 downto 0);
85
 
86
    portLinkTimeout_o : out std_logic_vector(23 downto 0);
87
 
88
    linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0);
89
    outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
90
    inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
91
 
92
    localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0);
93
    clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0);
94
    inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
95
    outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
96
    outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
97
    inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
98
    outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
99
    outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
100
 
101
    configStb_o : out std_logic;
102
    configWe_o : out std_logic;
103
    configAddr_o : out std_logic_vector(23 downto 0);
104
    configData_o : out std_logic_vector(31 downto 0);
105
    configData_i : in std_logic_vector(31 downto 0));
106
end entity;
107
 
108
 
109
-------------------------------------------------------------------------------
110
-- Architecture for RioSwitch.
111
-------------------------------------------------------------------------------
112
architecture RioSwitchImpl of RioSwitch is
113
 
114
  component RouteTableInterconnect is
115
    generic(
116
      WIDTH : natural range 1 to 256 := 8);
117
    port(
118
      clk : in std_logic;
119
      areset_n : in std_logic;
120
 
121
      stb_i : in Array1(WIDTH-1 downto 0);
122
      addr_i : in Array16(WIDTH-1 downto 0);
123
      dataM_o : out Array8(WIDTH-1 downto 0);
124
      ack_o : out Array1(WIDTH-1 downto 0);
125
 
126
      stb_o : out std_logic;
127
      addr_o : out std_logic_vector(15 downto 0);
128
      dataS_i : in std_logic_vector(7 downto 0);
129
      ack_i : in std_logic);
130
  end component;
131
 
132
  component SwitchPortInterconnect is
133
    generic(
134
      WIDTH : natural range 1 to 256 := 8);
135
    port(
136
      clk : in std_logic;
137
      areset_n : in std_logic;
138
 
139
      masterCyc_i : in Array1(WIDTH-1 downto 0);
140
      masterStb_i : in Array1(WIDTH-1 downto 0);
141
      masterWe_i : in Array1(WIDTH-1 downto 0);
142
      masterAddr_i : in Array10(WIDTH-1 downto 0);
143
      masterData_i : in Array32(WIDTH-1 downto 0);
144
      masterData_o : out Array1(WIDTH-1 downto 0);
145
      masterAck_o : out Array1(WIDTH-1 downto 0);
146
 
147
      slaveCyc_o : out Array1(WIDTH-1 downto 0);
148
      slaveStb_o : out Array1(WIDTH-1 downto 0);
149
      slaveWe_o : out Array1(WIDTH-1 downto 0);
150
      slaveAddr_o : out Array10(WIDTH-1 downto 0);
151
      slaveData_o : out Array32(WIDTH-1 downto 0);
152
      slaveData_i : in Array1(WIDTH-1 downto 0);
153
      slaveAck_i : in Array1(WIDTH-1 downto 0));
154
  end component;
155
 
156
  component SwitchPortMaintenance is
157
    generic(
158
      SWITCH_PORTS : natural range 0 to 255;
159
      DEVICE_IDENTITY : std_logic_vector(15 downto 0);
160
      DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
161
      DEVICE_REV : std_logic_vector(31 downto 0);
162
      ASSY_IDENTITY : std_logic_vector(15 downto 0);
163
      ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
164
      ASSY_REV : std_logic_vector(15 downto 0));
165
    port(
166
      clk : in std_logic;
167
      areset_n : in std_logic;
168
 
169
      lookupStb_i : in std_logic;
170
      lookupAddr_i : in std_logic_vector(15 downto 0);
171
      lookupData_o : out std_logic_vector(7 downto 0);
172
      lookupAck_o : out std_logic;
173
 
174
      masterCyc_o : out std_logic;
175
      masterStb_o : out std_logic;
176
      masterWe_o : out std_logic;
177
      masterAddr_o : out std_logic_vector(9 downto 0);
178
      masterData_o : out std_logic_vector(31 downto 0);
179
      masterData_i : in std_logic;
180
      masterAck_i : in std_logic;
181
 
182
      slaveCyc_i : in std_logic;
183
      slaveStb_i : in std_logic;
184
      slaveWe_i : in std_logic;
185
      slaveAddr_i : in std_logic_vector(9 downto 0);
186
      slaveData_i : in std_logic_vector(31 downto 0);
187
      slaveData_o : out std_logic;
188
      slaveAck_o : out std_logic;
189
 
190
      lookupStb_o : out std_logic;
191
      lookupAddr_o : out std_logic_vector(15 downto 0);
192
      lookupData_i : in std_logic_vector(7 downto 0);
193
      lookupAck_i : in std_logic;
194
 
195
      portLinkTimeout_o : out std_logic_vector(23 downto 0);
196
 
197
      linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0);
198
      outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
199
      inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
200
      localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0);
201
      clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0);
202
      inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
203
      outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
204
      outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
205
      inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
206
      outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
207
      outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
208
 
209
      configStb_o : out std_logic;
210
      configWe_o : out std_logic;
211
      configAddr_o : out std_logic_vector(23 downto 0);
212
      configData_o : out std_logic_vector(31 downto 0);
213
      configData_i : in std_logic_vector(31 downto 0));
214
  end component;
215
 
216
  component SwitchPort is
217
    generic(
218
      PORT_INDEX : natural);
219
    port(
220
      clk : in std_logic;
221
      areset_n : in std_logic;
222
 
223
      masterCyc_o : out std_logic;
224
      masterStb_o : out std_logic;
225
      masterWe_o : out std_logic;
226
      masterAddr_o : out std_logic_vector(9 downto 0);
227
      masterData_o : out std_logic_vector(31 downto 0);
228
      masterData_i : in std_logic;
229
      masterAck_i : in std_logic;
230
 
231
      slaveCyc_i : in std_logic;
232
      slaveStb_i : in std_logic;
233
      slaveWe_i : in std_logic;
234
      slaveAddr_i : in std_logic_vector(9 downto 0);
235
      slaveData_i : in std_logic_vector(31 downto 0);
236
      slaveData_o : out std_logic;
237
      slaveAck_o : out std_logic;
238
 
239
      lookupStb_o : out std_logic;
240
      lookupAddr_o : out std_logic_vector(15 downto 0);
241
      lookupData_i : in std_logic_vector(7 downto 0);
242
      lookupAck_i : in std_logic;
243
 
244
      readFrameEmpty_i : in std_logic;
245
      readFrame_o : out std_logic;
246
      readFrameRestart_o : out std_logic;
247
      readFrameAborted_i : in std_logic;
248
      readContentEmpty_i : in std_logic;
249
      readContent_o : out std_logic;
250
      readContentEnd_i : in std_logic;
251
      readContentData_i : in std_logic_vector(31 downto 0);
252
      writeFrameFull_i : in std_logic;
253
      writeFrame_o : out std_logic;
254
      writeFrameAbort_o : out std_logic;
255
      writeContent_o : out std_logic;
256
      writeContentData_o : out std_logic_vector(31 downto 0));
257
  end component;
258
 
259
  signal masterLookupStb : Array1(SWITCH_PORTS downto 0);
260
  signal masterLookupAddr : Array16(SWITCH_PORTS downto 0);
261
  signal masterLookupData : Array8(SWITCH_PORTS downto 0);
262
  signal masterLookupAck : Array1(SWITCH_PORTS downto 0);
263
 
264
  signal slaveLookupStb : std_logic;
265
  signal slaveLookupAddr : std_logic_vector(15 downto 0);
266
  signal slaveLookupData : std_logic_vector(7 downto 0);
267
  signal slaveLookupAck : std_logic;
268
 
269
  signal masterCyc : Array1(SWITCH_PORTS downto 0);
270
  signal masterStb : Array1(SWITCH_PORTS downto 0);
271
  signal masterWe : Array1(SWITCH_PORTS downto 0);
272
  signal masterAddr : Array10(SWITCH_PORTS downto 0);
273
  signal masterDataWrite : Array32(SWITCH_PORTS downto 0);
274
  signal masterDataRead : Array1(SWITCH_PORTS downto 0);
275
  signal masterAck : Array1(SWITCH_PORTS downto 0);
276
 
277
  signal slaveCyc : Array1(SWITCH_PORTS downto 0);
278
  signal slaveStb : Array1(SWITCH_PORTS downto 0);
279
  signal slaveWe : Array1(SWITCH_PORTS downto 0);
280
  signal slaveAddr : Array10(SWITCH_PORTS downto 0);
281
  signal slaveDataWrite : Array32(SWITCH_PORTS downto 0);
282
  signal slaveDataRead : Array1(SWITCH_PORTS downto 0);
283
  signal slaveAck : Array1(SWITCH_PORTS downto 0);
284
 
285
begin
286
 
287
  -----------------------------------------------------------------------------
288
  -- The routing table interconnect.
289
  -----------------------------------------------------------------------------
290
  RouteInterconnect: RouteTableInterconnect
291
    generic map(
292
      WIDTH=>SWITCH_PORTS+1)
293
    port map(
294
      clk=>clk, areset_n=>areset_n,
295
      stb_i=>masterLookupStb, addr_i=>masterLookupAddr,
296
      dataM_o=>masterLookupData, ack_o=>masterLookupAck,
297
      stb_o=>slaveLookupStb, addr_o=>slaveLookupAddr,
298
      dataS_i=>slaveLookupData, ack_i=>slaveLookupAck);
299
 
300
  -----------------------------------------------------------------------------
301
  -- The port interconnect.
302
  -----------------------------------------------------------------------------
303
  PortInterconnect: SwitchPortInterconnect
304
    generic map(
305
      WIDTH=>SWITCH_PORTS+1)
306
    port map(
307
      clk=>clk, areset_n=>areset_n,
308
      masterCyc_i=>masterCyc, masterStb_i=>masterStb, masterWe_i=>masterWe, masterAddr_i=>masterAddr,
309
      masterData_i=>masterDataWrite, masterData_o=>masterDataRead, masterAck_o=>masterAck,
310
      slaveCyc_o=>slaveCyc, slaveStb_o=>slaveStb, slaveWe_o=>slaveWe, slaveAddr_o=>slaveAddr,
311
      slaveData_o=>slaveDataWrite, slaveData_i=>slaveDataRead, slaveAck_i=>slaveAck);
312
 
313
  -----------------------------------------------------------------------------
314
  -- Data relaying port instantiation.
315
  -----------------------------------------------------------------------------
316
  PortGeneration: for portIndex in 0 to SWITCH_PORTS-1 generate
317
    PortInst: SwitchPort
318
      generic map(
319
        PORT_INDEX=>portIndex)
320
      port map(
321
        clk=>clk, areset_n=>areset_n,
322
        masterCyc_o=>masterCyc(portIndex), masterStb_o=>masterStb(portIndex),
323
        masterWe_o=>masterWe(portIndex), masterAddr_o=>masterAddr(portIndex),
324
        masterData_o=>masterDataWrite(portIndex),
325
        masterData_i=>masterDataRead(portIndex), masterAck_i=>masterAck(portIndex),
326
        slaveCyc_i=>slaveCyc(portIndex), slaveStb_i=>slaveStb(portIndex),
327
        slaveWe_i=>slaveWe(portIndex), slaveAddr_i=>slaveAddr(portIndex),
328
        slaveData_i=>slaveDataWrite(portIndex),
329
        slaveData_o=>slaveDataRead(portIndex), slaveAck_o=>slaveAck(portIndex),
330
        lookupStb_o=>masterLookupStb(portIndex),
331
        lookupAddr_o=>masterLookupAddr(portIndex),
332
        lookupData_i=>masterLookupData(portIndex), lookupAck_i=>masterLookupAck(portIndex),
333
        readFrameEmpty_i=>readFrameEmpty_i(portIndex), readFrame_o=>readFrame_o(portIndex),
334
        readFrameRestart_o=>readFrameRestart_o(portIndex),
335
        readFrameAborted_i=>readFrameAborted_i(portIndex),
336
        readContentEmpty_i=>readContentEmpty_i(portIndex), readContent_o=>readContent_o(portIndex),
337
        readContentEnd_i=>readContentEnd_i(portIndex), readContentData_i=>readContentData_i(portIndex),
338
        writeFrameFull_i=>writeFrameFull_i(portIndex), writeFrame_o=>writeFrame_o(portIndex),
339
        writeFrameAbort_o=>writeFrameAbort_o(portIndex), writeContent_o=>writeContent_o(portIndex),
340
        writeContentData_o=>writeContentData_o(portIndex));
341
  end generate;
342
 
343
  -----------------------------------------------------------------------------
344
  -- Maintenance port instantiation.
345
  -----------------------------------------------------------------------------
346
  MaintenancePort: SwitchPortMaintenance
347
    generic map(
348
      SWITCH_PORTS=>SWITCH_PORTS,
349
      DEVICE_IDENTITY=>DEVICE_IDENTITY,
350
      DEVICE_VENDOR_IDENTITY=>DEVICE_VENDOR_IDENTITY,
351
      DEVICE_REV=>DEVICE_REV,
352
      ASSY_IDENTITY=>ASSY_IDENTITY,
353
      ASSY_VENDOR_IDENTITY=>ASSY_VENDOR_IDENTITY,
354
      ASSY_REV=>ASSY_REV)
355
    port map(
356
      clk=>clk, areset_n=>areset_n,
357
      lookupStb_i=>slaveLookupStb, lookupAddr_i=>slaveLookupAddr,
358
      lookupData_o=>slaveLookupData, lookupAck_o=>slaveLookupAck,
359
      masterCyc_o=>masterCyc(SWITCH_PORTS), masterStb_o=>masterStb(SWITCH_PORTS),
360
      masterWe_o=>masterWe(SWITCH_PORTS), masterAddr_o=>masterAddr(SWITCH_PORTS),
361
      masterData_o=>masterDataWrite(SWITCH_PORTS),
362
      masterData_i=>masterDataRead(SWITCH_PORTS), masterAck_i=>masterAck(SWITCH_PORTS),
363
      slaveCyc_i=>slaveCyc(SWITCH_PORTS), slaveStb_i=>slaveStb(SWITCH_PORTS),
364
      slaveWe_i=>slaveWe(SWITCH_PORTS), slaveAddr_i=>slaveAddr(SWITCH_PORTS),
365
      slaveData_i=>slaveDataWrite(SWITCH_PORTS),
366
      slaveData_o=>slaveDataRead(SWITCH_PORTS), slaveAck_o=>slaveAck(SWITCH_PORTS),
367
      lookupStb_o=>masterLookupStb(SWITCH_PORTS),
368
      lookupAddr_o=>masterLookupAddr(SWITCH_PORTS),
369
      lookupData_i=>masterLookupData(SWITCH_PORTS), lookupAck_i=>masterLookupAck(SWITCH_PORTS),
370
      portLinkTimeout_o=>portLinkTimeout_o,
371
      linkInitialized_i=>linkInitialized_i,
372
      outputPortEnable_o=>outputPortEnable_o, inputPortEnable_o=>inputPortEnable_o,
373
      localAckIdWrite_o=>localAckIdWrite_o, clrOutstandingAckId_o=>clrOutstandingAckId_o,
374
      inboundAckId_o=>inboundAckId_o, outstandingAckId_o=>outstandingAckId_o,
375
      outboundAckId_o=>outboundAckId_o, inboundAckId_i=>inboundAckId_i,
376
      outstandingAckId_i=>outstandingAckId_i, outboundAckId_i=>outboundAckId_i,
377
      configStb_o=>configStb_o, configWe_o=>configWe_o, configAddr_o=>configAddr_o,
378
      configData_o=>configData_o, configData_i=>configData_i);
379
 
380
end architecture;
381
 
382
 
383
 
384
-------------------------------------------------------------------------------
385
-- SwitchPort
386
-------------------------------------------------------------------------------
387
 
388
library ieee;
389
use ieee.std_logic_1164.all;
390
use ieee.numeric_std.all;
391
use work.rio_common.all;
392
 
393
 
394
-------------------------------------------------------------------------------
395
-- Entity for SwitchPort.
396
-------------------------------------------------------------------------------
397
entity SwitchPort is
398
  generic(
399
    PORT_INDEX : natural);
400
  port(
401
    clk : in std_logic;
402
    areset_n : in std_logic;
403
 
404
    -- Master port signals.
405
    -- Write frames to other ports.
406
    masterCyc_o : out std_logic;
407
    masterStb_o : out std_logic;
408
    masterWe_o : out std_logic;
409
    masterAddr_o : out std_logic_vector(9 downto 0);
410
    masterData_o : out std_logic_vector(31 downto 0);
411
    masterData_i : in std_logic;
412
    masterAck_i : in std_logic;
413
 
414
    -- Slave port signals.
415
    -- Receives frames from other ports.
416
    slaveCyc_i : in std_logic;
417
    slaveStb_i : in std_logic;
418
    slaveWe_i : in std_logic;
419
    slaveAddr_i : in std_logic_vector(9 downto 0);
420
    slaveData_i : in std_logic_vector(31 downto 0);
421
    slaveData_o : out std_logic;
422
    slaveAck_o : out std_logic;
423
 
424
    -- Address-lookup interface.
425
    lookupStb_o : out std_logic;
426
    lookupAddr_o : out std_logic_vector(15 downto 0);
427
    lookupData_i : in std_logic_vector(7 downto 0);
428
    lookupAck_i : in std_logic;
429
 
430
    -- Physical port frame buffer interface.
431
    readFrameEmpty_i : in std_logic;
432
    readFrame_o : out std_logic;
433
    readFrameRestart_o : out std_logic;
434
    readFrameAborted_i : in std_logic;
435
    readContentEmpty_i : in std_logic;
436
    readContent_o : out std_logic;
437
    readContentEnd_i : in std_logic;
438
    readContentData_i : in std_logic_vector(31 downto 0);
439
    writeFrameFull_i : in std_logic;
440
    writeFrame_o : out std_logic;
441
    writeFrameAbort_o : out std_logic;
442
    writeContent_o : out std_logic;
443
    writeContentData_o : out std_logic_vector(31 downto 0));
444
end entity;
445
 
446
 
447
-------------------------------------------------------------------------------
448
-- Architecture for SwitchPort.
449
-------------------------------------------------------------------------------
450
architecture SwitchPortImpl of SwitchPort is
451
 
452
  type MasterStateType is (STATE_IDLE,
453
                           STATE_WAIT_HEADER_0, STATE_READ_HEADER_0,
454
                           STATE_READ_PORT_LOOKUP,
455
                           STATE_READ_TARGET_PORT,
456
                           STATE_WAIT_TARGET_PORT,
457
                           STATE_WAIT_TARGET_WRITE,
458
                           STATE_WAIT_COMPLETE);
459
  signal masterState : MasterStateType;
460
 
461
  type SlaveStateType is (STATE_IDLE, STATE_SEND_ACK);
462
  signal slaveState : SlaveStateType;
463
 
464
  alias ftype : std_logic_vector(3 downto 0) is readContentData_i(19 downto 16);
465
  alias tt : std_logic_vector(1 downto 0) is readContentData_i(21 downto 20);
466
 
467
begin
468
 
469
  -----------------------------------------------------------------------------
470
  -- Master interface process.
471
  -----------------------------------------------------------------------------
472
  Master: process(clk, areset_n)
473
  begin
474
    if (areset_n = '0') then
475
      masterState <= STATE_IDLE;
476
 
477
      lookupStb_o <= '0';
478
      lookupAddr_o <= (others => '0');
479
 
480
      masterCyc_o <= '0';
481
      masterStb_o <= '0';
482
      masterWe_o <= '0';
483
      masterAddr_o <= (others => '0');
484
      masterData_o <= (others => '0');
485
 
486
      readContent_o <= '0';
487
      readFrame_o <= '0';
488
      readFrameRestart_o <= '0';
489
    elsif (clk'event and clk = '1') then
490
      readContent_o <= '0';
491
      readFrame_o <= '0';
492
      readFrameRestart_o <= '0';
493
 
494
      -- REMARK: Add support for aborted frames...
495
      case masterState is
496
 
497
        when STATE_IDLE =>
498
          ---------------------------------------------------------------------
499
          -- Wait for a new packet or content of a new packet.
500
          ---------------------------------------------------------------------
501
 
502
          -- Reset bus signals.
503
          masterCyc_o <= '0';
504
          masterStb_o <= '0';
505
 
506
          -- Wait for frame content to be available.
507
          -- Use different signals to trigger the forwarding of packets depending
508
          -- on the switch philosofy.
509
          if (readFrameEmpty_i = '0') then
510
            readContent_o <= '1';
511
            masterState <= STATE_WAIT_HEADER_0;
512
          end if;
513
 
514
        when STATE_WAIT_HEADER_0 =>
515
          ---------------------------------------------------------------------
516
          -- Wait for the frame buffer output to be updated.
517
          ---------------------------------------------------------------------
518
 
519
          -- Wait for frame buffer output to be updated.
520
          masterState <= STATE_READ_HEADER_0;
521
 
522
        when STATE_READ_HEADER_0 =>
523
          ---------------------------------------------------------------------
524
          -- Check the FTYPE and forward it to the maintenance port if it is a
525
          -- maintenance packet. Otherwise, initiate an address lookup and wait
526
          -- for the result.
527
          ---------------------------------------------------------------------
528
 
529
          -- Check if the frame has ended.
530
          if (readContentEnd_i = '0') then
531
            -- The frame has not ended.
532
            -- This word contains the header and the source id.
533
 
534
            -- Read the tt-field to check the source and destination id size.
535
            if (tt = "01") then
536
              -- This frame contains 16-bit addresses.
537
 
538
              -- Read the new content.
539
              readContent_o <= '1';
540
 
541
              -- Save the content of the header and destination.
542
              masterData_o <= readContentData_i;
543
 
544
              -- Check if this is a maintenance frame.
545
              if (ftype = FTYPE_MAINTENANCE_CLASS) then
546
                -- This is a maintenance frame.
547
 
548
                -- Always route these frames to the maintenance module in the
549
                -- switch by setting the MSB bit of the port address.
550
                masterAddr_o <= '1' & std_logic_vector(to_unsigned(PORT_INDEX, 8)) & '0';
551
 
552
                -- Start an access to the maintenance port.
553
                masterState <= STATE_READ_TARGET_PORT;
554
              else
555
                -- This is not a maintenance frame.
556
 
557
                -- Lookup the destination address and proceed to wait for the
558
                -- result.
559
                lookupStb_o <= '1';
560
                lookupAddr_o <= readContentData_i(15 downto 0);
561
 
562
                -- Wait for the port lookup to return a result.
563
                masterState <= STATE_READ_PORT_LOOKUP;
564
              end if;
565
            else
566
              -- Unsupported tt-value, discard the frame.
567
              readFrame_o <= '1';
568
              masterState <= STATE_IDLE;
569
            end if;
570
          else
571
            -- End of frame.
572
            -- The frame is too short to contain a valid frame. Discard it.
573
            readFrame_o <= '1';
574
            masterState <= STATE_IDLE;
575
          end if;
576
 
577
        when STATE_READ_PORT_LOOKUP =>
578
          ---------------------------------------------------------------------
579
          -- Wait for the address lookup to be complete.
580
          ---------------------------------------------------------------------
581
 
582
          -- Wait for the routing table to complete the request.
583
          if (lookupAck_i = '1') then
584
            -- The address lookup is complete.
585
 
586
            -- Terminate the lookup cycle.
587
            lookupStb_o <= '0';
588
 
589
            -- Proceed to read the target port.
590
            masterAddr_o <= '0' & lookupData_i & '0';
591
            masterState <= STATE_READ_TARGET_PORT;
592
          else
593
            -- Wait until the address lookup is complete.
594
            -- REMARK: Timeout here???
595
          end if;
596
 
597
        when STATE_READ_TARGET_PORT =>
598
          ---------------------------------------------------------------------
599
          -- Initiate an access to the target port.
600
          ---------------------------------------------------------------------
601
 
602
          -- Read the status of the target port using the result from the
603
          -- lookup in the routing table.
604
          masterCyc_o <= '1';
605
          masterStb_o <= '1';
606
          masterWe_o <= '0';
607
          masterState <= STATE_WAIT_TARGET_PORT;
608
 
609
        when STATE_WAIT_TARGET_PORT =>
610
          ---------------------------------------------------------------------
611
          -- Wait to get access to the target port. When the port is ready
612
          -- check if it is ready to accept a new frame. If it cannot accept a
613
          -- new frame, terminate the access and go back and start a new one.
614
          -- This is to free the interconnect to let other ports access it if
615
          -- it is a shared bus. If the port is ready, initiate a write access
616
          -- to the selected port.
617
          ---------------------------------------------------------------------
618
 
619
          -- Wait for the target port to complete the request.
620
          if (masterAck_i = '1') then
621
            -- Target port has completed the request.
622
 
623
            -- Check the status of the target port.
624
            if (masterData_i = '0') then
625
              -- The target port has empty buffers to receive the frame.
626
 
627
              -- Hold the bus with cyc until the cycle is complete.
628
              -- Write the first word of the frame to the target port.
629
              -- The masterData_o has already been assigned.
630
              masterCyc_o <= '1';
631
              masterStb_o <= '1';
632
              masterWe_o <= '1';
633
              masterAddr_o(0) <= '1';
634
 
635
              -- Change state to transfer the frame.
636
              masterState <= STATE_WAIT_TARGET_WRITE;
637
            else
638
              -- The target port has no empty buffer to receive the frame.
639
              -- Terminate the cycle and retry later.
640
              masterCyc_o <= '0';
641
              masterStb_o <= '0';
642
              masterState <= STATE_READ_TARGET_PORT;
643
            end if;
644
          else
645
            -- Target port has not completed the request.
646
            -- Dont to anything.
647
          end if;
648
 
649
        when STATE_WAIT_TARGET_WRITE =>
650
          ---------------------------------------------------------------------
651
          -- Wait for the write access to complete. When complete, write the
652
          -- next content and update the content to the next. If the frame does
653
          -- not have any more data ready, terminate the access but keep the
654
          -- cycle active and proceed to wait for new data.
655
          ---------------------------------------------------------------------
656
 
657
          -- Wait for the target port to complete the request.
658
          -- REMARK: Remove the ack-condition, we know that the write takes one
659
          -- cycle...
660
          if (masterAck_i = '1') then
661
            -- The target port is ready.
662
 
663
            -- Check if the frame has ended.
664
            if (readContentEnd_i = '0') then
665
              -- The frame has not ended.
666
 
667
              -- There are more data to transfer.
668
              masterData_o <= readContentData_i;
669
              readContent_o <= '1';
670
            else
671
              -- There are no more data to transfer.
672
 
673
              -- Update to the next frame.
674
              readFrame_o <= '1';
675
 
676
              -- Tell the target port that the frame is complete.
677
              masterWe_o <= '1';
678
              masterAddr_o(0) <= '0';
679
              masterData_o <= x"00000001";
680
 
681
              -- Change state to wait for the target port to finalize the write
682
              -- of the full frame.
683
              masterState <= STATE_WAIT_COMPLETE;
684
            end if;
685
          else
686
            -- Wait for the target port to reply.
687
            -- Dont do anything.
688
          end if;
689
 
690
        when STATE_WAIT_COMPLETE =>
691
          ---------------------------------------------------------------------
692
          -- Wait for the target port to signal that the frame has been
693
          -- completed.
694
          ---------------------------------------------------------------------
695
 
696
          -- Wait for the target port to complete the final request.
697
          if (masterAck_i = '1') then
698
            -- The target port has finalized the write of the frame.
699
 
700
            -- Reset master bus signals.
701
            masterCyc_o <= '0';
702
            masterStb_o <= '0';
703
            masterState <= STATE_IDLE;
704
          else
705
            -- Wait for the target port to reply.
706
            -- REMARK: Timeout here???
707
          end if;
708
 
709
        when others =>
710
          ---------------------------------------------------------------------
711
          -- 
712
          ---------------------------------------------------------------------
713
      end case;
714
    end if;
715
  end process;
716
 
717
 
718
  -----------------------------------------------------------------------------
719
  -- Slave interface process.
720
  -----------------------------------------------------------------------------
721
  -- Addr |  Read  | Write
722
  --    0 |  full  | abort & complete
723
  --    1 |  full  | frameData
724
  writeContentData_o <= slaveData_i;
725
  Slave: process(clk, areset_n)
726
  begin
727
    if (areset_n = '0') then
728
      slaveState <= STATE_IDLE;
729
 
730
      slaveData_o <= '0';
731
 
732
      writeFrame_o <= '0';
733
      writeFrameAbort_o <= '0';
734
      writeContent_o <= '0';
735
    elsif (clk'event and clk = '1') then
736
      writeFrame_o <= '0';
737
      writeFrameAbort_o <= '0';
738
      writeContent_o <= '0';
739
 
740
      case slaveState is
741
 
742
        when STATE_IDLE =>
743
          ---------------------------------------------------------------------
744
          -- Wait for an access from a master.
745
          ---------------------------------------------------------------------
746
 
747
          -- Check if any cycle is active.
748
          if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then
749
            -- Cycle is active.
750
 
751
            -- Check if the cycle is accessing the status- or data address.
752
            if (slaveAddr_i(0) = '0') then
753
              -- Accessing port status address.
754
 
755
              -- Check if writing.
756
              if (slaveWe_i = '1') then
757
                -- Writing the status address.
758
                -- Update the buffering output signals according to the input
759
                -- data.
760
                writeFrame_o <= slaveData_i(0);
761
                writeFrameAbort_o <= slaveData_i(1);
762
              else
763
                -- Reading the status address.
764
                slaveData_o <= writeFrameFull_i;
765
              end if;
766
            else
767
              -- Accessing port data address.
768
 
769
              -- Check if writing.
770
              if (slaveWe_i = '1') then
771
                -- Write frame content into the frame buffer.
772
                writeContent_o <= '1';
773
              else
774
                slaveData_o <= writeFrameFull_i;
775
              end if;
776
            end if;
777
 
778
            -- Change state to send an ack to the master.
779
            slaveState <= STATE_SEND_ACK;
780
          end if;
781
 
782
        when STATE_SEND_ACK =>
783
          ---------------------------------------------------------------------
784
          -- Wait for acknowledge to be received by the master.
785
          ---------------------------------------------------------------------
786
 
787
          -- Go back to the idle state and wait for a new cycle.
788
          slaveState <= STATE_IDLE;
789
 
790
        when others =>
791
          ---------------------------------------------------------------------
792
          -- 
793
          ---------------------------------------------------------------------
794
          null;
795
 
796
      end case;
797
    end if;
798
  end process;
799
 
800
  -- Assign the acknowledge depending on the current slave state.
801
  slaveAck_o <= '1' when (slaveState = STATE_SEND_ACK) else '0';
802
 
803
end architecture;
804
 
805
 
806
 
807
-------------------------------------------------------------------------------
808
-- SwitchPortMaintenance
809
-------------------------------------------------------------------------------
810
 
811
library ieee;
812
use ieee.std_logic_1164.all;
813
use ieee.numeric_std.all;
814
use work.rio_common.all;
815
 
816
 
817
-------------------------------------------------------------------------------
818
-- Entity for SwitchPortMaintenance.
819
-------------------------------------------------------------------------------
820
entity SwitchPortMaintenance is
821
  generic(
822
    SWITCH_PORTS : natural range 0 to 255;
823
    DEVICE_IDENTITY : std_logic_vector(15 downto 0);
824
    DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
825
    DEVICE_REV : std_logic_vector(31 downto 0);
826
    ASSY_IDENTITY : std_logic_vector(15 downto 0);
827
    ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
828
    ASSY_REV : std_logic_vector(15 downto 0));
829
  port(
830
    clk : in std_logic;
831
    areset_n : in std_logic;
832
 
833
    -- Routing table port lookup signals.
834
    lookupStb_i : in std_logic;
835
    lookupAddr_i : in std_logic_vector(15 downto 0);
836
    lookupData_o : out std_logic_vector(7 downto 0);
837
    lookupAck_o : out std_logic;
838
 
839
    -- Master port signals.
840
    -- Write frames to other ports.
841
    masterCyc_o : out std_logic;
842
    masterStb_o : out std_logic;
843
    masterWe_o : out std_logic;
844
    masterAddr_o : out std_logic_vector(9 downto 0);
845
    masterData_o : out std_logic_vector(31 downto 0);
846
    masterData_i : in std_logic;
847
    masterAck_i : in std_logic;
848
 
849
    -- Slave port signals.
850
    -- Receives frames from other ports.
851
    slaveCyc_i : in std_logic;
852
    slaveStb_i : in std_logic;
853
    slaveWe_i : in std_logic;
854
    slaveAddr_i : in std_logic_vector(9 downto 0);
855
    slaveData_i : in std_logic_vector(31 downto 0);
856
    slaveData_o : out std_logic;
857
    slaveAck_o : out std_logic;
858
 
859
    -- Address-lookup interface.
860
    lookupStb_o : out std_logic;
861
    lookupAddr_o : out std_logic_vector(15 downto 0);
862
    lookupData_i : in std_logic_vector(7 downto 0);
863
    lookupAck_i : in std_logic;
864
 
865
    -- Port common access interface.
866
    portLinkTimeout_o : out std_logic_vector(23 downto 0);
867
 
868
    -- Port specific access interface.
869
    linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0);
870
    outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
871
    inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
872
    localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0);
873
    clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0);
874
    inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
875
    outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
876
    outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
877
    inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
878
    outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
879
    outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
880
 
881
    -- Configuration space for implementation-defined space.
882
    configStb_o : out std_logic;
883
    configWe_o : out std_logic;
884
    configAddr_o : out std_logic_vector(23 downto 0);
885
    configData_o : out std_logic_vector(31 downto 0);
886
    configData_i : in std_logic_vector(31 downto 0));
887
end entity;
888
 
889
 
890
-------------------------------------------------------------------------------
891
-- Architecture for SwitchPort.
892
-------------------------------------------------------------------------------
893
architecture SwitchPortMaintenanceImpl of SwitchPortMaintenance is
894
 
895
  component MemoryDualPort is
896
    generic(
897
      ADDRESS_WIDTH : natural := 1;
898
      DATA_WIDTH : natural := 1);
899
    port(
900
      clkA_i : in std_logic;
901
      enableA_i : in std_logic;
902
      writeEnableA_i : in std_logic;
903
      addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
904
      dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
905
      dataA_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
906
 
907
      clkB_i : in std_logic;
908
      enableB_i : in std_logic;
909
      addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
910
      dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
911
  end component;
912
 
913
  component MemorySinglePort is
914
    generic(
915
      ADDRESS_WIDTH : natural := 1;
916
      DATA_WIDTH : natural := 1);
917
    port(
918
      clk_i : in std_logic;
919
      enable_i : in std_logic;
920
      writeEnable_i : in std_logic;
921
      address_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
922
      data_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
923
      data_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
924
  end component;
925
 
926
  component Crc16CITT is
927
    port(
928
      d_i : in std_logic_vector(15 downto 0);
929
      crc_i : in std_logic_vector(15 downto 0);
930
      crc_o : out std_logic_vector(15 downto 0));
931
  end component;
932
 
933
  type MasterStateType is (STATE_IDLE,
934
                           STATE_CHECK_FRAME,
935
                           STATE_RELAY_READ_RESPONSE,
936
                           STATE_RELAY_WRITE_RESPONSE,
937
                           STATE_SEND_READ_REQUEST,
938
                           STATE_SEND_WRITE_REQUEST,
939
                           STATE_SEND_READ_RESPONSE,
940
                           STATE_SEND_WRITE_RESPONSE,
941
                           STATE_START_PORT_LOOKUP,
942
                           STATE_READ_PORT_LOOKUP,
943
                           STATE_READ_TARGET_PORT,
944
                           STATE_WAIT_TARGET_PORT,
945
                           STATE_WAIT_TARGET_WRITE,
946
                           STATE_WAIT_COMPLETE,
947
                           STATE_WAIT_SLAVE);
948
  signal masterState : MasterStateType;
949
 
950
  signal crc16Data : std_logic_vector(31 downto 0);
951
  signal crc16Current : std_logic_vector(15 downto 0);
952
  signal crc16Temp : std_logic_vector(15 downto 0);
953
  signal crc16Next : std_logic_vector(15 downto 0);
954
 
955
  signal configEnable : std_logic;
956
  signal configWrite : std_logic;
957
  signal configAddress : std_logic_vector(23 downto 0);
958
  signal configDataWrite : std_logic_vector(31 downto 0);
959
  signal configDataRead, configDataReadInternal : std_logic_vector(31 downto 0);
960
 
961
  signal outboundFrameEnable : std_logic;
962
  signal outboundFrameWrite : std_logic;
963
  signal outboundFrameAddress : std_logic_vector(2 downto 0);
964
  signal outboundFrameDataWrite : std_logic_vector(31 downto 0);
965
  signal outboundFrameDataRead : std_logic_vector(31 downto 0);
966
  signal outboundFrameLength : std_logic_vector(2 downto 0);
967
 
968
  type SlaveStateType is (STATE_READY,
969
                          STATE_BUSY);
970
  signal slaveState : SlaveStateType;
971
  signal slaveAck : std_logic;
972
 
973
  signal inboundFrameReady : std_logic;
974
  signal inboundFramePort : std_logic_vector(7 downto 0);
975
  signal inboundFrameLength : natural range 0 to 7;
976
  signal inboundFrameComplete : std_logic;
977
 
978
  signal vc : std_logic;
979
  signal crf : std_logic;
980
  signal prio : std_logic_vector(1 downto 0);
981
  signal tt : std_logic_vector(1 downto 0);
982
  signal ftype : std_logic_vector(3 downto 0);
983
  signal destinationId : std_logic_vector(15 downto 0);
984
  signal sourceId : std_logic_vector(15 downto 0);
985
  signal transaction : std_logic_vector(3 downto 0);
986
  signal size : std_logic_vector(3 downto 0);
987
  signal srcTid : std_logic_vector(7 downto 0);
988
  signal hopCount : std_logic_vector(7 downto 0);
989
  signal configOffset : std_logic_vector(20 downto 0);
990
  signal wdptr : std_logic;
991
  signal content : std_logic_vector(63 downto 0);
992
 
993
  -----------------------------------------------------------------------------
994
  -- Route table access signals.
995
  -----------------------------------------------------------------------------
996
 
997
  signal address0 : std_logic_vector(7 downto 0);
998
  signal address1 : std_logic_vector(7 downto 0);
999
  signal address2 : std_logic_vector(7 downto 0);
1000
  signal address3 : std_logic_vector(7 downto 0);
1001
 
1002
  signal lookupEnable : std_logic;
1003
  signal lookupAddress : std_logic_vector(10 downto 0);
1004
  signal lookupData : std_logic_vector(7 downto 0);
1005
  signal lookupAck : std_logic;
1006
 
1007
  signal routeTableEnable : std_logic;
1008
  signal routeTableWrite : std_logic;
1009
  signal routeTableAddress : std_logic_vector(10 downto 0);
1010
  signal routeTablePortWrite : std_logic_vector(7 downto 0);
1011
  signal routeTablePortRead : std_logic_vector(7 downto 0);
1012
 
1013
  signal routeTablePortDefault : std_logic_vector(7 downto 0);
1014
 
1015
  -----------------------------------------------------------------------------
1016
  -- Configuration space signals.
1017
  -----------------------------------------------------------------------------
1018
 
1019
  signal discovered : std_logic;
1020
 
1021
  signal hostBaseDeviceIdLocked : std_logic;
1022
  signal hostBaseDeviceId : std_logic_vector(15 downto 0);
1023
  signal componentTag : std_logic_vector(31 downto 0);
1024
 
1025
  signal portLinkTimeout : std_logic_vector(23 downto 0);
1026
 
1027
  signal outputPortEnable : Array1(SWITCH_PORTS-1 downto 0);
1028
  signal inputPortEnable : Array1(SWITCH_PORTS-1 downto 0);
1029
 
1030
begin
1031
 
1032
  -----------------------------------------------------------------------------
1033
  -- Memory to contain the outbound frame.
1034
  -----------------------------------------------------------------------------
1035
 
1036
  OutboundFrameMemory: MemorySinglePort
1037
    generic map(
1038
      ADDRESS_WIDTH=>3, DATA_WIDTH=>32)
1039
    port map(
1040
      clk_i=>clk,
1041
      enable_i=>outboundFrameEnable, writeEnable_i=>outboundFrameWrite,
1042
      address_i=>outboundFrameAddress,
1043
      data_i=>outboundFrameDataWrite, data_o=>outboundFrameDataRead);
1044
 
1045
  -----------------------------------------------------------------------------
1046
  -- CRC generation for outbound frames.
1047
  -----------------------------------------------------------------------------
1048
 
1049
  crc16Data <= outboundFrameDataWrite;
1050
 
1051
  -- REMARK: Insert FFs here to make the critical path shorter...
1052
  Crc16High: Crc16CITT
1053
    port map(
1054
      d_i=>crc16Data(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp);
1055
  Crc16Low: Crc16CITT
1056
    port map(
1057
      d_i=>crc16Data(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next);
1058
 
1059
  -----------------------------------------------------------------------------
1060
  -- Master interface process.
1061
  -----------------------------------------------------------------------------
1062
  Master: process(clk, areset_n)
1063
  begin
1064
    if (areset_n = '0') then
1065
      masterState <= STATE_IDLE;
1066
 
1067
      lookupStb_o <= '0';
1068
      lookupAddr_o <= (others => '0');
1069
 
1070
      masterCyc_o <= '0';
1071
      masterStb_o <= '0';
1072
      masterWe_o <= '0';
1073
      masterAddr_o <= (others => '0');
1074
      masterData_o <= (others => '0');
1075
 
1076
      configEnable <= '0';
1077
      configWrite <= '0';
1078
      configAddress <= (others => '0');
1079
      configDataWrite <= (others => '0');
1080
 
1081
      outboundFrameEnable <= '0';
1082
      outboundFrameWrite <= '0';
1083
      outboundFrameAddress <= (others=>'0');
1084
      outboundFrameDataWrite <= (others=>'0');
1085
      outboundFrameLength <= (others=>'0');
1086
 
1087
      inboundFrameComplete <= '0';
1088
    elsif (clk'event and clk = '1') then
1089
      configEnable <= '0';
1090
      configWrite <= '0';
1091
      inboundFrameComplete <= '0';
1092
 
1093
      case masterState is
1094
 
1095
        when STATE_IDLE =>
1096
          ---------------------------------------------------------------------
1097
          -- 
1098
          ---------------------------------------------------------------------
1099
 
1100
          -- Wait for a full frame to be available.
1101
          if (inboundFrameReady = '1') then
1102
            if (inboundFrameLength > 3) then
1103
              masterState <= STATE_CHECK_FRAME;
1104
            else
1105
              -- Frame is too short.
1106
              -- REMARK: Discard the frame.
1107
            end if;
1108
          end if;
1109
 
1110
        when STATE_CHECK_FRAME =>
1111
          ---------------------------------------------------------------------
1112
          -- 
1113
          ---------------------------------------------------------------------
1114
 
1115
          -- Check if the frame has 16-bit addresses and is a maintenance frame.
1116
          if (tt = "01") and (ftype = FTYPE_MAINTENANCE_CLASS) then
1117
            -- Maintenance class frame and 16-bit addresses.
1118
 
1119
            -- Check the frame type.
1120
            case transaction is
1121
 
1122
              when "0000" =>
1123
                ---------------------------------------------------------------
1124
                -- Maintenance read request.
1125
                ---------------------------------------------------------------
1126
 
1127
                -- Check if the frame is for us.
1128
                if (hopCount = x"00") then
1129
                  -- This frame is for us.
1130
                  configEnable <= '1';
1131
                  configWrite <= '0';
1132
                  configAddress <= configOffset & wdptr & "00";
1133
 
1134
                  outboundFrameEnable <= '1';
1135
                  outboundFrameWrite <= '1';
1136
                  outboundFrameAddress <= (others=>'0');
1137
                  outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & sourceId;
1138
                  crc16Current <= x"ffff";
1139
 
1140
                  masterState <= STATE_SEND_READ_RESPONSE;
1141
                else
1142
                  -- This frame is not for us.
1143
                  -- Decrement hop_count and relay.
1144
                  outboundFrameEnable <= '1';
1145
                  outboundFrameWrite <= '1';
1146
                  outboundFrameAddress <= (others=>'0');
1147
                  outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId;
1148
                  crc16Current <= x"ffff";
1149
 
1150
                  masterState <= STATE_SEND_READ_REQUEST;
1151
                end if;
1152
 
1153
              when "0001" =>
1154
                ---------------------------------------------------------------
1155
                -- Maintenance write request.
1156
                ---------------------------------------------------------------
1157
 
1158
                -- Check if the frame is for us.
1159
                if (hopCount = x"00") then
1160
                  -- This frame is for us.
1161
                  configEnable <= '1';
1162
                  configWrite <= '1';
1163
                  configAddress <= configOffset & wdptr & "00";
1164
 
1165
                  if (wdptr = '0') then
1166
                    configDataWrite <= content(63 downto 32);
1167
                  else
1168
                    configDataWrite <= content(31 downto 0);
1169
                  end if;
1170
 
1171
                  outboundFrameEnable <= '1';
1172
                  outboundFrameWrite <= '1';
1173
                  outboundFrameAddress <= (others=>'0');
1174
                  outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & sourceId;
1175
                  crc16Current <= x"ffff";
1176
 
1177
                  masterState <= STATE_SEND_WRITE_RESPONSE;
1178
                else
1179
                  -- This frame is not for us.
1180
                  -- Decrement hop_count and relay.
1181
                  outboundFrameEnable <= '1';
1182
                  outboundFrameWrite <= '1';
1183
                  outboundFrameAddress <= (others=>'0');
1184
                  outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId;
1185
                  crc16Current <= x"ffff";
1186
 
1187
                  masterState <= STATE_SEND_WRITE_REQUEST;
1188
                end if;
1189
 
1190
              when "0010" =>
1191
                ---------------------------------------------------------------
1192
                -- Maintenance read response frame.
1193
                ---------------------------------------------------------------
1194
 
1195
                outboundFrameEnable <= '1';
1196
                outboundFrameWrite <= '1';
1197
                outboundFrameAddress <= (others=>'0');
1198
                outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId;
1199
                crc16Current <= x"ffff";
1200
 
1201
                -- Relay frame.
1202
                masterState <= STATE_RELAY_READ_RESPONSE;
1203
 
1204
              when "0011" =>
1205
                ---------------------------------------------------------------
1206
                -- Maintenance write response frame.
1207
                ---------------------------------------------------------------
1208
 
1209
                outboundFrameEnable <= '1';
1210
                outboundFrameWrite <= '1';
1211
                outboundFrameAddress <= (others=>'0');
1212
                outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId;
1213
                crc16Current <= x"ffff";
1214
 
1215
                -- Relay frame.
1216
                masterState <= STATE_RELAY_WRITE_RESPONSE;
1217
 
1218
              when "0100" =>
1219
                ---------------------------------------------------------------
1220
                -- Maintenance port write frame.
1221
                ---------------------------------------------------------------
1222
 
1223
                -- REMARK: Support these???
1224
 
1225
              when others =>
1226
                ---------------------------------------------------------------
1227
                -- Unsupported frame type.
1228
                ---------------------------------------------------------------
1229
 
1230
                -- REMARK: Support these???
1231
            end case;
1232
          else
1233
            -- Non-maintenance class frame or unsupported address type.
1234
            -- REMARK: These should not end up here... discard them???
1235
          end if;
1236
 
1237
        when STATE_RELAY_READ_RESPONSE =>
1238
          ---------------------------------------------------------------------
1239
          -- A maintenance response has been received. It should be relayed as
1240
          -- is using the destinationId. 
1241
          ---------------------------------------------------------------------
1242
 
1243
          case to_integer(unsigned(outboundFrameAddress)) is
1244
            when 0 =>
1245
              outboundFrameEnable <= '1';
1246
              outboundFrameWrite <= '1';
1247
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1248
              outboundFrameDataWrite <= sourceId & transaction & size & srcTid;
1249
              crc16Current <= crc16Next;
1250
            when 1 =>
1251
              outboundFrameEnable <= '1';
1252
              outboundFrameWrite <= '1';
1253
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1254
              outboundFrameDataWrite <= hopCount & configOffset & wdptr & "00";
1255
              crc16Current <= crc16Next;
1256
            when 2 =>
1257
              outboundFrameEnable <= '1';
1258
              outboundFrameWrite <= '1';
1259
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1260
              outboundFrameDataWrite <= content(63 downto 32);
1261
              crc16Current <= crc16Next;
1262
            when 3 =>
1263
              outboundFrameEnable <= '1';
1264
              outboundFrameWrite <= '1';
1265
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1266
              outboundFrameDataWrite <= content(31 downto 0);
1267
              crc16Current <= crc16Next;
1268
            when 4 =>
1269
              outboundFrameEnable <= '1';
1270
              outboundFrameWrite <= '1';
1271
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1272
              outboundFrameDataWrite(31 downto 16) <= crc16Next;
1273
              outboundFrameDataWrite(15 downto 0) <= x"0000";
1274
            when others =>
1275
              outboundFrameEnable <= '1';
1276
              outboundFrameWrite <= '0';
1277
              outboundFrameAddress <= (others=>'0');
1278
              outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1279
              masterState <= STATE_START_PORT_LOOKUP;
1280
          end case;
1281
 
1282
        when STATE_RELAY_WRITE_RESPONSE =>
1283
          ---------------------------------------------------------------------
1284
          -- A maintenance response has been received. It should be relayed as
1285
          -- is using the destinationId. 
1286
          ---------------------------------------------------------------------
1287
 
1288
          case to_integer(unsigned(outboundFrameAddress)) is
1289
            when 0 =>
1290
              outboundFrameEnable <= '1';
1291
              outboundFrameWrite <= '1';
1292
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1293
              outboundFrameDataWrite <= sourceId & transaction & size & srcTid;
1294
              crc16Current <= crc16Next;
1295
            when 1 =>
1296
              outboundFrameEnable <= '1';
1297
              outboundFrameWrite <= '1';
1298
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1299
              outboundFrameDataWrite <= hopCount & configOffset & wdptr & "00";
1300
              crc16Current <= crc16Next;
1301
            when 2 =>
1302
              outboundFrameEnable <= '1';
1303
              outboundFrameWrite <= '1';
1304
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1305
              outboundFrameDataWrite(31 downto 16) <= crc16Next;
1306
              outboundFrameDataWrite(15 downto 0) <= x"0000";
1307
            when others =>
1308
              outboundFrameEnable <= '1';
1309
              outboundFrameWrite <= '0';
1310
              outboundFrameAddress <= (others=>'0');
1311
              outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1312
              masterState <= STATE_START_PORT_LOOKUP;
1313
          end case;
1314
 
1315
        when STATE_SEND_READ_REQUEST =>
1316
          ---------------------------------------------------------------------
1317
          -- A read request has been received but the hopcount is larger than
1318
          -- zero. Decrement the hopcount, recalculate the crc and relay the
1319
          -- frame using the destinationId. 
1320
          ---------------------------------------------------------------------
1321
 
1322
          case to_integer(unsigned(outboundFrameAddress)) is
1323
            when 0 =>
1324
              outboundFrameEnable <= '1';
1325
              outboundFrameWrite <= '1';
1326
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1327
              outboundFrameDataWrite <= sourceId & transaction & size & srcTid;
1328
              crc16Current <= crc16Next;
1329
            when 1 =>
1330
              outboundFrameEnable <= '1';
1331
              outboundFrameWrite <= '1';
1332
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1333
              outboundFrameDataWrite <= std_logic_vector(unsigned(hopCount) - 1) & configOffset & wdptr & "00";
1334
              crc16Current <= crc16Next;
1335
            when 2 =>
1336
              outboundFrameEnable <= '1';
1337
              outboundFrameWrite <= '1';
1338
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1339
              outboundFrameDataWrite(31 downto 16) <= crc16Next;
1340
              outboundFrameDataWrite(15 downto 0) <= x"0000";
1341
            when others =>
1342
              outboundFrameEnable <= '1';
1343
              outboundFrameWrite <= '0';
1344
              outboundFrameAddress <= (others=>'0');
1345
              outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1346
              masterState <= STATE_START_PORT_LOOKUP;
1347
          end case;
1348
 
1349
        when STATE_SEND_WRITE_REQUEST =>
1350
          ---------------------------------------------------------------------
1351
          -- A write request has been received but the hopcount is larger than
1352
          -- zero. Decrement the hopcount, recalculate the crc and relay the
1353
          -- frame using the destinationId. 
1354
          ---------------------------------------------------------------------
1355
 
1356
          case to_integer(unsigned(outboundFrameAddress)) is
1357
            when 0 =>
1358
              outboundFrameEnable <= '1';
1359
              outboundFrameWrite <= '1';
1360
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1361
              outboundFrameDataWrite <= sourceId & transaction & size & srcTid;
1362
              crc16Current <= crc16Next;
1363
            when 1 =>
1364
              outboundFrameEnable <= '1';
1365
              outboundFrameWrite <= '1';
1366
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1367
              outboundFrameDataWrite <= std_logic_vector(unsigned(hopCount) - 1) & configOffset & wdptr & "00";
1368
              crc16Current <= crc16Next;
1369
            when 2 =>
1370
              outboundFrameEnable <= '1';
1371
              outboundFrameWrite <= '1';
1372
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1373
              outboundFrameDataWrite <= content(63 downto 32);
1374
              crc16Current <= crc16Next;
1375
            when 3 =>
1376
              outboundFrameEnable <= '1';
1377
              outboundFrameWrite <= '1';
1378
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1379
              outboundFrameDataWrite <= content(31 downto 0);
1380
              crc16Current <= crc16Next;
1381
            when 4 =>
1382
              outboundFrameEnable <= '1';
1383
              outboundFrameWrite <= '1';
1384
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1385
              outboundFrameDataWrite(31 downto 16) <= crc16Next;
1386
              outboundFrameDataWrite(15 downto 0) <= x"0000";
1387
            when others =>
1388
              outboundFrameEnable <= '1';
1389
              outboundFrameWrite <= '0';
1390
              outboundFrameAddress <= (others=>'0');
1391
              outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1392
              masterState <= STATE_START_PORT_LOOKUP;
1393
          end case;
1394
 
1395
        when STATE_SEND_READ_RESPONSE =>
1396
          ---------------------------------------------------------------------
1397
          -- A read request has been received with a hopcount that are zero.
1398
          -- Create a read response, calculate crc and write it to the port it
1399
          -- came from.
1400
          ---------------------------------------------------------------------
1401
 
1402
          case to_integer(unsigned(outboundFrameAddress)) is
1403
            when 0 =>
1404
              outboundFrameEnable <= '1';
1405
              outboundFrameWrite <= '1';
1406
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1407
              outboundFrameDataWrite <= destinationId & "0010" & "0000" & srcTid;
1408
              crc16Current <= crc16Next;
1409
            when 1 =>
1410
              outboundFrameEnable <= '1';
1411
              outboundFrameWrite <= '1';
1412
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1413
              outboundFrameDataWrite <= x"ff" & x"000000";
1414
              crc16Current <= crc16Next;
1415
            when 2 =>
1416
              outboundFrameEnable <= '1';
1417
              outboundFrameWrite <= '1';
1418
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1419
              if (wdptr = '1') then
1420
                outboundFrameDataWrite <= (others => '0');
1421
              else
1422
                outboundFrameDataWrite <= configDataRead(31 downto 0);
1423
              end if;
1424
              crc16Current <= crc16Next;
1425
            when 3 =>
1426
              outboundFrameEnable <= '1';
1427
              outboundFrameWrite <= '1';
1428
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1429
              if (wdptr = '1') then
1430
                outboundFrameDataWrite <= configDataRead(31 downto 0);
1431
              else
1432
                outboundFrameDataWrite <= (others => '0');
1433
              end if;
1434
              crc16Current <= crc16Next;
1435
            when 4 =>
1436
              outboundFrameEnable <= '1';
1437
              outboundFrameWrite <= '1';
1438
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1439
              outboundFrameDataWrite(31 downto 16) <= crc16Next;
1440
              outboundFrameDataWrite(15 downto 0) <= x"0000";
1441
            when others =>
1442
              outboundFrameEnable <= '1';
1443
              outboundFrameWrite <= '0';
1444
              outboundFrameAddress <= (others=>'0');
1445
              outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1446
              masterAddr_o <= '0' & inboundFramePort & '0';
1447
              masterState <= STATE_READ_TARGET_PORT;
1448
          end case;
1449
 
1450
        when STATE_SEND_WRITE_RESPONSE =>
1451
          ---------------------------------------------------------------------
1452
          -- A write request has been received with a hopcount that are zero.
1453
          -- Create a write response, calculate crc and write it to the port it
1454
          -- came from.
1455
          ---------------------------------------------------------------------
1456
 
1457
          case to_integer(unsigned(outboundFrameAddress)) is
1458
            when 0 =>
1459
              outboundFrameEnable <= '1';
1460
              outboundFrameWrite <= '1';
1461
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1462
              outboundFrameDataWrite <= destinationId & "0011" & "0000" & srcTid;
1463
              crc16Current <= crc16Next;
1464
            when 1 =>
1465
              outboundFrameEnable <= '1';
1466
              outboundFrameWrite <= '1';
1467
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1468
              outboundFrameDataWrite <= x"ff" & x"000000";
1469
              crc16Current <= crc16Next;
1470
            when 2 =>
1471
              outboundFrameEnable <= '1';
1472
              outboundFrameWrite <= '1';
1473
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1474
              outboundFrameDataWrite(31 downto 16) <= crc16Next;
1475
              outboundFrameDataWrite(15 downto 0) <= x"0000";
1476
            when others =>
1477
              outboundFrameEnable <= '1';
1478
              outboundFrameWrite <= '0';
1479
              outboundFrameAddress <= (others=>'0');
1480
              outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1481
              masterAddr_o <= '0' & inboundFramePort & '0';
1482
              masterState <= STATE_READ_TARGET_PORT;
1483
          end case;
1484
 
1485
        when STATE_START_PORT_LOOKUP =>
1486
          ---------------------------------------------------------------------
1487
          -- 
1488
          ---------------------------------------------------------------------
1489
 
1490
          -- Initiate a port-lookup of the destination address.
1491
          lookupStb_o <= '1';
1492
          lookupAddr_o <= destinationId;
1493
          masterState <= STATE_READ_PORT_LOOKUP;
1494
 
1495
        when STATE_READ_PORT_LOOKUP =>
1496
          ---------------------------------------------------------------------
1497
          -- 
1498
          ---------------------------------------------------------------------
1499
 
1500
          -- Wait for the routing table to complete the request.
1501
          if (lookupAck_i = '1') then
1502
            -- The address lookup is complete.
1503
 
1504
            -- Terminate the lookup cycle.
1505
            lookupStb_o <= '0';
1506
 
1507
            -- Wait for the target port to reply.
1508
            masterAddr_o <= '0' & lookupData_i & '0';
1509
            masterState <= STATE_READ_TARGET_PORT;
1510
          else
1511
            -- Wait until the address lookup is complete.
1512
            -- REMARK: Timeout here???
1513
          end if;
1514
 
1515
        when STATE_READ_TARGET_PORT =>
1516
          ---------------------------------------------------------------------
1517
          -- 
1518
          ---------------------------------------------------------------------
1519
 
1520
          -- Read the status of the target port using the result from the
1521
          -- lookup in the routing table.
1522
          masterCyc_o <= '1';
1523
          masterStb_o <= '1';
1524
          masterWe_o <= '0';
1525
          masterState <= STATE_WAIT_TARGET_PORT;
1526
 
1527
        when STATE_WAIT_TARGET_PORT =>
1528
          ---------------------------------------------------------------------
1529
          -- 
1530
          ---------------------------------------------------------------------
1531
 
1532
          -- Wait for the target port to complete the request.
1533
          if (masterAck_i = '1') then
1534
            if (masterData_i = '0') then
1535
              -- The target port has empty buffers to receive the frame.
1536
 
1537
              -- Write the first word of the frame to the target port.
1538
              -- The masterData_o has already been assigned.
1539
              masterCyc_o <= '1';
1540
              masterStb_o <= '1';
1541
              masterWe_o <= '1';
1542
              masterAddr_o(0) <= '1';
1543
 
1544
              -- Read the first word in the frame and update the frame address.
1545
              masterData_o <= outboundFrameDataRead;
1546
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1547
 
1548
              -- Change state to transfer the frame.
1549
              masterState <= STATE_WAIT_TARGET_WRITE;
1550
            else
1551
              -- The target port has no empty buffer to receive the frame.
1552
              -- Terminate the cycle and retry later.
1553
              masterCyc_o <= '0';
1554
              masterStb_o <= '0';
1555
              masterState <= STATE_READ_TARGET_PORT;
1556
            end if;
1557
          else
1558
            -- Wait for the target port to reply.
1559
            -- REMARK: Timeout here???
1560
          end if;
1561
 
1562
        when STATE_WAIT_TARGET_WRITE =>
1563
          ---------------------------------------------------------------------
1564
          -- 
1565
          ---------------------------------------------------------------------
1566
 
1567
          -- Wait for the target port to complete the request.
1568
          if (masterAck_i = '1') then
1569
            -- The target port is ready.
1570
 
1571
            -- Check if the frame has ended.
1572
            if (outboundFrameLength /= outboundFrameAddress) then
1573
              -- The frame has not ended.
1574
 
1575
              -- There are more data to transfer.
1576
              masterData_o <= outboundFrameDataRead;
1577
              outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
1578
            else
1579
              -- There are no more data to transfer.
1580
 
1581
              -- Tell the target port that the frame is complete.
1582
              masterWe_o <= '1';
1583
              masterAddr_o(0) <= '0';
1584
              masterData_o <= x"00000001";
1585
              outboundFrameAddress <= (others=>'0');
1586
 
1587
              -- Change state to wait for the target port to finalize the write
1588
              -- of the full frame.
1589
              masterState <= STATE_WAIT_COMPLETE;
1590
            end if;
1591
          else
1592
            -- Wait for the target port to reply.
1593
            -- REMARK: Timeout here???
1594
          end if;
1595
 
1596
        when STATE_WAIT_COMPLETE =>
1597
          ---------------------------------------------------------------------
1598
          -- 
1599
          ---------------------------------------------------------------------
1600
 
1601
          -- Wait for the target port to complete the final request.
1602
          if (masterAck_i = '1') then
1603
            -- The target port has finalized the write of the frame.
1604
            masterCyc_o <= '0';
1605
            masterStb_o <= '0';
1606
            masterState <= STATE_WAIT_SLAVE;
1607
 
1608
            -- Indicate the frame has been read.
1609
            inboundFrameComplete <= '1';
1610
          else
1611
            -- Wait for the target port to reply.
1612
            -- REMARK: Timeout here???
1613
          end if;
1614
 
1615
        when STATE_WAIT_SLAVE =>
1616
          ---------------------------------------------------------------------
1617
          -- 
1618
          ---------------------------------------------------------------------
1619
          masterState <= STATE_IDLE;
1620
 
1621
        when others =>
1622
          ---------------------------------------------------------------------
1623
          -- 
1624
          ---------------------------------------------------------------------
1625
      end case;
1626
    end if;
1627
  end process;
1628
 
1629
 
1630
  -----------------------------------------------------------------------------
1631
  -- Slave interface process.
1632
  -----------------------------------------------------------------------------
1633
  -- Addr |  Read  | Write
1634
  --    0 |  full  | abort & complete
1635
  --    1 |  full  | frameData
1636
  Slave: process(clk, areset_n)
1637
  begin
1638
    if (areset_n = '0') then
1639
      slaveState <= STATE_READY;
1640
      slaveData_o <= '0';
1641
      slaveAck <= '0';
1642
 
1643
      vc <= '0';
1644
      crf <= '0';
1645
      prio <= (others=>'0');
1646
      tt <= (others=>'0');
1647
      ftype <= (others=>'0');
1648
      destinationId <= (others=>'0');
1649
      sourceId <= (others=>'0');
1650
      transaction <= (others=>'0');
1651
      size <= (others=>'0');
1652
      srcTid <= (others=>'0');
1653
      hopCount <= (others=>'0');
1654
      configOffset <= (others=>'0');
1655
      wdptr <= '0';
1656
      content <= (others=>'0');
1657
 
1658
      inboundFrameReady <= '0';
1659
      inboundFramePort <= (others => '0');
1660
      inboundFrameLength <= 0;
1661
    elsif (clk'event and clk = '1') then
1662
      slaveAck <= '0';
1663
 
1664
      case slaveState is
1665
        when STATE_READY =>
1666
          ---------------------------------------------------------------------
1667
          -- Ready to receive a new frame.
1668
          ---------------------------------------------------------------------
1669
 
1670
          -- Check if any cycle is active.
1671
          if ((slaveCyc_i = '1') and (slaveStb_i = '1') and (slaveAck = '0')) then
1672
            -- Cycle is active.
1673
 
1674
            -- Check if writing.
1675
            if (slaveWe_i = '1') then
1676
              -- Writing request.
1677
 
1678
              -- Check if the cycle is accessing the status- or data address.
1679
              if (slaveAddr_i(0) = '0') then
1680
                -- Writing to port status address.
1681
 
1682
                if (slaveData_i(0) = '1') and (slaveData_i(1) = '0') then
1683
                  -- A frame has been written.
1684
 
1685
                  -- Indicate the frame is ready for processing.
1686
                  -- The slave address contains the number of the accessing port.
1687
                  inboundFrameReady <= '1';
1688
                  inboundFramePort <= slaveAddr_i(8 downto 1);
1689
 
1690
                  -- Change state until the frame has been processed.
1691
                  slaveState <= STATE_BUSY;
1692
                else
1693
                  -- The frame has been aborted.
1694
                  -- Reset the received frame length.
1695
                  inboundFrameLength <= 0;
1696
                end if;
1697
              else
1698
                -- Write frame content into the frame buffer.
1699
 
1700
                -- Check which frame index that is written.
1701
                case inboundFrameLength is
1702
                  when 0 =>
1703
                    vc <= slaveData_i(25);
1704
                    crf <= slaveData_i(24);
1705
                    prio <= slaveData_i(23 downto 22);
1706
                    tt <= slaveData_i(21 downto 20);
1707
                    ftype <= slaveData_i(19 downto 16);
1708
                    destinationId <= slaveData_i(15 downto 0);
1709
                    inboundFrameLength <= inboundFrameLength + 1;
1710
                  when 1 =>
1711
                    sourceId <= slaveData_i(31 downto 16);
1712
                    transaction <= slaveData_i(15 downto 12);
1713
                    size <= slaveData_i(11 downto 8);
1714
                    srcTid <= slaveData_i(7 downto 0);
1715
                    inboundFrameLength <= inboundFrameLength + 1;
1716
                  when 2 =>
1717
                    hopCount <= slaveData_i(31 downto 24);
1718
                    configOffset <= slaveData_i(23 downto 3);
1719
                    wdptr <= slaveData_i(2);
1720
                    inboundFrameLength <= inboundFrameLength + 1;
1721
                  when 3 =>
1722
                    -- Note that crc will be assigned here if there are no
1723
                    -- content in the frame.
1724
                    content(63 downto 32) <= slaveData_i;
1725
                    inboundFrameLength <= inboundFrameLength + 1;
1726
                  when 4 =>
1727
                    content(31 downto 0) <= slaveData_i;
1728
                    inboundFrameLength <= inboundFrameLength + 1;
1729
                  when others =>
1730
                    -- Dont support longer frames.
1731
                    -- REMARK: Add support for longer frames??? Especially
1732
                    -- received frames that only should be routed...
1733
                end case;
1734
              end if;
1735
 
1736
              -- Send acknowledge.
1737
              slaveAck <= '1';
1738
            else
1739
              -- Reading request.
1740
 
1741
              -- Reading the status address.
1742
              -- Always indicate that we are ready to accept a new frame.
1743
              slaveData_o <= '0';
1744
 
1745
              -- Send acknowledge.
1746
              slaveAck <= '1';
1747
            end if;
1748
          else
1749
            -- No cycle is active.
1750
          end if;
1751
 
1752
        when STATE_BUSY =>
1753
          ---------------------------------------------------------------------
1754
          -- Waiting for a received frame to be processed.
1755
          ---------------------------------------------------------------------
1756
 
1757
          -- Check if any cycle is active.
1758
          if ((slaveCyc_i = '1') and (slaveStb_i = '1') and (slaveAck = '0')) then
1759
            -- Cycle is active.
1760
 
1761
            -- Check if writing.
1762
            if (slaveWe_i = '1') then
1763
              -- Writing.
1764
              -- Dont do anything.
1765
 
1766
              -- Send acknowledge.
1767
              slaveAck <= '1';
1768
            else
1769
              -- Read port data address.
1770
 
1771
              -- Reading the status address.
1772
              -- Always indicate that we are busy.
1773
              slaveData_o <= '1';
1774
 
1775
              -- Send acknowledge.
1776
              slaveAck <= '1';
1777
            end if;
1778
          else
1779
            -- No cycle is active.
1780
            -- Dont do anything.
1781
          end if;
1782
 
1783
          -- Check if the master process has processed the received frame.
1784
          if (inboundFrameComplete = '1') then
1785
            -- The master has processed the frame.
1786
            inboundFrameReady <= '0';
1787
            inboundFrameLength <= 0;
1788
            slaveState <= STATE_READY;
1789
          else
1790
            -- The master is not ready yet.
1791
            -- Dont do anything.
1792
          end if;
1793
 
1794
        when others =>
1795
          ---------------------------------------------------------------------
1796
          -- 
1797
          ---------------------------------------------------------------------
1798
          null;
1799
 
1800
      end case;
1801
    end if;
1802
  end process;
1803
 
1804
  slaveAck_o <= slaveAck;
1805
 
1806
  -----------------------------------------------------------------------------
1807
  -- Logic implementing the routing table access.
1808
  -----------------------------------------------------------------------------
1809
 
1810
  -- Lookup interface port memory signals.
1811
  lookupEnable <= '1' when (lookupStb_i = '1') and (lookupAddr_i(15 downto 11) = "00000") else '0';
1812
  lookupAddress <= lookupAddr_i(10 downto 0);
1813
  lookupData_o <= lookupData when (lookupEnable = '1') else routeTablePortDefault;
1814
  lookupAck_o <= lookupAck;
1815
  LookupProcess: process(clk, areset_n)
1816
  begin
1817
    if (areset_n = '0') then
1818
      lookupAck <= '0';
1819
    elsif (clk'event and clk = '1') then
1820
      if ((lookupStb_i = '1') and (lookupAck = '0')) then
1821
        lookupAck <= '1';
1822
      else
1823
        lookupAck <= '0';
1824
      end if;
1825
    end if;
1826
  end process;
1827
 
1828
  -- Dual port memory containing the routing table.
1829
  RoutingTable: MemoryDualPort
1830
    generic map(
1831
      ADDRESS_WIDTH=>11, DATA_WIDTH=>8)
1832
    port map(
1833
      clkA_i=>clk, enableA_i=>routeTableEnable, writeEnableA_i=>routeTableWrite,
1834
      addressA_i=>routeTableAddress,
1835
      dataA_i=>routeTablePortWrite, dataA_o=>routeTablePortRead,
1836
      clkB_i=>clk, enableB_i=>lookupEnable,
1837
      addressB_i=>lookupAddress, dataB_o=>lookupData);
1838
 
1839
  -----------------------------------------------------------------------------
1840
  -- Configuration memory.
1841
  -----------------------------------------------------------------------------
1842
 
1843
  portLinkTimeout_o <= portLinkTimeout;
1844
  outputPortEnable_o <= outputPortEnable;
1845
  inputPortEnable_o <= inputPortEnable;
1846
 
1847
  configStb_o <= '1' when ((configEnable = '1') and (configAddress(23 downto 16) /= x"00")) else '0';
1848
  configWe_o <= configWrite;
1849
  configAddr_o <= configAddress;
1850
  configData_o <= configDataWrite;
1851
  configDataRead <= configData_i when (configAddress(23 downto 16) /= x"00") else
1852
                    configDataReadInternal;
1853
 
1854
  ConfigMemory: process(areset_n, clk)
1855
  begin
1856
    if (areset_n = '0') then
1857
      configDataReadInternal <= (others => '0');
1858
 
1859
      routeTableEnable <= '1';
1860
      routeTableWrite <= '0';
1861
      routeTableAddress <= (others => '0');
1862
      routeTablePortWrite <= (others => '0');
1863
      routeTablePortDefault <= (others => '0');
1864
 
1865
      discovered <= '0';
1866
 
1867
      hostBaseDeviceIdLocked <= '0';
1868
      hostBaseDeviceId <= (others => '1');
1869
      componentTag <= (others => '0');
1870
 
1871
      portLinkTimeout <= (others => '1');
1872
 
1873
      -- REMARK: These should be set to zero when a port gets initialized...
1874
      outputPortEnable <= (others => '0');
1875
      inputPortEnable <= (others => '0');
1876
 
1877
      localAckIdWrite_o <= (others => '0');
1878
    elsif (clk'event and clk = '1') then
1879
      routeTableWrite <= '0';
1880
      localAckIdWrite_o <= (others => '0');
1881
 
1882
      if (configEnable = '1') then
1883
        -- Check if the access is into implementation defined space or if the
1884
        -- access should be handled here.
1885
        if (configAddress(23 downto 16) /= x"00") then
1886
          -- Accessing implementation defined space.
1887
          -- Make an external access and return the resonse.
1888
          configDataReadInternal <= (others=>'0');
1889
        else
1890
          -- Access should be handled here.
1891
 
1892
          case (configAddress) is
1893
            when x"000000" =>
1894
              -----------------------------------------------------------------
1895
              -- Device Identity CAR. Read-only.
1896
              -----------------------------------------------------------------
1897
 
1898
              configDataReadInternal(31 downto 16) <= DEVICE_IDENTITY;
1899
              configDataReadInternal(15 downto 0) <= DEVICE_VENDOR_IDENTITY;
1900
 
1901
            when x"000004" =>
1902
              -----------------------------------------------------------------
1903
              -- Device Information CAR. Read-only.
1904
              -----------------------------------------------------------------
1905
 
1906
              configDataReadInternal(31 downto 0) <= DEVICE_REV;
1907
 
1908
            when x"000008" =>
1909
              -----------------------------------------------------------------
1910
              -- Assembly Identity CAR. Read-only.
1911
              -----------------------------------------------------------------
1912
 
1913
              configDataReadInternal(31 downto 16) <= ASSY_IDENTITY;
1914
              configDataReadInternal(15 downto 0) <= ASSY_VENDOR_IDENTITY;
1915
 
1916
            when x"00000c" =>
1917
              -----------------------------------------------------------------
1918
              -- Assembly Informaiton CAR. Read-only.
1919
              -----------------------------------------------------------------
1920
 
1921
              configDataReadInternal(31 downto 16) <= ASSY_REV;
1922
              configDataReadInternal(15 downto 0) <= x"0100";
1923
 
1924
            when x"000010" =>
1925
              -----------------------------------------------------------------
1926
              -- Processing Element Features CAR. Read-only.
1927
              -----------------------------------------------------------------
1928
 
1929
              -- Bridge.
1930
              configDataReadInternal(31) <= '0';
1931
 
1932
              -- Memory.
1933
              configDataReadInternal(30) <= '0';
1934
 
1935
              -- Processor.
1936
              configDataReadInternal(29) <= '0';
1937
 
1938
              -- Switch.
1939
              configDataReadInternal(28) <= '1';
1940
 
1941
              -- Reserved.
1942
              configDataReadInternal(27 downto 10) <= (others => '0');
1943
 
1944
              -- Extended route table configuration support.
1945
              configDataReadInternal(9) <= '0';
1946
 
1947
              -- Standard route table configuration support.
1948
              configDataReadInternal(8) <= '1';
1949
 
1950
              -- Reserved.
1951
              configDataReadInternal(7 downto 5) <= (others => '0');
1952
 
1953
              -- Common transport large system support.
1954
              configDataReadInternal(4) <= '1';
1955
 
1956
              -- Extended features.
1957
              configDataReadInternal(3) <= '1';
1958
 
1959
              -- Extended addressing support.
1960
              -- Not a processing element.
1961
              configDataReadInternal(2 downto 0) <= "000";
1962
 
1963
            when x"000014" =>
1964
              -----------------------------------------------------------------
1965
              -- Switch Port Information CAR. Read-only.
1966
              -----------------------------------------------------------------
1967
 
1968
              -- Reserved.
1969
              configDataReadInternal(31 downto 16) <= (others => '0');
1970
 
1971
              -- PortTotal.
1972
              configDataReadInternal(15 downto 8) <=
1973
                std_logic_vector(to_unsigned(SWITCH_PORTS, 8));
1974
 
1975
              -- PortNumber.
1976
              configDataReadInternal(7 downto 0) <= inboundFramePort;
1977
 
1978
            when x"000034" =>
1979
              -----------------------------------------------------------------
1980
              -- Switch Route Table Destination ID Limit CAR.
1981
              -----------------------------------------------------------------
1982
 
1983
              -- Max_destId.
1984
              -- Support 2048 addresses.
1985
              configDataReadInternal(15 downto 0) <= x"0800";
1986
 
1987
            when x"000068" =>
1988
              -----------------------------------------------------------------
1989
              -- Host Base Device ID Lock CSR.
1990
              -----------------------------------------------------------------
1991
 
1992
              if (configWrite = '1') then
1993
                -- Check if this field has been written before.
1994
                if (hostBaseDeviceIdLocked = '0') then
1995
                  -- The field has not been written.
1996
                  -- Lock the field and set the host base device id.
1997
                  hostBaseDeviceIdLocked <= '1';
1998
                  hostBaseDeviceId <= configDataWrite(15 downto 0);
1999
                else
2000
                  -- The field has been written.
2001
                  -- Check if the written data is the same as the stored.
2002
                  if (hostBaseDeviceId = configDataWrite(15 downto 0)) then
2003
                    -- Same as stored, reset the value to its initial value.
2004
                    hostBaseDeviceIdLocked <= '0';
2005
                    hostBaseDeviceId <= (others => '1');
2006
                  else
2007
                    -- Not writing the same as the stored value.
2008
                    -- Ignore the write.
2009
                  end if;
2010
                end if;
2011
              end if;
2012
 
2013
              configDataReadInternal(31 downto 16) <= (others => '0');
2014
              configDataReadInternal(15 downto 0) <= hostBaseDeviceId;
2015
 
2016
            when x"00006c" =>
2017
              -----------------------------------------------------------------
2018
              -- Component TAG CSR.
2019
              -----------------------------------------------------------------
2020
 
2021
              if (configWrite = '1') then
2022
                componentTag <= configDataWrite;
2023
              end if;
2024
 
2025
              configDataReadInternal <= componentTag;
2026
 
2027
            when x"000070" =>
2028
              -----------------------------------------------------------------
2029
              -- Standard Route Configuration Destination ID Select CSR.
2030
              -----------------------------------------------------------------             
2031
 
2032
              if (configWrite = '1') then
2033
                -- Write the address to access the routing table.
2034
                routeTableAddress <= configDataWrite(10 downto 0);
2035
              end if;
2036
 
2037
              configDataReadInternal(31 downto 11) <= (others => '0');
2038
              configDataReadInternal(10 downto 0) <= routeTableAddress;
2039
 
2040
            when x"000074" =>
2041
              -----------------------------------------------------------------
2042
              -- Standard Route Configuration Port Select CSR.
2043
              -----------------------------------------------------------------
2044
 
2045
              if (configWrite = '1') then
2046
                -- Write the port information for the address selected by the
2047
                -- above register.
2048
                routeTableWrite <= '1';
2049
                routeTablePortWrite <= configDataWrite(7 downto 0);
2050
              end if;
2051
 
2052
              configDataReadInternal(31 downto 8) <= (others => '0');
2053
              configDataReadInternal(7 downto 0) <= routeTablePortRead;
2054
 
2055
            when x"000078" =>
2056
              -----------------------------------------------------------------
2057
              -- Standard Route Default Port CSR.
2058
              -----------------------------------------------------------------
2059
 
2060
              if (configWrite = '1') then
2061
                -- Write the default route device id.
2062
                routeTablePortDefault <= configDataWrite(7 downto 0);
2063
              end if;
2064
 
2065
              configDataReadInternal(31 downto 8) <= (others => '0');
2066
              configDataReadInternal(7 downto 0) <= routeTablePortDefault;
2067
 
2068
            when x"000100" =>
2069
              -----------------------------------------------------------------
2070
              -- Extended features. LP-Serial Register Block Header.
2071
              -----------------------------------------------------------------
2072
 
2073
              -- One feature only, 0x0003=Generic End Point Free Device.
2074
              configDataReadInternal(31 downto 16) <= x"0000";
2075
              configDataReadInternal(15 downto 0) <= x"0003";
2076
 
2077
            when x"000120" =>
2078
              -----------------------------------------------------------------
2079
              -- Port Link Timeout Control CSR.
2080
              -----------------------------------------------------------------
2081
 
2082
              if (configWrite = '1') then
2083
                portLinkTimeout <= configDataWrite(31 downto 8);
2084
              end if;
2085
 
2086
              configDataReadInternal(31 downto 8) <= portLinkTimeout;
2087
              configDataReadInternal(7 downto 0) <= x"00";
2088
 
2089
            when x"00013c" =>
2090
              -----------------------------------------------------------------
2091
              -- Port General Control CSR.
2092
              -----------------------------------------------------------------
2093
 
2094
              if (configWrite = '1') then
2095
                discovered <= configDataWrite(29);
2096
              end if;
2097
 
2098
              configDataReadInternal(31 downto 30) <= "00";
2099
              configDataReadInternal(29) <= discovered;
2100
              configDataReadInternal(28 downto 0) <= (others => '0');
2101
 
2102
            when others =>
2103
              -----------------------------------------------------------------
2104
              -- Other port specific registers.
2105
              -----------------------------------------------------------------
2106
 
2107
              -- Make sure the output is always set to something.
2108
              configDataReadInternal <= (others=>'0');
2109
 
2110
              -- Iterate through all active ports.
2111
              for portIndex in 0 to SWITCH_PORTS-1 loop
2112
 
2113
                if(unsigned(configAddress) = (x"000148" + (x"000020"*portIndex))) then
2114
                  -----------------------------------------------------------------
2115
                  -- Port N Local ackID CSR.
2116
                  -----------------------------------------------------------------
2117
                  if (configWrite = '1') then
2118
                    localAckIdWrite_o(portIndex) <= '1';
2119
                    clrOutstandingAckId_o(portIndex) <= configDataWrite(31);
2120
                    inboundAckId_o(portIndex) <= configDataWrite(28 downto 24);
2121
                    outstandingAckId_o(portIndex) <= configDataWrite(12 downto 8);
2122
                    outboundAckId_o(portIndex) <= configDataWrite(4 downto 0);
2123
                  end if;
2124
                  configDataReadInternal(31 downto 29) <= (others => '0');
2125
                  configDataReadInternal(28 downto 24) <= inboundAckId_i(portIndex);
2126
                  configDataReadInternal(23 downto 13) <= (others => '0');
2127
                  configDataReadInternal(12 downto 8) <= outstandingAckId_i(portIndex);
2128
                  configDataReadInternal(7 downto 5) <= (others => '0');
2129
                  configDataReadInternal(4 downto 0) <= outboundAckId_i(portIndex);
2130
 
2131
                elsif(unsigned(configAddress) = (x"000154" + (x"000020"*portIndex))) then
2132
                  -----------------------------------------------------------------
2133
                  -- Port N Control 2 CSR.
2134
                  -----------------------------------------------------------------
2135
                  configDataReadInternal <= (others => '0');
2136
 
2137
                elsif(unsigned(configAddress) = (x"000158" + (x"000020"*portIndex))) then
2138
                  -----------------------------------------------------------------
2139
                  -- Port N Error and Status CSR.
2140
                  -----------------------------------------------------------------
2141
                  -- Idle Sequence 2 Support.
2142
                  configDataReadInternal(31) <= '0';
2143
 
2144
                  -- Idle Sequence 2 Enable.
2145
                  configDataReadInternal(30) <= '0';
2146
 
2147
                  -- Idle Sequence.
2148
                  configDataReadInternal(29) <= '0';
2149
 
2150
                  -- Reserved.
2151
                  configDataReadInternal(28) <= '0';
2152
 
2153
                  -- Flow Control Mode.
2154
                  configDataReadInternal(27) <= '0';
2155
 
2156
                  -- Reserved.
2157
                  configDataReadInternal(26 downto 21) <= (others => '0');
2158
 
2159
                  -- Output retry-encountered.
2160
                  configDataReadInternal(20) <= '0';
2161
 
2162
                  -- Output retried.
2163
                  configDataReadInternal(19) <= '0';
2164
 
2165
                  -- Output retried-stopped.
2166
                  configDataReadInternal(18) <= '0';
2167
 
2168
                  -- Output error-encountered.
2169
                  configDataReadInternal(17) <= '0';
2170
 
2171
                  -- Output error-stopped.
2172
                  configDataReadInternal(16) <= '0';
2173
 
2174
                  -- Reserved.
2175
                  configDataReadInternal(15 downto 11) <= (others => '0');
2176
 
2177
                  -- Input retry-stopped.
2178
                  configDataReadInternal(10) <= '0';
2179
 
2180
                  -- Input error-encountered.
2181
                  configDataReadInternal(9) <= '0';
2182
 
2183
                  -- Input error-stopped.
2184
                  configDataReadInternal(8) <= '0';
2185
 
2186
                  -- Reserved.
2187
                  configDataReadInternal(7 downto 5) <= (others => '0');
2188
 
2189
                  -- Port-write pending.
2190
                  configDataReadInternal(4) <= '0';
2191
 
2192
                  -- Port unavailable.
2193
                  configDataReadInternal(3) <= '0';
2194
 
2195
                  -- Port error.
2196
                  configDataReadInternal(2) <= '0';
2197
 
2198
                  -- Port OK.
2199
                  configDataReadInternal(1) <= linkInitialized_i(portIndex);
2200
 
2201
                  -- Port uninitialized.
2202
                  configDataReadInternal(0) <= not linkInitialized_i(portIndex);
2203
 
2204
                elsif(unsigned(configAddress) = (x"00015c" + (x"000020"*portIndex))) then
2205
                  -----------------------------------------------------------------
2206
                  -- Port N Control CSR.
2207
                  -----------------------------------------------------------------
2208
 
2209
                  -- Port Width Support.
2210
                  configDataReadInternal(31 downto 30) <= (others=>'0');
2211
 
2212
                  -- Initialized Port Width.
2213
                  configDataReadInternal(29 downto 27) <= (others=>'0');
2214
 
2215
                  -- Port Width Override.
2216
                  configDataReadInternal(26 downto 24) <= (others=>'0');
2217
 
2218
                  -- Port disable.
2219
                  configDataReadInternal(23) <= '0';
2220
 
2221
                  -- Output Port Enable.
2222
                  if (configWrite = '1') then
2223
                    outputPortEnable(portIndex) <= configDataWrite(22);
2224
                  end if;
2225
                  configDataReadInternal(22) <= outputPortEnable(portIndex);
2226
 
2227
                  -- Input Port Enable.
2228
                  if (configWrite = '1') then
2229
                    inputPortEnable(portIndex) <= configDataWrite(21);
2230
                  end if;
2231
                  configDataReadInternal(21) <= inputPortEnable(portIndex);
2232
 
2233
                  -- Error Checking Disabled.
2234
                  configDataReadInternal(20) <= '0';
2235
 
2236
                  -- Multicast-event Participant.
2237
                  configDataReadInternal(19) <= '0';
2238
 
2239
                  -- Reserved.
2240
                  configDataReadInternal(18) <= '0';
2241
 
2242
                  -- Enumeration Boundry.
2243
                  configDataReadInternal(17) <= '0';
2244
 
2245
                  -- Reserved.
2246
                  configDataReadInternal(16) <= '0';
2247
 
2248
                  -- Extended Port Width Override.
2249
                  configDataReadInternal(15 downto 14) <= (others=>'0');
2250
 
2251
                  -- Extended Port Width Support.
2252
                  configDataReadInternal(13 downto 12) <= (others=>'0');
2253
 
2254
                  -- Implementation defined.
2255
                  configDataReadInternal(11 downto 4) <= (others=>'0');
2256
 
2257
                  -- Reserved.
2258
                  configDataReadInternal(3 downto 1) <= (others=>'0');
2259
 
2260
                  -- Port Type.
2261
                  configDataReadInternal(0) <= '1';
2262
                end if;
2263
              end loop;
2264
 
2265
          end case;
2266
        end if;
2267
      else
2268
        -- Config memory not enabled.
2269
      end if;
2270
    end if;
2271
  end process;
2272
 
2273
end architecture;
2274
 
2275
 
2276
-------------------------------------------------------------------------------
2277
-- 
2278
-------------------------------------------------------------------------------
2279
 
2280
library ieee;
2281
use ieee.std_logic_1164.all;
2282
use ieee.numeric_std.all;
2283
use work.rio_common.all;
2284
 
2285
 
2286
-------------------------------------------------------------------------------
2287
-- 
2288
-------------------------------------------------------------------------------
2289
entity RouteTableInterconnect is
2290
  generic(
2291
    WIDTH : natural range 1 to 256 := 8);
2292
  port(
2293
    clk : in std_logic;
2294
    areset_n : in std_logic;
2295
 
2296
    stb_i : in Array1(WIDTH-1 downto 0);
2297
    addr_i : in Array16(WIDTH-1 downto 0);
2298
    dataM_o : out Array8(WIDTH-1 downto 0);
2299
    ack_o : out Array1(WIDTH-1 downto 0);
2300
 
2301
    stb_o : out std_logic;
2302
    addr_o : out std_logic_vector(15 downto 0);
2303
    dataS_i : in std_logic_vector(7 downto 0);
2304
    ack_i : in std_logic);
2305
end entity;
2306
 
2307
 
2308
-------------------------------------------------------------------------------
2309
-- 
2310
-------------------------------------------------------------------------------
2311
architecture RouteTableInterconnectImpl of RouteTableInterconnect is
2312
  signal activeCycle : std_logic;
2313
  signal selectedMaster : natural range 0 to WIDTH-1;
2314
begin
2315
 
2316
  -----------------------------------------------------------------------------
2317
  -- Arbitration.
2318
  -----------------------------------------------------------------------------
2319
  Arbiter: process(areset_n, clk)
2320
  begin
2321
    if (areset_n = '0') then
2322
      activeCycle <= '0';
2323
      selectedMaster <= 0;
2324
    elsif (clk'event and clk = '1') then
2325
      if (activeCycle = '0') then
2326
        for i in 0 to WIDTH-1 loop
2327
          if (stb_i(i) = '1') then
2328
            activeCycle <= '1';
2329
            selectedMaster <= i;
2330
          end if;
2331
        end loop;
2332
      else
2333
        if (stb_i(selectedMaster) = '0') then
2334
          activeCycle <= '0';
2335
        end if;
2336
      end if;
2337
    end if;
2338
  end process;
2339
 
2340
  -----------------------------------------------------------------------------
2341
  -- Interconnection.
2342
  -----------------------------------------------------------------------------
2343
  stb_o <= stb_i(selectedMaster);
2344
  addr_o <= addr_i(selectedMaster);
2345
 
2346
  Interconnect: for i in 0 to WIDTH-1 generate
2347
    dataM_o(i) <= dataS_i;
2348
    ack_o(i) <= ack_i when (selectedMaster = i) else '0';
2349
  end generate;
2350
 
2351
end architecture;
2352
 
2353
 
2354
-------------------------------------------------------------------------------
2355
-- 
2356
-------------------------------------------------------------------------------
2357
 
2358
library ieee;
2359
use ieee.std_logic_1164.all;
2360
use ieee.numeric_std.all;
2361
use work.rio_common.all;
2362
 
2363
 
2364
-------------------------------------------------------------------------------
2365
-- 
2366
-------------------------------------------------------------------------------
2367
entity SwitchPortInterconnect is
2368
  generic(
2369
    WIDTH : natural range 1 to 256 := 8);
2370
  port(
2371
    clk : in std_logic;
2372
    areset_n : in std_logic;
2373
 
2374
    masterCyc_i : in Array1(WIDTH-1 downto 0);
2375
    masterStb_i : in Array1(WIDTH-1 downto 0);
2376
    masterWe_i : in Array1(WIDTH-1 downto 0);
2377
    masterAddr_i : in Array10(WIDTH-1 downto 0);
2378
    masterData_i : in Array32(WIDTH-1 downto 0);
2379
    masterData_o : out Array1(WIDTH-1 downto 0);
2380
    masterAck_o : out Array1(WIDTH-1 downto 0);
2381
 
2382
    slaveCyc_o : out Array1(WIDTH-1 downto 0);
2383
    slaveStb_o : out Array1(WIDTH-1 downto 0);
2384
    slaveWe_o : out Array1(WIDTH-1 downto 0);
2385
    slaveAddr_o : out Array10(WIDTH-1 downto 0);
2386
    slaveData_o : out Array32(WIDTH-1 downto 0);
2387
    slaveData_i : in Array1(WIDTH-1 downto 0);
2388
    slaveAck_i : in Array1(WIDTH-1 downto 0));
2389
end entity;
2390
 
2391
 
2392
-------------------------------------------------------------------------------
2393
-- 
2394
-------------------------------------------------------------------------------
2395
architecture SwitchPortInterconnectImpl of SwitchPortInterconnect is
2396
  --component ChipscopeIcon1 is
2397
  --  port (
2398
  --    CONTROL0 : inout STD_LOGIC_VECTOR ( 35 downto 0 )
2399
  --    );
2400
  --end component;
2401
  --component ChipscopeIlaWb is
2402
  --  port (
2403
  --    CLK : in STD_LOGIC := 'X';
2404
  --    TRIG0 : in STD_LOGIC_VECTOR ( 46 downto 0);
2405
  --    CONTROL : inout STD_LOGIC_VECTOR ( 35 downto 0 ) 
2406
  --    );
2407
  --end component;
2408
  --signal control : std_logic_vector(35 downto 0);
2409
  --signal trig : std_logic_vector(46 downto 0);
2410
 
2411
  signal activeCycle : std_logic;
2412
  signal selectedMaster : natural range 0 to WIDTH-1;
2413
  signal selectedSlave : natural range 0 to WIDTH-1;
2414
 
2415
begin
2416
 
2417
  -----------------------------------------------------------------------------
2418
  -- Arbitration process.
2419
  -----------------------------------------------------------------------------
2420
 
2421
  RoundRobinArbiter: process(areset_n, clk)
2422
    variable index : natural range 0 to WIDTH-1;
2423
  begin
2424
    if (areset_n = '0') then
2425
      activeCycle <= '0';
2426
      selectedMaster <= 0;
2427
    elsif (clk'event and clk = '1') then
2428
      -- Check if a cycle is ongoing.
2429
      if (activeCycle = '0') then
2430
        -- No ongoing cycles.
2431
 
2432
        -- Iterate through all ports and check if any new cycle has started.
2433
        for i in 0 to WIDTH-1 loop
2434
          if ((selectedMaster+i) >= WIDTH) then
2435
            index := (selectedMaster+i) - WIDTH;
2436
          else
2437
            index := (selectedMaster+i);
2438
          end if;
2439
 
2440
          if (masterCyc_i(index) = '1') then
2441
            activeCycle <= '1';
2442
            selectedMaster <= index;
2443
          end if;
2444
        end loop;
2445
      else
2446
        -- Ongoing cycle.
2447
 
2448
        -- Check if the cycle has ended.
2449
        if (masterCyc_i(selectedMaster) = '0') then
2450
          -- Cycle has ended.
2451
          activeCycle <= '0';
2452
 
2453
          -- Check if a new cycle has started from another master.
2454
          -- Start to check from the one that ended its cycle, this way, the
2455
          -- ports will be scheduled like round-robin.
2456
          for i in 0 to WIDTH-1 loop
2457
            if ((selectedMaster+i) >= WIDTH) then
2458
              index := (selectedMaster+i) - WIDTH;
2459
            else
2460
              index := (selectedMaster+i);
2461
            end if;
2462
 
2463
            if (masterCyc_i(index) = '1') then
2464
              activeCycle <= '1';
2465
              selectedMaster <= index;
2466
            end if;
2467
          end loop;
2468
        end if;
2469
      end if;
2470
    end if;
2471
  end process;
2472
 
2473
  -----------------------------------------------------------------------------
2474
  -- Address decoding.
2475
  -----------------------------------------------------------------------------
2476
 
2477
  -- Select the last port when the top bit is set.
2478
  -- The last port must be the maintenance slave port.
2479
  selectedSlave <= WIDTH-1 when masterAddr_i(selectedMaster)(9) = '1' else
2480
                   to_integer(unsigned(masterAddr_i(selectedMaster)(8 downto 1)));
2481
 
2482
  -----------------------------------------------------------------------------
2483
  -- Interconnection matrix.
2484
  -----------------------------------------------------------------------------
2485
  Interconnect: for i in 0 to WIDTH-1 generate
2486
    slaveCyc_o(i) <= masterCyc_i(selectedMaster) when (selectedSlave = i) else '0';
2487
    slaveStb_o(i) <= masterStb_i(selectedMaster) when (selectedSlave = i) else '0';
2488
    slaveWe_o(i) <= masterWe_i(selectedMaster);
2489
    slaveAddr_o(i) <= masterAddr_i(selectedMaster);
2490
    slaveData_o(i) <= masterData_i(selectedMaster);
2491
    masterData_o(i) <= slaveData_i(selectedSlave);
2492
    masterAck_o(i) <= slaveAck_i(selectedSlave) when (selectedMaster = i) else '0';
2493
  end generate;
2494
 
2495
  -----------------------------------------------------------------------------
2496
  -- Chipscope debugging probe.
2497
  -----------------------------------------------------------------------------
2498
  --trig <= masterCyc_i(selectedMaster) & masterStb_i(selectedMaster) &
2499
  --        masterWe_i(selectedMaster) &  masterAddr_i(selectedMaster) &
2500
  --        masterData_i(selectedMaster) & slaveData_i(selectedSlave) &
2501
  --        slaveAck_i(selectedSlave);
2502
  --ChipscopeIconInst: ChipscopeIcon1
2503
  --  port map(CONTROL0=>control);
2504
  --ChipscopeIlaInst: ChipscopeIlaWb
2505
  --  port map(CLK=>clk, TRIG0=>trig, CONTROL=>control);
2506
 
2507
end architecture;
2508
 
2509
 
2510
 

powered by: WebSVN 2.1.0

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