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

Subversion Repositories rio

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

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

powered by: WebSVN 2.1.0

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