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

Subversion Repositories rio

[/] [rio/] [branches/] [parallelSymbols/] [rtl/] [vhdl/] [RioSerial.vhd] - Blame information for rev 11

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

Line No. Rev Author Line
1 4 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 the transmission channel independent parts of the LP-Serial
10
-- Physical Layer Specification (RapidIO 2.2, part 6).
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
-- RioSerial
48 8 magro732
--
49 11 magro732
-- Generics
50
-- --------
51
-- TIMEOUT_WIDTH - The number of bits to be used in the portLinkTimeout signal.
52
-- NUMBER_WORDS - The number of parallell words that the data symbols can
53
-- contain. This sizes the data buses. It can be used to increase the bandwidth
54
-- of the core. Note that it cannot be larger than 4. This is since two
55
-- packets may be completed at the same tick and the interface to the
56
-- packetBuffer cannot handle more than one packets in one tick.
57
--
58
-- Signals
59
-- -------
60
-- System signals.
61 8 magro732
-- clk - System clock.
62
-- areset_n - System reset. Asynchronous, active low. 
63
--
64 11 magro732
-- Configuration signals. These are used to change the runtime behaviour.
65 8 magro732
-- portLinkTimeout_i - The number of ticks to wait for a packet-accepted before
66
--   a timeout occurrs.
67
-- linkInitialized_o - Indicates if a link partner is answering with valid
68
--   status-control-symbols. 
69
-- inputPortEnable_i - Activate the input port for non-maintenance packets. If
70
--   deasserted, only non-maintenance packets are allowed.
71
-- outputPortEnable_i - Activate the output port for non-maintenance packets.
72
--   If deasserted, only non-maintenance packets are allowed.
73
--
74
-- This interface makes it possible to read and write ackId in both outbound
75
-- and inbound directions. All input signals are validated by localAckIdWrite.
76
-- localAckIdWrite_i - Indicate if a localAckId write operation is ongoing.
77
--   Usually this signal is high one tick. 
78
-- clrOutstandingAckId_i - Clear outstanding ackId, i.e. reset the transmission
79
--   window. The signal is only read if localAckIdWrite_i is high.
80
-- inboundAckId_i - The value to set the inbound ackId (the ackId that the
81
--  next inbound packet should have) to. This signal is only read if localAckIdWrite
82
--  is high.
83
-- outstandingAckId_i - The value to set the outstanding ackId (the ackId
84
--   transmitted but not acknowledged) to. This signal is only read if localAckIdWrite
85
--   is high.
86
-- outboundAckId_i - The value to set the outbound ackId (the ackId that the
87
--   next outbound packet will have) to. This signal is only read if localAckIdWrite
88
--   is high.
89
-- inboundAckId_o - The current inbound ackId.
90
-- outstandingAckId_o - The current outstanding ackId.
91
-- outboundAckId_o - The current outbound ackId.
92
--
93
-- This is the interface to the packet buffering sublayer. 
94
-- The window signals are used to send packets without removing them from the
95
-- memory storage. This way, many packet can be sent without awaiting
96
-- packet-accepted symbols and if a packet-accepted gets lost, it is possible
97
-- to revert and resend a packet. This is achived by reading readWindowEmpty
98
-- for new packet and asserting readWindowNext when a packet has been sent.
99
-- When the packet-accepted is received, readFrame should be asserted to remove the
100
-- packet from the storage. If a packet-accepted is missing, readWindowReset is
101
-- asserted to set the current packet to read to the one that has not received
102
-- a packet-accepted.
103
-- readFrameEmpty_i - Indicate if a packet is ready in the outbound direction.
104
--   Once deasserted, it is possible to read the packet content using
105
--   readContent_o to update readContentData and readContentEnd.
106
-- readFrame_o - Assert this signal for one tick to discard the oldest packet.
107
--   It should be used when a packet has been fully read, a linkpartner has
108
--   accepted it and the resources occupied by it should be returned to be
109
--   used for new packets.
110
-- readFrameRestart_o - Assert this signal to restart the reading of the
111
--   current packet. readContentData and readContentEnd will be reset to the
112
--   first content of the packet. 
113
-- readFrameAborted_i - This signal is asserted if the current packet was
114
--   aborted while it was written. It is used when a transmitter starts to send a
115
--   packet before it has been fully received and it is cancelled before it is
116
--   completed. A one tick asserted readFrameRestart signal resets this signal.
117
-- readWindowEmpty_i - Indicate if there are more packets to send.
118
-- readWindowReset_o - Reset the current packet to the oldest stored in the memory.
119
-- readWindowNext_o - Indicate that a new packet should be read. Must only be
120
--   asserted if readWindowEmpty is deasserted. It should be high for one tick.
121
-- readContentEmpty_i - Indicate if there are any packet content to be read.
122
--   This signal is updated directly when packet content is written making it
123
--   possible to read packet content before the full packet has been written to
124
--   the memory storage.
125
-- readContent_o - Update readContentData and readContentEnd.
126
-- readContentEnd_i - Indicate if the end of the current packet has been
127
--   reached. When asserted, readContentData is not valid.
128
-- readContentData_i - The content of the current packet.
129
-- writeFrameFull_i - Indicate if the inbound packet storage is ready to accept
130
--   a new packet.
131
-- writeFrame_o - Indicate that a new complete inbound packet has been written.
132
-- writeFrameAbort_o - Indicate that the current packet is aborted and that all
133
--   data written for this packet should be discarded. 
134
-- writeContent_o - Indicate that writeContentData is valid and should be
135
--   written into the packet content storage. 
136
-- writeContentData_o - The content to write to the packet content storage.
137
--
138
-- This is the interface to the PCS (Physical Control Sublayer). Four types of
139
-- symbols exist, idle, control, data and error.
140
-- Idle symbols are transmitted when nothing else can be transmitted. They are
141
-- mainly intended to enforce a timing on the transmitted symbols. This is
142
-- needed to be able to guarantee that a status-control-symbol is transmitted
143
-- at least once every 256 symbol.
144
-- Control symbols contain control-symbols as described by the standard.
145
-- Data symbols contains a 32-bit fragment of a RapidIO packet.
146
-- Error symbols indicate that a corrupted symbol was received. This could be
147
-- used by a PCS layer to indicate that a transmission error was detected and
148
-- that the above layers should send link-requests to ensure the synchronism
149
-- between the link-partners.
150
-- The signals in this interface are:
151
-- portInitialized_i - An asserted signal on this pin indicates that the PCS
152
--   layer has established synchronization with the link and is ready to accept
153
--   symbols. 
154
-- outboundSymbolEmpty_o - An asserted signal indicates that there are no
155
--   outbound symbols to read. Once deasserted, outboundSymbol_o will be
156
--   already be valid. This signal will be updated one tick after
157
--   outboundSymbolRead_i has been asserted.
158
-- outboundSymbolRead_i - Indicate that outboundSymbol_o has been read and a
159
--   new value could be accepted. It should be active for one tick. 
160 11 magro732
-- REMARK: Update this comment...
161
-- outboundSymbol_o - The outbound symbol. It is divided into two parts,
162
--   symbolType and symbolContent.
163
--   symbolType - The two MSB bits are the type of the symbol according to
164
--   table below:
165
--     00=IDLE, the rest of the bits are not used.
166
--     01=CONTROL, the control symbols payload (24 bits) are placed in the MSB
167
--       part of the symbolContent.
168
--     10=ERROR, the rest of the bits are not used.
169
--     11=DATA, all the remaining bits contain the number of valid words and
170
--     the payload of the symbol.
171
--   symbolContent - The rest of the bits are symbol content. If there are
172
--     multiple words in the symbols they must be set to zero. The first
173
--     received word is placed in the MSB part of this field.
174 8 magro732
-- inboundSymbolFull_o - An asserted signal indicates that no more inbound
175
--   symbols can be accepted.
176
-- inboundSymbolWrite_i - Indicate that inboundSymbol_i contains valid
177 11 magro732
--   information that should be forwarded. Should be active for one tick.
178 8 magro732
-- inboundSymbol_i - The inbound symbol. See outboundSymbol_o for formating.
179 4 magro732
-------------------------------------------------------------------------------
180
library ieee;
181
use ieee.std_logic_1164.all;
182
use ieee.numeric_std.all;
183
use work.rio_common.all;
184
 
185
 
186
-------------------------------------------------------------------------------
187
-- Entity for RioSerial.
188
-------------------------------------------------------------------------------
189
entity RioSerial is
190
  generic(
191 11 magro732
    TIMEOUT_WIDTH : natural;
192
    NUMBER_WORDS : natural range 1 to 4 := 1);
193 4 magro732
  port(
194
    -- System signals.
195
    clk : in std_logic;
196
    areset_n : in std_logic;
197
 
198
    -- Status signals for maintenance operations.
199
    portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
200
    linkInitialized_o : out std_logic;
201
    inputPortEnable_i : in std_logic;
202
    outputPortEnable_i : in std_logic;
203
 
204
    -- Support for portLocalAckIdCSR.
205
    localAckIdWrite_i : in std_logic;
206
    clrOutstandingAckId_i : in std_logic;
207
    inboundAckId_i : in std_logic_vector(4 downto 0);
208
    outstandingAckId_i : in std_logic_vector(4 downto 0);
209
    outboundAckId_i : in std_logic_vector(4 downto 0);
210
    inboundAckId_o : out std_logic_vector(4 downto 0);
211
    outstandingAckId_o : out std_logic_vector(4 downto 0);
212
    outboundAckId_o : out std_logic_vector(4 downto 0);
213
 
214
    -- Outbound frame interface.
215
    readFrameEmpty_i : in std_logic;
216
    readFrame_o : out std_logic;
217
    readFrameRestart_o : out std_logic;
218
    readFrameAborted_i : in std_logic;
219
    readWindowEmpty_i : in std_logic;
220
    readWindowReset_o : out std_logic;
221
    readWindowNext_o : out std_logic;
222
    readContentEmpty_i : in std_logic;
223
    readContent_o : out std_logic;
224
    readContentEnd_i : in std_logic;
225 11 magro732
    readContentData_i : in std_logic_vector(2+(32*NUMBER_WORDS-1) downto 0);
226 4 magro732
 
227
    -- Inbound frame interface.
228
    writeFrameFull_i : in std_logic;
229
    writeFrame_o : out std_logic;
230
    writeFrameAbort_o : out std_logic;
231
    writeContent_o : out std_logic;
232 11 magro732
    writeContentData_o : out std_logic_vector(2+(32*NUMBER_WORDS-1) downto 0);
233 4 magro732
 
234
    -- PCS layer signals.
235
    portInitialized_i : in std_logic;
236
    outboundSymbolEmpty_o : out std_logic;
237
    outboundSymbolRead_i : in std_logic;
238 11 magro732
    outboundSymbol_o : out std_logic_vector(((2+32)*NUMBER_WORDS-1) downto 0);
239 4 magro732
    inboundSymbolFull_o : out std_logic;
240
    inboundSymbolWrite_i : in std_logic;
241 11 magro732
    inboundSymbol_i : in std_logic_vector(((2+32)*NUMBER_WORDS-1) downto 0));
242 4 magro732
end entity;
243
 
244
 
245
-------------------------------------------------------------------------------
246
-- Architecture for RioSerial.
247
-------------------------------------------------------------------------------
248
architecture RioSerialImpl of RioSerial is
249
 
250
  component RioFifo1 is
251
    generic(
252
      WIDTH : natural);
253
    port(
254
      clk : in std_logic;
255
      areset_n : in std_logic;
256
 
257
      empty_o : out std_logic;
258
      read_i : in std_logic;
259
      data_o : out std_logic_vector(WIDTH-1 downto 0);
260
 
261
      full_o : out std_logic;
262
      write_i : in std_logic;
263
      data_i : in std_logic_vector(WIDTH-1 downto 0));
264
  end component;
265
 
266
  component RioTransmitter is
267
    generic(
268 11 magro732
      TIMEOUT_WIDTH : natural;
269
      NUMBER_WORDS : natural range 1 to 4 := 1);
270 4 magro732
    port(
271
      clk : in std_logic;
272
      areset_n : in std_logic;
273
 
274
      portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
275
      portEnable_i : in std_logic;
276
 
277
      localAckIdWrite_i : in std_logic;
278
      clrOutstandingAckId_i : in std_logic;
279
      outstandingAckId_i : in std_logic_vector(4 downto 0);
280
      outboundAckId_i : in std_logic_vector(4 downto 0);
281
      outstandingAckId_o : out std_logic_vector(4 downto 0);
282
      outboundAckId_o : out std_logic_vector(4 downto 0);
283
 
284
      portInitialized_i : in std_logic;
285
      txFull_i : in std_logic;
286
      txWrite_o : out std_logic;
287 11 magro732
      txType_o : out std_logic_vector(1 downto 0);
288 4 magro732
      txData_o : out std_logic_vector(31 downto 0);
289
 
290
      txControlEmpty_i : in std_logic;
291
      txControlSymbol_i : in std_logic_vector(12 downto 0);
292
      txControlUpdate_o : out std_logic;
293
      rxControlEmpty_i : in std_logic;
294
      rxControlSymbol_i : in std_logic_vector(12 downto 0);
295
      rxControlUpdate_o : out std_logic;
296
 
297
      linkInitialized_i : in std_logic;
298
      linkInitialized_o : out std_logic;
299
      ackIdStatus_i : in std_logic_vector(4 downto 0);
300
 
301
      readFrameEmpty_i : in std_logic;
302
      readFrame_o : out std_logic;
303
      readFrameRestart_o : out std_logic;
304
      readFrameAborted_i : in std_logic;
305
      readWindowEmpty_i : in std_logic;
306
      readWindowReset_o : out std_logic;
307
      readWindowNext_o : out std_logic;
308
      readContentEmpty_i : in std_logic;
309
      readContent_o : out std_logic;
310
      readContentEnd_i : in std_logic;
311 11 magro732
      readContentWords_i : in std_logic_vector(1 downto 0);
312
      readContentData_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0));
313 4 magro732
  end component;
314
 
315
  component RioReceiver is
316 11 magro732
    generic(
317
      NUMBER_WORDS : natural range 1 to 4 := 1);
318 4 magro732
    port(
319
      clk : in std_logic;
320
      areset_n : in std_logic;
321
 
322
      portEnable_i : in std_logic;
323
 
324
      localAckIdWrite_i : in std_logic;
325
      inboundAckId_i : in std_logic_vector(4 downto 0);
326
      inboundAckId_o : out std_logic_vector(4 downto 0);
327
 
328
      portInitialized_i : in std_logic;
329
      rxEmpty_i : in std_logic;
330
      rxRead_o : out std_logic;
331 11 magro732
      rxType_i : in std_logic_vector(2*NUMBER_WORDS-1 downto 0);
332
      rxData_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0);
333 4 magro732
 
334 11 magro732
      txControlWrite_o : out std_logic_vector(NUMBER_WORDS-1 downto 0);
335
      txControlSymbol_o : out std_logic_vector(12*NUMBER_WORDS downto 0);
336
      rxControlWrite_o : out std_logic_vector(NUMBER_WORDS-1 downto 0);
337
      rxControlSymbol_o : out std_logic_vector(12*NUMBER_WORDS downto 0);
338 4 magro732
 
339
      ackIdStatus_o : out std_logic_vector(4 downto 0);
340
      linkInitialized_o : out std_logic;
341
 
342
      writeFrameFull_i : in std_logic;
343
      writeFrame_o : out std_logic;
344
      writeFrameAbort_o : out std_logic;
345
      writeContent_o : out std_logic;
346 11 magro732
      writeContentWords_o : out std_logic_vector(1 downto 0);
347
      writeContentData_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0));
348 4 magro732
  end component;
349
 
350
  signal linkInitializedRx : std_logic;
351
  signal linkInitializedTx : std_logic;
352
  signal ackIdStatus : std_logic_vector(4 downto 0);
353
 
354 11 magro732
  signal txControlWrite : std_logic_vector(NUMBER_WORDS-1 downto 0);
355
  signal txControlWriteSymbol : std_logic_vector(12*NUMBER_WORDS downto 0);
356
  signal txControlReadEmpty : std_logic_vector(NUMBER_WORDS-1 downto 0);
357
  signal txControlRead : std_logic_vector(NUMBER_WORDS-1 downto 0);
358
  signal txControlReadSymbol : std_logic_vector(12*NUMBER_WORDS downto 0);
359 4 magro732
 
360 11 magro732
  signal rxControlWrite : std_logic_vector(NUMBER_WORDS-1 downto 0);
361
  signal rxControlWriteSymbol : std_logic_vector(12*NUMBER_WORDS downto 0);
362
  signal rxControlReadEmpty : std_logic_vector(NUMBER_WORDS-1 downto 0);
363
  signal rxControlRead : std_logic_vector(NUMBER_WORDS-1 downto 0);
364
  signal rxControlReadSymbol : std_logic_vector(12*NUMBER_WORDS downto 0);
365 4 magro732
 
366
  signal outboundFull : std_logic;
367
  signal outboundWrite : std_logic;
368 11 magro732
  signal outboundType : std_logic_vector(1 downto 0);
369
  signal outboundData : std_logic_vector(32*NUMBER_WORDS-1 downto 0);
370
  signal outboundSymbol : std_logic_vector(2+(32*NUMBER_WORDS-1) downto 0);
371 4 magro732
 
372
  signal inboundEmpty : std_logic;
373
  signal inboundRead : std_logic;
374 11 magro732
  signal inboundType : std_logic_vector(1 downto 0);
375
  signal inboundData : std_logic_vector(32*NUMBER_WORDS-1 downto 0);
376
  signal inboundSymbol : std_logic_vector(((2+32)*NUMBER_WORDS-1) downto 0);
377 4 magro732
 
378
begin
379
 
380
  linkInitialized_o <=
381
    '1' when ((linkInitializedRx = '1') and (linkInitializedTx = '1')) else '0';
382
 
383
  -----------------------------------------------------------------------------
384
  -- Serial layer modules.
385
  -----------------------------------------------------------------------------
386
 
387
  Transmitter: RioTransmitter
388
    generic map(
389 11 magro732
      TIMEOUT_WIDTH=>TIMEOUT_WIDTH,
390
      NUMBER_WORDS=>NUMBER_WORDS)
391 4 magro732
    port map(
392
      clk=>clk, areset_n=>areset_n,
393
      portLinkTimeout_i=>portLinkTimeout_i,
394
      portEnable_i=>outputPortEnable_i,
395
      localAckIdWrite_i=>localAckIdWrite_i,
396
      clrOutstandingAckId_i=>clrOutstandingAckId_i,
397
      outstandingAckId_i=>outstandingAckId_i,
398
      outboundAckId_i=>outboundAckId_i,
399
      outstandingAckId_o=>outstandingAckId_o,
400
      outboundAckId_o=>outboundAckId_o,
401
      portInitialized_i=>portInitialized_i,
402
      txFull_i=>outboundFull, txWrite_o=>outboundWrite,
403 11 magro732
      txType_o=>outboundType, txData_o=>outboundData,
404
      txControlEmpty_i=>txControlReadEmpty(0), txControlSymbol_i=>txControlReadSymbol,
405
      txControlUpdate_o=>txControlRead(0),
406
      rxControlEmpty_i=>rxControlReadEmpty(0), rxControlSymbol_i=>rxControlReadSymbol,
407
      rxControlUpdate_o=>rxControlRead(0),
408 4 magro732
      linkInitialized_o=>linkInitializedTx,
409
      linkInitialized_i=>linkInitializedRx, ackIdStatus_i=>ackIdStatus,
410
      readFrameEmpty_i=>readFrameEmpty_i, readFrame_o=>readFrame_o,
411
      readFrameRestart_o=>readFrameRestart_o, readFrameAborted_i=>readFrameAborted_i,
412
      readWindowEmpty_i=>readWindowEmpty_i,
413
      readWindowReset_o=>readWindowReset_o, readWindowNext_o=>readWindowNext_o,
414
      readContentEmpty_i=>readContentEmpty_i, readContent_o=>readContent_o,
415 11 magro732
      readContentEnd_i=>readContentEnd_i,
416
      readContentWords_i=>readContentData_i(2+(32*NUMBER_WORDS-1) downto 1+(32*NUMBER_WORDS-1)),
417
      readContentData_i=>readContentData_i(32*NUMBER_WORDS-1 downto 0));
418 4 magro732
 
419 11 magro732
  SymbolFifo: for i in 0 to NUMBER_WORDS-1 generate
420
    TxSymbolFifo: RioFifo1
421
      generic map(WIDTH=>13)
422
      port map(
423
        clk=>clk, areset_n=>areset_n,
424
        empty_o=>txControlReadEmpty(i),
425
        read_i=>txControlRead(i),
426
        data_o=>txControlReadSymbol(12*(i+1) downto 12*i),
427
        full_o=>open,
428
        write_i=>txControlWrite(i),
429
        data_i=>txControlWriteSymbol(12*(i+1) downto 12*i));
430 4 magro732
 
431 11 magro732
    RxSymbolFifo: RioFifo1
432
      generic map(WIDTH=>13)
433
      port map(
434
        clk=>clk, areset_n=>areset_n,
435
        empty_o=>rxControlReadEmpty(i),
436
        read_i=>rxControlRead(i),
437
        data_o=>rxControlReadSymbol(12*(i+1) downto 12*i),
438
        full_o=>open,
439
        write_i=>rxControlWrite(i),
440
        data_i=>rxControlWriteSymbol(12*(i+1) downto 12*i));
441
  end generate;
442
 
443 4 magro732
  Receiver: RioReceiver
444 11 magro732
    generic map(NUMBER_WORDS=>NUMBER_WORDS)
445 4 magro732
    port map(
446
      clk=>clk, areset_n=>areset_n,
447
      portEnable_i=>inputPortEnable_i,
448
      localAckIdWrite_i=>localAckIdWrite_i,
449
      inboundAckId_i=>inboundAckId_i,
450
      inboundAckId_o=>inboundAckId_o,
451
      portInitialized_i=>portInitialized_i,
452
      rxEmpty_i=>inboundEmpty, rxRead_o=>inboundRead,
453 11 magro732
      rxType_i=>inboundType, rxData_i=>inboundData,
454 4 magro732
      txControlWrite_o=>txControlWrite, txControlSymbol_o=>txControlWriteSymbol,
455
      rxControlWrite_o=>rxControlWrite, rxControlSymbol_o=>rxControlWriteSymbol,
456
      ackIdStatus_o=>ackIdStatus,
457
      linkInitialized_o=>linkInitializedRx,
458
      writeFrameFull_i=>writeFrameFull_i,
459
      writeFrame_o=>writeFrame_o, writeFrameAbort_o=>writeFrameAbort_o,
460 11 magro732
      writeContent_o=>writeContent_o,
461
      writeContentWords_o=>writeContentData_o(2+(32*NUMBER_WORDS-1) downto 1+(32*NUMBER_WORDS-1)),
462
      writeContentData_o=>writeContentData_o(32*NUMBER_WORDS-1 downto 0));
463 4 magro732
 
464
  -----------------------------------------------------------------------------
465
  -- PCS layer FIFO interface.
466
  -----------------------------------------------------------------------------
467
 
468 11 magro732
  outboundSymbol <= outboundType & outboundData;
469 4 magro732
  OutboundSymbolFifo: RioFifo1
470 11 magro732
    generic map(WIDTH=>2+32*NUMBER_WORDS)
471 4 magro732
    port map(
472
      clk=>clk, areset_n=>areset_n,
473
      empty_o=>outboundSymbolEmpty_o, read_i=>outboundSymbolRead_i, data_o=>outboundSymbol_o,
474
      full_o=>outboundFull, write_i=>outboundWrite, data_i=>outboundSymbol);
475
 
476 11 magro732
  inboundType <= inboundSymbol(2+(32*NUMBER_WORDS-1) downto 1+(32*NUMBER_WORDS-1));
477
  inboundData <= inboundSymbol(32*NUMBER_WORDS-1 downto 0);
478 4 magro732
  InboundSymbolFifo: RioFifo1
479 11 magro732
    generic map(WIDTH=>2+32*NUMBER_WORDS)
480 4 magro732
    port map(
481
      clk=>clk, areset_n=>areset_n,
482
      empty_o=>inboundEmpty, read_i=>inboundRead, data_o=>inboundSymbol,
483
      full_o=>inboundSymbolFull_o, write_i=>inboundSymbolWrite_i, data_i=>inboundSymbol_i);
484
 
485
end architecture;
486
 
487
 
488
 
489
-------------------------------------------------------------------------------
490
-- RioTransmitter
491
-------------------------------------------------------------------------------
492
library ieee;
493
use ieee.std_logic_1164.all;
494
use ieee.numeric_std.all;
495
use work.rio_common.all;
496
 
497
 
498
-------------------------------------------------------------------------------
499
-- Entity for RioTransmitter.
500
-------------------------------------------------------------------------------
501
entity RioTransmitter is
502
  generic(
503 11 magro732
    TIMEOUT_WIDTH : natural;
504
    NUMBER_WORDS : natural range 1 to 4 := 1);
505 4 magro732
  port(
506
    -- System signals.
507
    clk : in std_logic;
508
    areset_n : in std_logic;
509
 
510
    -- Status signals used for maintenance.
511
    portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
512
    portEnable_i : in std_logic;
513
 
514
    -- Support for localAckIdCSR.
515
    localAckIdWrite_i : in std_logic;
516
    clrOutstandingAckId_i : in std_logic;
517
    outstandingAckId_i : in std_logic_vector(4 downto 0);
518
    outboundAckId_i : in std_logic_vector(4 downto 0);
519
    outstandingAckId_o : out std_logic_vector(4 downto 0);
520
    outboundAckId_o : out std_logic_vector(4 downto 0);
521
 
522
    -- Port output interface.
523
    portInitialized_i : in std_logic;
524
    txFull_i : in std_logic;
525
    txWrite_o : out std_logic;
526 11 magro732
    txType_o : out std_logic_vector(2*NUMBER_WORDS-1 downto 0);
527
    txData_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0);
528 4 magro732
 
529
    -- Control symbols aimed to the transmitter.
530
    txControlEmpty_i : in std_logic;
531
    txControlSymbol_i : in std_logic_vector(12 downto 0);
532
    txControlUpdate_o : out std_logic;
533
 
534
    -- Control symbols from the receiver to send.
535
    rxControlEmpty_i : in std_logic;
536
    rxControlSymbol_i : in std_logic_vector(12 downto 0);
537
    rxControlUpdate_o : out std_logic;
538
 
539
    -- Internal signalling from the receiver part.
540
    linkInitialized_o : out std_logic;
541
    linkInitialized_i : in std_logic;
542
    ackIdStatus_i : in std_logic_vector(4 downto 0);
543
 
544
    -- Frame buffer interface.
545
    readFrameEmpty_i : in std_logic;
546
    readFrame_o : out std_logic;
547
    readFrameRestart_o : out std_logic;
548
    readFrameAborted_i : in std_logic;
549
    readWindowEmpty_i : in std_logic;
550
    readWindowReset_o : out std_logic;
551
    readWindowNext_o : out std_logic;
552
    readContentEmpty_i : in std_logic;
553
    readContent_o : out std_logic;
554
    readContentEnd_i : in std_logic;
555 11 magro732
    readContentWords_i : in std_logic_vector(1 downto 0);
556
    readContentData_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0));
557 4 magro732
end entity;
558
 
559
 
560
-------------------------------------------------------------------------------
561
-- Architecture for RioTransmitter.
562
-------------------------------------------------------------------------------
563
architecture RioTransmitterImpl of RioTransmitter is
564
 
565
  constant NUMBER_STATUS_TRANSMIT : natural := 15;
566
  constant NUMBER_LINK_RESPONSE_RETRIES : natural := 2;
567 11 magro732
 
568
  component RioTransmitterCore is
569
    generic(
570
      TIMEOUT_WIDTH : natural;
571
      NUMBER_WORDS : natural range 1 to 4 := 1);
572
    port(
573
      -- System signals.
574
      clk : in std_logic;
575
      areset_n : in std_logic;
576
 
577
      -- Status signals used for maintenance.
578
      portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
579
      portEnable_i : in std_logic;
580
 
581
      -- Port output interface.
582
      portInitialized_i : in std_logic;
583
      txFull_i : in std_logic;
584
      txWrite_o : out std_logic;
585
      txType_o : out std_logic_vector(2*NUMBER_WORDS-1 downto 0);
586
      txData_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0);
587
 
588
      -- Control symbols aimed to the transmitter.
589
      txControlEmpty_i : in std_logic;
590
      txControlSymbol_i : in std_logic_vector(13*NUMBER_WORDS-1 downto 0);
591
      txControlUpdate_o : out std_logic;
592
 
593
      -- Control symbols from the receiver to send.
594
      rxControlEmpty_i : in std_logic;
595
      rxControlSymbol_i : in std_logic_vector(13*NUMBER_WORDS-1 downto 0);
596
      rxControlUpdate_o : out std_logic;
597
 
598
      -- Internal signalling from the receiver part.
599
      linkInitialized_o : out std_logic;
600
      linkInitialized_i : in std_logic;
601
      ackIdStatus_i : in std_logic_vector(4 downto 0);
602
 
603
      -- The current time used for timeout calculations.
604
      timeCurrent_i : in std_logic_vector(TIMEOUT_WIDTH downto 0);
605
 
606
      -- Internal core variables for cascading.
607
      timeSentWrite_o : out std_logic;
608
      timeSentWriteAddress_o : out std_logic_vector(4 downto 0);
609
      timeSentWriteData_o : out std_logic_vector(TIMEOUT_WIDTH downto 0);
610
      timeSentReadAddress_o : out std_logic_vector(4 downto 0);
611
      timeSentReadData_i : in std_logic_vector(TIMEOUT_WIDTH downto 0);
612
      operational_i : in std_logic;
613
      operational_o : out std_logic;
614
      ackId_i : in std_logic_vector(4 downto 0);
615
      ackId_o : out std_logic_vector(4 downto 0);
616
      bufferStatus_i : in std_logic_vector(4 downto 0);
617
      bufferStatus_o : out std_logic_vector(4 downto 0);
618
      statusReceived_i : in std_logic;
619
      statusReceived_o : out std_logic;
620
      numberSentLinkRequests_i : in std_logic_vector(1 downto 0);
621
      numberSentLinkRequests_o : out std_logic_vector(1 downto 0);
622
      outputErrorStopped_i : in std_logic;
623
      outputErrorStopped_o : out std_logic;
624
      recoverActive_i : in std_logic;
625
      recoverActive_o : out std_logic;
626
      recoverCounter_i : in std_logic_vector(4 downto 0);
627
      recoverCounter_o : out std_logic_vector(4 downto 0);
628
      ackIdWindow_i : in std_logic_vector(4 downto 0);
629
      ackIdWindow_o : out std_logic_vector(4 downto 0);
630
      frameState_i : in std_logic_vector(4 downto 0);
631
      frameState_o : out std_logic_vector(4 downto 0);
632
      frameWordCounter_i : in std_logic_vector(1 downto 0);
633
      frameWordCounter_o : out std_logic_vector(1 downto 0);
634
      frameContent_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0);
635
      frameContent_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0);
636
      counter_i : in std_logic_vector(3 downto 0);
637
      counter_o : out std_logic_vector(3 downto 0);
638
      symbolsTransmitted_i : in std_logic_vector(7 downto 0);
639
      symbolsTransmitted_o : out std_logic_vector(7 downto 0);
640
 
641
      -- Frame buffer interface.
642
      readFrameEmpty_i : in std_logic;
643
      readFrame_o : out std_logic;
644
      readFrameRestart_o : out std_logic;
645
      readFrameAborted_i : in std_logic;
646
      readWindowEmpty_i : in std_logic;
647
      readWindowReset_o : out std_logic;
648
      readWindowNext_o : out std_logic;
649
      readContentEmpty_i : in std_logic;
650
      readContent_o : out std_logic;
651
      readContentEnd_i : in std_logic;
652
      readContentWords_i : in std_logic_vector(1 downto 0);
653
      readContentData_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0));
654
  end component;
655 4 magro732
 
656
  component MemorySimpleDualPortAsync is
657
    generic(
658
      ADDRESS_WIDTH : natural := 1;
659
      DATA_WIDTH : natural := 1;
660
      INIT_VALUE : std_logic := 'U');
661
    port(
662
      clkA_i : in std_logic;
663
      enableA_i : in std_logic;
664
      addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
665
      dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
666
 
667
      addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
668
      dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
669
  end component;
670
 
671 11 magro732
  signal timeCurrent : std_logic_vector(TIMEOUT_WIDTH downto 0);
672
  signal timeSentWrite : std_logic;
673
  signal timeSentWriteAddress : std_logic_vector(4 downto 0);
674
  signal timeSentWriteData  : std_logic_vector(TIMEOUT_WIDTH downto 0);
675
  signal timeSentReadAddress : std_logic_vector(4 downto 0);
676
  signal timeSentReadData : std_logic_vector(TIMEOUT_WIDTH downto 0);
677 4 magro732
 
678 11 magro732
  signal operationalCurrent, operationalNext : std_logic;
679
  signal ackIdCurrent, ackIdNext : std_logic_vector(4 downto 0);
680 4 magro732
  signal bufferStatusCurrent, bufferStatusNext : std_logic_vector(4 downto 0);
681 11 magro732
  signal statusReceivedCurrent, statusReceivedNext : std_logic;
682
  signal numberSentLinkRequestsCurrent, numberSentLinkRequestsNext : std_logic_vector(1 downto 0);
683
  signal outputErrorStoppedCurrent, outputErrorStoppedNext : std_logic;
684
  signal recoverActiveCurrent, recoverActiveNext : std_logic;
685
  signal recoverCounterCurrent, recoverCounterNext : std_logic_vector(4 downto 0);
686
  signal ackIdWindowCurrent, ackIdWindowNext : std_logic_vector(4 downto 0);
687
  signal frameStateCurrent, frameStateNext : std_logic_vector(4 downto 0);
688
  signal frameWordCounterCurrent, frameWordCounterNext : std_logic_vector(1 downto 0);
689
  signal frameContentCurrent, frameContentNext : std_logic_vector(32*NUMBER_WORDS-1 downto 0);
690
  signal counterCurrent, counterNext : std_logic_vector(3 downto 0);
691
  signal symbolsTransmittedCurrent, symbolsTransmittedNext : std_logic_vector(7 downto 0);
692 4 magro732
 
693
begin
694
 
695
  process(areset_n, clk)
696
  begin
697
    if (areset_n = '0') then
698 11 magro732
      timeCurrent <= (others=>'0');
699 4 magro732
    elsif (clk'event and clk = '1') then
700 11 magro732
      timeCurrent <= std_logic_vector(unsigned(timeCurrent) + 1);
701 4 magro732
    end if;
702
  end process;
703
 
704
  TimeoutMemory: MemorySimpleDualPortAsync
705
    generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>TIMEOUT_WIDTH+1, INIT_VALUE=>'0')
706
    port map(
707 11 magro732
      clkA_i=>clk, enableA_i=>timeSentWrite,
708
      addressA_i=>timeSentWriteAddress, dataA_i=>timeSentWriteData,
709
      addressB_i=>timeSentReadAddress, dataB_o=>timeSentReadData);
710 4 magro732
 
711
  process(areset_n, clk)
712
  begin
713
    if (areset_n = '0') then
714 11 magro732
      operationalCurrent <= '0';
715
      ackIdCurrent <= (others=>'0');
716
      bufferStatusCurrent <= (others=>'0');
717 4 magro732
      statusReceivedCurrent <= '0';
718 11 magro732
      numberSentLinkRequestsCurrent <= (others=>'0');
719
      outputErrorStoppedCurrent <= '0';
720
      recoverActiveCurrent <= '0';
721
      recoverCounterCurrent <= (others=>'0');
722
      ackIdWindowCurrent <= (others=>'0');
723
      frameStateCurrent <= (others=>'0');
724
      frameWordCounterCurrent <= (others=>'0');
725
      frameContentCurrent <= (others=>'0');
726
      counterCurrent <= (others=>'0');
727
      symbolsTransmittedCurrent <= (others=>'0');
728 4 magro732
    elsif (clk'event and clk = '1') then
729 11 magro732
      operationalCurrent <= operationalNext;
730
      ackIdCurrent <= ackIdNext;
731
      bufferStatusCurrent <= bufferStatusNext;
732 4 magro732
      statusReceivedCurrent <= statusReceivedNext;
733 11 magro732
      numberSentLinkRequestsCurrent <= numberSentLinkRequestsNext;
734
      outputErrorStoppedCurrent <= outputErrorStoppedNext;
735
      recoverActiveCurrent <= recoverActiveNext;
736
      recoverCounterCurrent <= recoverCounterNext;
737
      ackIdWindowCurrent <= ackIdWindowNext;
738
      frameStateCurrent <= frameStateNext;
739
      frameWordCounterCurrent <= frameWordCounterNext;
740
      frameContentCurrent <= frameContentNext;
741 4 magro732
      counterCurrent <= counterNext;
742
      symbolsTransmittedCurrent <= symbolsTransmittedNext;
743
    end if;
744
  end process;
745 11 magro732
 
746
  TxCore: RioTransmitterCore
747
    generic map(TIMEOUT_WIDTH=>TIMEOUT_WIDTH,
748
                NUMBER_WORDS=>NUMBER_WORDS)
749
    port map(
750
      clk=>clk, areset_n=>areset_n,
751
      portLinkTimeout_i=>portLinkTimeout_i, portEnable_i=>portEnable_i,
752
      portInitialized_i=>portInitialized_i,
753
      txFull_i=>txFull_i, txWrite_o=>txWrite_o, txType_o=>txType_o, txData_o=>txData_o,
754
      txControlEmpty_i=>txControlEmpty_i,
755
      txControlSymbol_i=>txControlSymbol_i,
756
      txControlUpdate_o=>txControlUpdate_o,
757
      rxControlEmpty_i=>rxControlEmpty_i,
758
      rxControlSymbol_i=>rxControlSymbol_i,
759
      rxControlUpdate_o=>rxControlUpdate_o,
760
      linkInitialized_o=>linkInitialized_o,
761
      linkInitialized_i=>linkInitialized_i,
762
      ackIdStatus_i=>ackIdStatus_i,
763 4 magro732
 
764 11 magro732
      timeCurrent_i=>timeCurrent,
765
      timeSentWrite_o=>timeSentWrite,
766
      timeSentWriteAddress_o=>timeSentWriteAddress,
767
      timeSentWriteData_o=>timeSentWriteData,
768
      timeSentReadAddress_o=>timeSentReadAddress,
769
      timeSentReadData_i=>timeSentReadData,
770
 
771
      operational_i=>operationalCurrent, operational_o=>operationalNext,
772
      ackId_i=>ackIdCurrent, ackId_o=>ackIdNext,
773
      bufferStatus_i=>bufferStatusCurrent, bufferStatus_o=>bufferStatusNext,
774
      statusReceived_i=>statusReceivedCurrent, statusReceived_o=>statusReceivedNext,
775
      numberSentLinkRequests_i=>numberSentLinkRequestsCurrent, numberSentLinkRequests_o=>numberSentLinkRequestsNext,
776
      outputErrorStopped_i=>outputErrorStoppedCurrent, outputErrorStopped_o=>outputErrorStoppedNext,
777
      recoverActive_i=>recoverActiveCurrent, recoverActive_o=>recoverActiveNext,
778
      recoverCounter_i=>recoverCounterCurrent, recoverCounter_o=>recoverCounterNext,
779
      ackIdWindow_i=>ackIdWindowCurrent, ackIdWindow_o=>ackIdWindowNext,
780
      frameState_i=>frameStateCurrent, frameState_o=>frameStateNext,
781
      frameWordCounter_i=>frameWordCounterCurrent, frameWordCounter_o=>frameWordCounterNext,
782
      frameContent_i=>frameContentCurrent, frameContent_o=>frameContentNext,
783
      counter_i=>counterCurrent, counter_o=>counterNext,
784
      symbolsTransmitted_i=>symbolsTransmittedCurrent, symbolsTransmitted_o=>symbolsTransmittedNext,
785 4 magro732
 
786 11 magro732
      readFrameEmpty_i=>readFrameEmpty_i,
787
      readFrame_o=>readFrame_o,
788
      readFrameRestart_o=>readFrameRestart_o,
789
      readFrameAborted_i=>readFrameAborted_i,
790
      readWindowEmpty_i=>readWindowEmpty_i,
791
      readWindowReset_o=>readWindowReset_o,
792
      readWindowNext_o=>readWindowNext_o,
793
      readContentEmpty_i=>readContentEmpty_i,
794
      readContent_o=>readContent_o,
795
      readContentEnd_i=>readContentEnd_i,
796
      readContentWords_i=>readContentWords_i,
797
      readContentData_i=>readContentData_i);
798 4 magro732
 
799 11 magro732
end architecture;
800
 
801
 
802
 
803
-------------------------------------------------------------------------------
804
-- RioTransmitterCore
805
-------------------------------------------------------------------------------
806
library ieee;
807
use ieee.std_logic_1164.all;
808
use ieee.numeric_std.all;
809
use work.rio_common.all;
810
use work.rio_serial_common.all;
811
 
812
-------------------------------------------------------------------------------
813
-- Entity for RioTransmitterCore.
814
-------------------------------------------------------------------------------
815
entity RioTransmitterCore is
816
  generic(
817
    TIMEOUT_WIDTH : natural;
818
    NUMBER_WORDS : natural range 1 to 4 := 1);
819
  port(
820
    -- System signals.
821
    clk : in std_logic;
822
    areset_n : in std_logic;
823
 
824
    -- Status signals used for maintenance.
825
    portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
826
    portEnable_i : in std_logic;
827
 
828
    -- Port output interface.
829
    portInitialized_i : in std_logic;
830
    txFull_i : in std_logic;
831
    txWrite_o : out std_logic;
832
    txType_o : out std_logic_vector(2*NUMBER_WORDS-1 downto 0);
833
    txData_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0);
834
 
835
    -- Control symbols aimed to the transmitter.
836
    txControlEmpty_i : in std_logic;
837
    txControlSymbol_i : in std_logic_vector(13*NUMBER_WORDS-1 downto 0);
838
    txControlUpdate_o : out std_logic;
839
 
840
    -- Control symbols from the receiver to send.
841
    rxControlEmpty_i : in std_logic;
842
    rxControlSymbol_i : in std_logic_vector(13*NUMBER_WORDS-1 downto 0);
843
    rxControlUpdate_o : out std_logic;
844
 
845
    -- Internal signalling from the receiver part.
846
    linkInitialized_o : out std_logic;
847
    linkInitialized_i : in std_logic;
848
    ackIdStatus_i : in std_logic_vector(4 downto 0);
849
 
850
    -- The current time used for timeout calculations.
851
    timeCurrent_i : in std_logic_vector(TIMEOUT_WIDTH downto 0);
852 4 magro732
 
853 11 magro732
    -- Internal core variables for cascading.
854
    timeSentWrite_o : out std_logic;
855
    timeSentWriteAddress_o : out std_logic_vector(4 downto 0);
856
    timeSentWriteData_o : out std_logic_vector(TIMEOUT_WIDTH downto 0);
857
    timeSentReadAddress_o : out std_logic_vector(4 downto 0);
858
    timeSentReadData_i : in std_logic_vector(TIMEOUT_WIDTH downto 0);
859
 
860
    operational_i : in std_logic;
861
    operational_o : out std_logic;
862
    ackId_i : in std_logic_vector(4 downto 0);
863
    ackId_o : out std_logic_vector(4 downto 0);
864
    bufferStatus_i : in std_logic_vector(4 downto 0);
865
    bufferStatus_o : out std_logic_vector(4 downto 0);
866
    statusReceived_i : in std_logic;
867
    statusReceived_o : out std_logic;
868
    numberSentLinkRequests_i : in std_logic_vector(1 downto 0);
869
    numberSentLinkRequests_o : out std_logic_vector(1 downto 0);
870
    outputErrorStopped_i : in std_logic;
871
    outputErrorStopped_o : out std_logic;
872
    recoverActive_i : in std_logic;
873
    recoverActive_o : out std_logic;
874
    recoverCounter_i : in std_logic_vector(4 downto 0);
875
    recoverCounter_o : out std_logic_vector(4 downto 0);
876
    ackIdWindow_i : in std_logic_vector(4 downto 0);
877
    ackIdWindow_o : out std_logic_vector(4 downto 0);
878
    frameState_i : in std_logic_vector(4 downto 0);
879
    frameState_o : out std_logic_vector(4 downto 0);
880
    frameWordCounter_i : in std_logic_vector(1 downto 0);
881
    frameWordCounter_o : out std_logic_vector(1 downto 0);
882
    frameContent_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0);
883
    frameContent_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0);
884
    counter_i : in std_logic_vector(3 downto 0);
885
    counter_o : out std_logic_vector(3 downto 0);
886
    symbolsTransmitted_i : in std_logic_vector(7 downto 0);
887
    symbolsTransmitted_o : out std_logic_vector(7 downto 0);
888
 
889
    -- Frame buffer interface.
890
    readFrameEmpty_i : in std_logic;
891
    readFrame_o : out std_logic;
892
    readFrameRestart_o : out std_logic;
893
    readFrameAborted_i : in std_logic;
894
    readWindowEmpty_i : in std_logic;
895
    readWindowReset_o : out std_logic;
896
    readWindowNext_o : out std_logic;
897
    readContentEmpty_i : in std_logic;
898
    readContent_o : out std_logic;
899
    readContentEnd_i : in std_logic;
900
    readContentWords_i : in std_logic_vector(1 downto 0);
901
    readContentData_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0));
902
end entity;
903 4 magro732
 
904
 
905 11 magro732
-------------------------------------------------------------------------------
906
-- Architecture for RioTransmitterCore.
907
-------------------------------------------------------------------------------
908
architecture RioTransmitterCoreImpl of RioTransmitterCore is
909 4 magro732
 
910 11 magro732
  constant NUMBER_STATUS_TRANSMIT : std_logic_vector := "1111";
911
  constant NUMBER_LINK_RESPONSE_RETRIES : std_logic_vector := "10";
912 4 magro732
 
913 11 magro732
  -- REMARK: Binary coding???
914
  constant FRAME_START : std_logic_vector(4 downto 0) := "00001";
915
  constant FRAME_CHECK : std_logic_vector(4 downto 0) := "00010";
916
  constant FRAME_ACKID : std_logic_vector(4 downto 0) := "00100";
917
  constant FRAME_BODY : std_logic_vector(4 downto 0) := "01000";
918
  constant FRAME_END : std_logic_vector(4 downto 0) := "10000";
919
 
920
  component Crc5ITU is
921
    port(
922
      d_i : in  std_logic_vector(18 downto 0);
923
      crc_o : out std_logic_vector(4 downto 0));
924
  end component;
925 4 magro732
 
926 11 magro732
  signal timeSentUpdate : std_logic;
927
  signal timeElapsed : unsigned(TIMEOUT_WIDTH downto 0);
928
  signal timeDelta : unsigned(TIMEOUT_WIDTH downto 0);
929
  signal timeExpired : std_logic;
930 4 magro732
 
931 11 magro732
  signal sendRestartFromRetry, sendRestartFromRetryOut : std_logic;
932
  signal sendLinkRequest, sendLinkRequestOut : std_logic;
933 4 magro732
 
934 11 magro732
  signal symbolControlRestartOut, symbolControlRestart : std_logic;
935
  signal symbolControlLinkRequestOut, symbolControlLinkRequest : std_logic;
936
  signal symbolControlStartOut, symbolControlStart : std_logic;
937
  signal symbolControlEndOut, symbolControlEnd : std_logic;
938
  signal symbolDataOut, symbolData : std_logic;
939
  signal symbolDataContentOut, symbolDataContent : std_logic_vector(31 downto 0);
940 4 magro732
 
941 11 magro732
  signal symbolControlStype1 : std_logic;
942
  signal controlValidOut, controlValid : std_logic;
943
  signal stype0Out, stype0 : std_logic_vector(2 downto 0);
944
  signal parameter0Out, parameter0 : std_logic_vector(4 downto 0);
945
  signal parameter1Out, parameter1 : std_logic_vector(4 downto 0);
946
  signal stype1 : std_logic_vector(2 downto 0);
947
  signal cmd : std_logic_vector(2 downto 0);
948
  signal dataValid : std_logic;
949
  signal dataContent : std_logic_vector(31 downto 0);
950
 
951
  signal controlContent : std_logic_vector(31 downto 0);
952
  signal crc5 : std_logic_vector(4 downto 0);
953
 
954
  signal txControlStype0 : std_logic_vector(2 downto 0);
955
  signal txControlParameter0 : std_logic_vector(4 downto 0);
956
  signal txControlParameter1 : std_logic_vector(4 downto 0);
957 4 magro732
 
958 11 magro732
  signal rxControlStype0 : std_logic_vector(2 downto 0);
959
  signal rxControlParameter0 : std_logic_vector(4 downto 0);
960
  signal rxControlParameter1 : std_logic_vector(4 downto 0);
961 4 magro732
 
962 11 magro732
begin
963 4 magro732
 
964 11 magro732
  linkInitialized_o <= operational_i;
965
 
966
  -----------------------------------------------------------------------------
967
  -- N-3
968
  -- Receive stuff from link-partner and timeout supervision.
969
  -- Input: ackId, ackIdWindow, timeoutExpired
970
  -- Output: sendLinkRequest, sendRestartFromRetry, ackId,
971
  -----------------------------------------------------------------------------
972 4 magro732
 
973 11 magro732
  timeSentReadAddress_o <= ackId_i;
974
  timeElapsed <= unsigned(timeCurrent_i) - unsigned(timeSentReadData_i);
975
  timeDelta <= unsigned('0' & portLinkTimeout_i) - timeElapsed;
976
  timeExpired <= timeDelta(TIMEOUT_WIDTH);
977 4 magro732
 
978 11 magro732
  process(clk, areset_n)
979
  begin
980
    if (areset_n = '0') then
981
      sendRestartFromRetry <= '0';
982
      sendLinkRequest <= '0';
983
    elsif (clk'event and clk = '1') then
984
      sendRestartFromRetry <= sendRestartFromRetryOut;
985
      sendLinkRequest <= sendLinkRequestOut;
986
    end if;
987
  end process;
988
 
989
  -- REMARK: Reset statusReceived at startup...
990
  process(outputErrorStopped_i, recoverActive_i, recoverCounter_i, ackId_i, bufferStatus_i,
991
          statusReceived_i, numberSentLinkRequests_i)
992
  begin
993
    txControlUpdate_o <= '0';
994
    outputErrorStopped_o <= outputErrorStopped_i;
995
    recoverActive_o <= recoverActive_i;
996
    recoverCounter_o <= recoverCounter_i;
997
    ackId_o <= ackId_i;
998
    bufferStatus_o <= bufferStatus_i;
999
    statusReceived_o <= statusReceived_i;
1000
    numberSentLinkRequests_o <= numberSentLinkRequests_i;
1001 4 magro732
 
1002 11 magro732
    sendRestartFromRetryOut <= '0';
1003
    sendLinkRequestOut <= '0';
1004 4 magro732
 
1005 11 magro732
    if (recoverActive_i = '1') then
1006
      if (ackId_i /= recoverCounter_i) then
1007
        ackId_o <= std_logic_vector(unsigned(ackId_i) + 1);
1008
      else
1009
        recoverActive_o <= '0';
1010
        outputErrorStopped_o <= '0';
1011
      end if;
1012
    else
1013
      if (txFull_i = '0') then
1014
        if (operational_i = '0') then
1015
          if (txControlEmpty_i = '0') then
1016
            if (txControlStype0 = STYPE0_STATUS) then
1017
              -- A status-control symbol has been received.
1018
              ackId_o <= txControlParameter0;
1019
              bufferStatus_o <= txControlParameter1;
1020
              statusReceived_o <= '1';
1021 4 magro732
            else
1022 11 magro732
              -- Discard all other received symbols in this state.
1023 4 magro732
            end if;
1024 11 magro732
            txControlUpdate_o <= '1';
1025
          end if;
1026
        else
1027
          -- Check if the oldest frame timeout has expired.
1028
          if ((ackId_i /= ackIdWindow_i) and
1029
              (timeExpired = '1')) then
1030
            -- There has been a timeout on a transmitted frame.
1031 4 magro732
 
1032 11 magro732
            if (outputErrorStopped_i = '1') then
1033
              -- Count the number of retransmissions and abort if
1034
              -- no reply has been received for too many times.
1035
              if (unsigned(numberSentLinkRequests_i) /= 0) then
1036
                -- Not sent link-request too many times.
1037 4 magro732
 
1038 11 magro732
                -- Send another link-request.
1039
                sendLinkRequestOut <= '1';
1040
                numberSentLinkRequests_o <= std_logic_vector(unsigned(numberSentLinkRequests_i) - 1);
1041 4 magro732
              else
1042 11 magro732
                -- No response for too many times.
1043
                -- REMARK: What to do here???
1044
                --readWindowReset_o <= '1';
1045
                --stateNext <= STATE_UNINITIALIZED;
1046 4 magro732
              end if;
1047
            else
1048 11 magro732
              sendLinkRequestOut <= '1';
1049
              numberSentLinkRequests_o <= NUMBER_LINK_RESPONSE_RETRIES;
1050
              outputErrorStopped_o <= '1';
1051 4 magro732
            end if;
1052
          else
1053 11 magro732
            -- There has been no timeout.
1054 4 magro732
 
1055
            -- Check if any control symbol has been received from the link
1056
            -- partner.
1057
            if (txControlEmpty_i = '0') then
1058
              -- A control symbol has been received.
1059
 
1060
              -- Check the received control symbol.
1061
              case txControlStype0 is
1062
 
1063
                when STYPE0_STATUS =>
1064 11 magro732
                  if (outputErrorStopped_i = '0') then
1065
                    -- Save the number of buffers in the link partner.
1066
                    bufferStatus_o <= txControlParameter1;
1067
                  end if;
1068 4 magro732
 
1069
                when STYPE0_PACKET_ACCEPTED =>
1070
                  -- The link partner is accepting a frame.
1071
 
1072 11 magro732
                  if (outputErrorStopped_i = '0') then
1073
                    -- Save the number of buffers in the link partner.
1074
                    bufferStatus_o <= txControlParameter1;
1075
 
1076
                    -- Check if expecting this type of reply and that the ackId is
1077
                    -- expected.
1078
                    if ((ackId_i /= ackIdWindow_i) and
1079
                        (ackId_i = txControlParameter0)) then
1080
                      -- The packet-accepted is expected and the ackId is the expected.
1081
                      -- The frame has been accepted by the link partner.
1082
 
1083
                      -- Update to a new buffer and increment the ackId.
1084
                      readFrame_o <= '1';
1085
                      ackId_o <= std_logic_vector(unsigned(ackId_i) + 1);
1086
                    else
1087
                      -- Unexpected packet-accepted or packet-accepted for
1088
                      -- unexpected ackId.
1089
                      sendLinkRequestOut <= '1';
1090
                      numberSentLinkRequests_o <= NUMBER_LINK_RESPONSE_RETRIES;
1091
                      outputErrorStopped_o <= '1';
1092
                    end if;
1093 4 magro732
                  end if;
1094
 
1095
                when STYPE0_PACKET_RETRY =>
1096
                  -- The link partner has asked for a frame retransmission.
1097
 
1098 11 magro732
                  if (outputErrorStopped_i = '0') then
1099
                    -- Save the number of buffers in the link partner.
1100
                    bufferStatus_o <= txControlParameter1;
1101 4 magro732
 
1102 11 magro732
                    -- Check if the ackId is the one expected.
1103
                    if (ackId_i = txControlParameter0) then
1104
                      -- The ackId to retry is expected.
1105
                      -- Go to the output-retry-stopped state.
1106
                      -- REMARK: The output-retry-stopped state is equivalent
1107
                      -- to sending a restart-from-retry.
1108
                      sendRestartFromRetryOut <= '1';
1109
                    else
1110
                      -- Unexpected ackId to retry.
1111
                      sendLinkRequestOut <= '1';
1112
                      numberSentLinkRequests_o <= NUMBER_LINK_RESPONSE_RETRIES;
1113
                      outputErrorStopped_o <= '1';
1114
                    end if;
1115 4 magro732
                  end if;
1116 11 magro732
 
1117 4 magro732
                when STYPE0_PACKET_NOT_ACCEPTED =>
1118 11 magro732
                  if (outputErrorStopped_i = '0') then
1119
                    -- Packet was rejected by the link-partner.
1120
                    sendLinkRequestOut <= '1';
1121
                    numberSentLinkRequests_o <= NUMBER_LINK_RESPONSE_RETRIES;
1122
                    outputErrorStopped_o <= '1';
1123
                  end if;
1124 4 magro732
 
1125
                when STYPE0_LINK_RESPONSE =>
1126 11 magro732
                  if (outputErrorStopped_i = '1') then
1127
                    -- Check if the link partner return value is acceptable.
1128
                    if ((unsigned(txControlParameter0) - unsigned(ackId_i)) <=
1129
                        (unsigned(ackIdWindow_i) - unsigned(ackId_i))) then
1130
                      -- Recoverable error.
1131
                      -- Use the received ackId and recover by removing packets
1132
                      -- that has been received by the link-partner.
1133
                      recoverCounter_o <= txControlParameter0;
1134
                      recoverActive_o <= '1';
1135
                    else
1136
                      -- Totally out of sync.
1137
                      -- REMARK: What to do here???
1138
                      --readWindowReset_o <= '1';
1139
                      --stateNext <= STATE_UNINITIALIZED;
1140
                    end if;
1141
                  else
1142
                    -- Dont expect or need a link-response in this state.
1143
                    -- Discard it.
1144
                  end if;
1145 4 magro732
 
1146
                when STYPE0_VC_STATUS =>
1147
                  -- Not supported.
1148
                  -- Discard it.
1149
 
1150
                when STYPE0_RESERVED =>
1151
                  -- Not supported.
1152
                  -- Discard it.
1153
 
1154
                when STYPE0_IMPLEMENTATION_DEFINED =>
1155
                  -- Not supported.
1156
                  -- Discard it.
1157
 
1158
                when others =>
1159
                  null;
1160
              end case;
1161
 
1162
              -- Indicate the control symbol has been processed.
1163 11 magro732
              txControlUpdate_o <= '1';
1164
            end if;
1165
          end if;
1166
        end if;
1167
      end if;
1168
    end if;
1169
  end process;
1170
 
1171
  -----------------------------------------------------------------------------
1172
  -- N-2 pipeline stage.
1173
  -- Create stype1-part of symbols and data symbols. Save the time when a
1174
  -- packet was fully sent.
1175
  -- Input:  sendRestartFromRetry, sendLinkRequest
1176
  -- Output: ackIdWindow, frameState, timeout(0 to 31), 
1177
  --         symbolControlStart, symbolControlEnd, symbolControlRestart,
1178
  --         symbolControlLinkRequest, symbolData2, symbolData2Content.
1179
  -----------------------------------------------------------------------------
1180 4 magro732
 
1181 11 magro732
  process(clk, areset_n)
1182
  begin
1183
    if (areset_n = '0') then
1184
      symbolControlRestart <= '0';
1185
      symbolControlLinkRequest <= '0';
1186
      symbolControlStart <= '0';
1187
      symbolControlEnd <= '0';
1188
      symbolData <= '0';
1189
      symbolDataContent <= (others => '0');
1190
    elsif (clk'event and clk = '1') then
1191
      symbolControlRestart <= symbolControlRestartOut;
1192
      symbolControlLinkRequest <= symbolControlLinkRequestOut;
1193
      symbolControlStart <= symbolControlStartOut;
1194
      symbolControlEnd <= symbolControlEndOut;
1195
      symbolData <= symbolDataOut;
1196
      symbolDataContent <= symbolDataContentOut;
1197
    end if;
1198
  end process;
1199
 
1200
  -- This process decide which stype1-part of a control symbols to send as well
1201
  -- as all data symbols.
1202
  process(frameState_i, ackIdWindow_i, timeCurrent_i, sendRestartFromRetry, sendLinkRequest)
1203
  begin
1204
    readFrame_o <= '0';
1205
    readFrameRestart_o <= '0';
1206
    readWindowReset_o <= '0';
1207
    readWindowNext_o <= '0';
1208
    readContent_o <= '0';
1209 4 magro732
 
1210 11 magro732
    frameState_o <= frameState_i;
1211
    ackIdWindow_o <= ackIdWindow_i;
1212
 
1213
    timeSentWrite_o <= '0';
1214
    timeSentWriteAddress_o <= ackIdWindow_i;
1215
    timeSentWriteData_o <= timeCurrent_i;
1216 4 magro732
 
1217 11 magro732
    symbolControlRestartOut <= '0';
1218
    symbolControlLinkRequestOut <= '0';
1219
    symbolControlStartOut <= '0';
1220
    symbolControlEndOut <= '0';
1221
    symbolDataOut <= '0';
1222
    symbolDataContentOut <= (others => '0');
1223 4 magro732
 
1224 11 magro732
    if (recoverActive_i = '1') then
1225
      -- REMARK: Make sure idle is generated when this state is active...
1226
      ackIdWindow_o <= recoverCounter_i;
1227
      frameState_o <= FRAME_START;
1228 4 magro732
 
1229 11 magro732
      if (ackId_i /= recoverCounter_i) then
1230
        readFrame_o <= '1';
1231
      else
1232
        readWindowReset_o <= '1';
1233
      end if;
1234
    else
1235
      if (txFull_i = '0') then
1236
        if (operational_i = '0') then
1237 4 magro732
          -----------------------------------------------------------------------
1238 11 magro732
          -- This state is entered at startup. A port that is not initialized
1239
          -- should only transmit idle sequences.
1240 4 magro732
          -----------------------------------------------------------------------
1241 11 magro732
 
1242
          -- Initialize framing before entering the operational state.
1243
          -- REMARK: Only do this when the portInitialized becomes asserted???
1244
          frameState_o <= FRAME_START;
1245
          ackIdWindow_o <= ackId_i;
1246
          readWindowReset_o <= '1';
1247
        else
1248
          -------------------------------------------------------------------
1249
          -- This state is the operational state. It relays frames and handle
1250
          -- flow control.
1251
          -------------------------------------------------------------------
1252
 
1253
          if (sendRestartFromRetry = '1') then
1254 4 magro732
            -- Send a restart-from-retry control symbol to acknowledge the restart
1255
            -- of the frame.
1256 11 magro732
            symbolControlRestartOut <= '1';
1257 4 magro732
 
1258
            -- Make sure there wont be any timeout before the frame is
1259
            -- starting to be retransmitted.
1260 11 magro732
            timeSentWrite_o <= '1';
1261 4 magro732
 
1262
            -- Restart the frame transmission.
1263 11 magro732
            ackIdWindow_o <= ackId_i;
1264
            frameState_o <= FRAME_START;
1265 4 magro732
            readWindowReset_o <= '1';
1266 11 magro732
          end if;
1267 4 magro732
 
1268 11 magro732
          if (sendLinkRequest = '1') then
1269
            -- Dont restart the packet transmission since we do not yet know which
1270
            -- packets that was successfully received by our link partner.
1271 4 magro732
 
1272
            -- Send a link-request symbol.
1273 11 magro732
            symbolControlLinkRequestOut <= '1';
1274 4 magro732
 
1275
            -- Write the current timer value.
1276 11 magro732
            timeSentWrite_o <= '1';
1277 4 magro732
          end if;
1278
 
1279 11 magro732
          if ((sendRestartFromRetry = '0') and (sendLinkRequest = '0')  and
1280
              (outputErrorStopped_i = '0')) then
1281
            -- Check if a frame transfer is in progress.
1282
            -- REMARK: Hold any data symbol if there is a pending symbol from the
1283
            -- receiver side...
1284 4 magro732
 
1285 11 magro732
            case frameState_i is
1286
 
1287
              when FRAME_START =>
1288
                ---------------------------------------------------------------
1289
                -- No frame has been started.
1290
                ---------------------------------------------------------------
1291 4 magro732
 
1292 11 magro732
                -- Wait for a new frame to arrive from the frame buffer,
1293
                -- for new buffers to be available at the link-partner
1294
                -- and also check that a maximum 31 frames are outstanding.
1295
                -- REMARK: Only update readContent_o in the last instance
1296
                -- if cascaded...
1297
                if ((readWindowEmpty_i = '0') and
1298
                    (bufferStatus_i /= "00000") and
1299
                    ((unsigned(ackIdWindow_i) - unsigned(ackId_i)) /= 31)) then
1300
                  -- New data is available for transmission and there
1301
                  -- is room to receive it at the other side.
1302 4 magro732
 
1303 11 magro732
                  -- Indicate that a control symbol has been sent to start the
1304
                  -- transmission of the frame.
1305
                  frameState_o <= FRAME_CHECK;
1306 4 magro732
 
1307 11 magro732
                  -- Update the output from the frame buffer to contain the
1308
                  -- data when it is read later.
1309
                  readContent_o <= '1';
1310
                end if;
1311
 
1312
              when FRAME_CHECK =>
1313
                -------------------------------------------------------
1314
                -- Check if we are allowed to transmit this packet.
1315
                -------------------------------------------------------
1316
 
1317
                -- Check if this packet is allowed to be transmitted.
1318
                if ((portEnable_i = '1') or
1319
                    (readContentData_i(19 downto 16) = FTYPE_MAINTENANCE_CLASS)) then
1320
                  -- The packet may be transmitted.
1321 4 magro732
 
1322 11 magro732
                  -- Indicate that a control symbol has been sent to start the
1323
                  -- transmission of the frame.
1324
                  frameState_o <= FRAME_ACKID;
1325
                  frameWordCounter_o <= readContentWords_i;
1326
                  frameContent_o <= readContentData_i;
1327 4 magro732
 
1328 11 magro732
                  -- Send a control symbol to start the packet and a status to
1329
                  -- complete the symbol.
1330
                  symbolControlStartOut <= '1';
1331
                else
1332
                  -- The packet should be discarded.
1333
                  -- Send idle-sequence.
1334 4 magro732
 
1335 11 magro732
                  -- Check that there are no outstanding packets that
1336
                  -- has not been acknowledged.
1337
                  if(unsigned(ackIdWindow_i) = unsigned(ackId_i)) then
1338
                    -- No unacknowledged packets.
1339
                    -- It is now safe to remove the unallowed frame.
1340
                    readFrame_o <= '1';
1341 4 magro732
 
1342 11 magro732
                    -- Go back and send a new frame.
1343
                    frameState_o <= FRAME_START;
1344
                  end if;
1345
                end if;
1346 4 magro732
 
1347 11 magro732
              when FRAME_ACKID =>
1348
                ---------------------------------------------------------------
1349
                -- Send the first packet content containing our current
1350
                -- ackId.
1351
                ---------------------------------------------------------------
1352
 
1353
                -- Write a new data symbol and fill in our ackId on the
1354
                -- packet.
1355
                symbolDataOut <= '1';
1356
                symbolDataContentOut <=
1357
                  std_logic_vector(ackIdWindow_i) & "0" &
1358
                  frameContent_i((32*NUMBER_WORDS)-1 downto (32*(NUMBER_WORDS-1))-1);
1359
 
1360
                if (unsigned(frameWordCounter_i) /= 0) then
1361
                  frameWordCounter_o <=
1362
                    std_logic_vector(unsigned(frameWordCounter_i) - 1);
1363
                  frameContent_o <=
1364
                    frameContent_i((32*(NUMBER_WORDS-1))-1 downto 0) & x"0000";
1365 4 magro732
                else
1366 11 magro732
                  readContent_o <= '1';
1367
                  frameWordCounter_o <= readContentWords_i;
1368
                  frameContent_o <= readContentData_i;
1369 4 magro732
                end if;
1370
 
1371 11 magro732
                -- Continue to send the rest of the body of the packet.
1372
                frameState_o <= FRAME_BODY;
1373
 
1374
              when FRAME_BODY =>
1375
                ---------------------------------------------------------------
1376
                -- The frame has not been fully sent.
1377
                -- Send a data symbol.
1378
                ---------------------------------------------------------------
1379
                -- REMARK: There will be idle symbols generated here if the
1380
                -- end-of-packet cannot be generated directly following the last
1381
                -- data symbol... need to rewrite PacketBufferWindow to indicate
1382
                -- the end at the last word.
1383
                -- REMARK: Dont send anything if there is a pending symbol in the
1384
                -- rx-control fifo to let it be transmitted in the middle of the
1385
                -- packet...
1386
 
1387
                -- Write a new data symbol.
1388
                symbolDataOut <= '1';
1389
                symbolDataContentOut <=
1390
                  frameContent_i((32*NUMBER_WORDS)-1 downto (32*(NUMBER_WORDS-1))-1);
1391 4 magro732
 
1392 11 magro732
                if (unsigned(frameWordCounter_i) /= 0) then
1393
                  frameWordCounter_o <=
1394
                    std_logic_vector(unsigned(frameWordCounter_i) - 1);
1395
                  frameContent_o <=
1396
                    frameContent_i((32*(NUMBER_WORDS-1))-1 downto 0) & x"0000";
1397
                else
1398
                  -- Check if the frame is ending.
1399
                  if (readContentEnd_i = '1') then
1400
                    -- The frame is ending.
1401 4 magro732
 
1402 11 magro732
                    -- Update the window to the next frame.
1403
                    -- It takes one tick for the output from the frame
1404
                    -- buffer to get updated.
1405
                    readWindowNext_o <= '1';
1406 4 magro732
 
1407 11 magro732
                    -- Proceed to check if there is another frame to start
1408
                    -- with directly.
1409
                    frameState_o <= FRAME_END;
1410 4 magro732
                  else
1411 11 magro732
                    readContent_o <= '1';
1412
                    frameWordCounter_o <= readContentWords_i;
1413
                    frameContent_o <= readContentData_i;
1414 4 magro732
                  end if;
1415
                end if;
1416 11 magro732
 
1417
              when FRAME_END =>
1418
                ---------------------------------------------------------------
1419
                -- A frame has ended and the window has been updated.
1420
                -- Check if the next symbol should end the frame or if a
1421
                -- new one should be started.
1422
                ---------------------------------------------------------------
1423
 
1424
                -- Check if there is a new frame pending.
1425
                if (readWindowEmpty_i = '1') then
1426
                  -- No new frame is pending.
1427
 
1428
                  -- Send a control symbol to end the packet.
1429
                  symbolControlEndOut <= '1';
1430
                end if;
1431
 
1432
                -- Update the window ackId.
1433
                ackIdWindow_o <= std_logic_vector(unsigned(ackIdWindow_i) + 1);
1434
 
1435
                -- Start timeout supervision for transmitted frame.
1436
                timeSentWrite_o <= '1';
1437
 
1438
                -- Start a new frame the next time.
1439
                frameState_o <= FRAME_START;
1440
 
1441
              when others =>
1442
                ---------------------------------------------------------------
1443
                -- 
1444
                ---------------------------------------------------------------
1445
                null;
1446
 
1447
            end case;
1448
          end if;
1449
        end if;
1450
      end if;
1451
    end if;
1452
  end process;
1453
 
1454
  -----------------------------------------------------------------------------
1455
  -- N-1
1456
  -- Create the stype0 and stype1 part of a control symbol.
1457
  -- This process makes sure that the buffer status are transmitted at least
1458
  -- every 255 symbol.
1459
  -- At startup it makes sure that at least 16 status symbols are transmitted
1460
  -- before the operational-state is entered.
1461
  -- Input:  symbolControlStart, symbolControlEnd, symbolControlRestart,
1462
  --         symbolControlLinkRequest, symbolData, symbolDataContent
1463
  -- Output: symbolsTransmitted_o, operational_o, 
1464
  --         symbolControl, stype0, parameter0, parameter1, stype1, cmd,
1465
  --         symbolData1, symbolData1Content
1466
  -----------------------------------------------------------------------------
1467
 
1468
  process(clk, areset_n)
1469
  begin
1470
    if (areset_n = '0') then
1471
      controlValid <= '0';
1472
      stype0 <= (others=>'0');
1473
      parameter0 <= (others=>'0');
1474
      parameter1 <= (others=>'0');
1475
      stype1 <= STYPE1_NOP;
1476
      cmd <= (others=>'0');
1477
      dataValid <= '0';
1478
      dataContent <= (others=>'0');
1479
    elsif (clk'event and clk = '1') then
1480
      if (txFull_i = '0') then
1481
        controlValid <= controlValidOut;
1482
        stype0 <= stype0Out;
1483
        parameter0 <= parameter0Out;
1484
        parameter1 <= parameter1Out;
1485
        stype1 <= STYPE1_NOP;
1486
        cmd <= "000";
1487
        dataValid <= symbolData;
1488
        dataContent <= symbolDataContent;
1489
 
1490
        if (symbolControlStart = '1') then
1491
          stype1 <= STYPE1_START_OF_PACKET;
1492
        end if;
1493
        if (symbolControlEnd = '1') then
1494
          stype1 <= STYPE1_END_OF_PACKET;
1495
        end if;
1496
        if (symbolControlRestart = '1') then
1497
          stype1 <= STYPE1_RESTART_FROM_RETRY;
1498
        end if;
1499
        if (symbolControlLinkRequest = '1') then
1500
          stype1 <= STYPE1_LINK_REQUEST;
1501
          cmd <= LINK_REQUEST_CMD_INPUT_STATUS;
1502
        end if;
1503
      end if;
1504
    end if;
1505
  end process;
1506
 
1507
  symbolControlStype1 <=
1508
    symbolControlRestart or symbolControlLinkRequest or
1509
    symbolControlStart or symbolControlEnd;
1510
 
1511
  process(txFull_i, linkInitialized_i, ackIdStatus_i, portInitialized_i,
1512
          operational_i, counter_i, statusReceived_i, symbolsTransmitted_i)
1513
  begin
1514
    operational_o <= operational_i;
1515
    counter_o <= counter_i;
1516
 
1517
    controlValidOut <= '0';
1518
    stype0Out <= STYPE0_STATUS;
1519
    parameter0Out <= ackIdStatus_i;
1520
    parameter1Out <= "11111";
1521
 
1522
    -- Check if there is room for more in the outbound fifo.
1523
    if (txFull_i = '0') then
1524
      -- The outbound fifo needs to be filled.
1525
 
1526
      -- Check the operational state.
1527
      if (operational_i = '0') then
1528
        -----------------------------------------------------------------------
1529
        -- This state is entered at startup. A port that is not initialized
1530
        -- should only transmit idle sequences.
1531
        -----------------------------------------------------------------------
1532
 
1533
        -- Check if the port is initialized.
1534
        if (portInitialized_i = '1') then
1535
          ---------------------------------------------------------------------
1536
          -- The specification requires a status control symbol being sent at
1537
          -- least every 1024 code word until an error-free status has been
1538
          -- received. This implies that at most 256 idle sequences should be
1539
          -- sent in between status control symbols. Once an error-free status 
1540
          -- has been received, status symbols may be sent more rapidly. At
1541
          -- least 15 statuses has to be transmitted once an error-free status
1542
          -- has been received.
1543
          ---------------------------------------------------------------------
1544
 
1545
          -- Check if we are ready to change state to operational.
1546
          if ((linkInitialized_i = '1') and
1547
              (unsigned(counter_i) = 0)) then
1548
            -- Receiver has received enough error free status symbols and we
1549
            -- have transmitted enough.
1550
 
1551
            -- Considder ourselfs operational.
1552
            operational_o <= '1';
1553
          else
1554
            -- Not ready to change state to operational.
1555
            -- Dont do anything.
1556
          end if;
1557
 
1558
          -- Check if idle sequence or a status symbol should be transmitted.
1559
          if (((statusReceived_i = '0') and (symbolsTransmitted_i = x"ff")) or
1560
              ((statusReceived_i = '1') and (symbolsTransmitted_i > x"0f"))) then
1561
            -- A status symbol should be transmitted.
1562
 
1563
            -- Send a status control symbol to the link partner.
1564
            controlValidOut <= '1';
1565
 
1566
            -- Reset idle sequence transmission counter.
1567
            symbolsTransmitted_o <= (others=>'0');
1568
 
1569
            -- Check if the number of transmitted statuses should be updated.
1570
            if (statusReceived_i = '1') and (unsigned(counter_i) /= 0) then
1571
              counter_o <= std_logic_vector(unsigned(counter_i) - 1);
1572 4 magro732
            end if;
1573
          else
1574 11 magro732
            -- Increment the idle sequence transmission counter.
1575
            symbolsTransmitted_o <= std_logic_vector(unsigned(symbolsTransmitted_i) + 1);
1576 4 magro732
          end if;
1577 11 magro732
        else
1578
          -- The port is not initialized.
1579
          -- Reset initialization variables.
1580
          counter_o <= NUMBER_STATUS_TRANSMIT;
1581
        end if;
1582
      else
1583
        ---------------------------------------------------------------------
1584
        -- This is the operational state.
1585
        -- It is entered once the link has been considdered up and running.
1586
        ---------------------------------------------------------------------
1587 4 magro732
 
1588 11 magro732
        -- Check if the port is still initialized.
1589
        if (portInitialized_i = '1') then
1590
          -- The port is still initialized.
1591
 
1592
          -- Check if a status must be sent.
1593
          -- A status must be sent when there are not other stype0 value to
1594
          -- send or if too many symbols without buffer-status has been sent.
1595
          -- REMARK: Is there a risk of a race when a generated status-symbol
1596
          -- is sent before another symbol stored in the rx-control fifo???
1597
          if (((symbolControlStype1 = '1') and (rxControlEmpty_i = '1')) or
1598
              ((symbolControlStype1 = '0') and (symbolData = '0') and
1599
               (symbolsTransmitted_i = x"ff"))) then
1600
            -- A control symbol is about to be sent without pending symbol from
1601
            -- receiver or too many idle symbols has been sent.
1602 4 magro732
 
1603 11 magro732
            -- Force the sending of a status containing the bufferStatus.
1604
            controlValidOut <= '1';
1605
            symbolsTransmitted_o <= (others=>'0');
1606
          elsif ((symbolControlStype1 = '1') and (rxControlEmpty_i = '0')) then
1607
            -- A control symbol is about to be sent and there is a pending
1608
            -- symbol from the receiver.
1609
 
1610
            -- Remove the symbol from the fifo.
1611
            rxControlUpdate_o <= '1';
1612
 
1613
            -- Send the receiver symbol.
1614
            controlValidOut <= '1';
1615
            stype0Out <= rxControlStype0;
1616
            parameter0Out <= rxControlParameter0;
1617
            parameter1Out <= rxControlParameter1;
1618
 
1619
            -- Check if the transmitted symbol contains status about
1620
            -- available buffers.
1621
            if ((rxControlStype0 = STYPE0_PACKET_ACCEPTED) or
1622
                (rxControlStype0 = STYPE0_PACKET_RETRY)) then
1623
              -- A symbol containing the bufferStatus has been sent.
1624
              symbolsTransmitted_o <= (others=>'0');
1625
            else
1626
              -- A symbol not containing the bufferStatus has been sent.
1627
              symbolsTransmitted_o <= std_logic_vector(unsigned(symbolsTransmitted_i) + 1);
1628
            end if;
1629 4 magro732
          else
1630 11 magro732
            -- A symbol not containing the bufferStatus has been sent.
1631
            controlValidOut <= '0';
1632
            symbolsTransmitted_o <= std_logic_vector(unsigned(symbolsTransmitted_i) + 1);
1633 4 magro732
          end if;
1634 11 magro732
        else
1635
          -- The port is not initialized anymore.
1636
          -- Change the operational state.
1637
          operational_o <= '0';
1638
        end if;
1639
      end if;
1640
    end if;
1641
  end process;
1642
 
1643
  -----------------------------------------------------------------------------
1644
  -- N pipeline stage.
1645
  -- Make all symbols ready for transmission, i.e. calculate the CRC5 on
1646
  -- control symbols.
1647
  -- Inputs: controlValid, stype0, parameter0, parameter1, stype1, cmd,
1648
  --         symbolData1, symbolData1Content 
1649
  -----------------------------------------------------------------------------
1650 4 magro732
 
1651 11 magro732
  controlContent(31 downto 29) <= stype0;
1652
  controlContent(28 downto 24) <= parameter0;
1653
  controlContent(23 downto 19) <= parameter1;
1654
  controlContent(18 downto 16) <= stype1;
1655
  controlContent(15 downto 13) <= cmd;
1656
  controlContent(12 downto 8) <= crc5;
1657
  controlContent(7 downto 0) <= x"00";
1658 4 magro732
 
1659 11 magro732
  Crc5Calculator: Crc5ITU
1660
    port map(
1661
      d_i=>controlContent(31 downto 13), crc_o=>crc5);
1662
 
1663
  txWrite_o <= not txFull_i;
1664
  process(clk, areset_n)
1665
  begin
1666
    if (areset_n = '0') then
1667
      txType_o <= SYMBOL_IDLE;
1668
      txData_o <= (others=>'0');
1669
    elsif (clk'event and clk = '1') then
1670
      if (txFull_i = '0') then
1671
        txType_o <= SYMBOL_IDLE;
1672
        if (controlValid = '1') then
1673
          txType_o <= SYMBOL_CONTROL;
1674
          txData_o <= controlContent;
1675
        end if;
1676
        if (dataValid = '1') then
1677
          txType_o <= SYMBOL_DATA;
1678
          txData_o <= dataContent;
1679
        end if;
1680
      end if;
1681 4 magro732
    end if;
1682 11 magro732
  end process;
1683
 
1684 4 magro732
end architecture;
1685
 
1686
 
1687
 
1688
-------------------------------------------------------------------------------
1689
-- 
1690
-------------------------------------------------------------------------------
1691
library ieee;
1692
use ieee.std_logic_1164.all;
1693
use ieee.numeric_std.all;
1694
use work.rio_common.all;
1695
 
1696
 
1697 11 magro732
entity RioReceiver is
1698
  generic(
1699
    NUMBER_WORDS : natural range 1 to 4 := 1);
1700
  port(
1701
    clk : in std_logic;
1702
    areset_n : in std_logic;
1703
 
1704
    portEnable_i : in std_logic;
1705
 
1706
    localAckIdWrite_i : in std_logic;
1707
    inboundAckId_i : in std_logic_vector(4 downto 0);
1708
    inboundAckId_o : out std_logic_vector(4 downto 0);
1709
 
1710
    portInitialized_i : in std_logic;
1711
    rxEmpty_i : in std_logic;
1712
    rxRead_o : out std_logic;
1713
    rxType_i : in std_logic_vector(2*NUMBER_WORDS-1 downto 0);
1714
    rxData_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0);
1715
 
1716
    txControlWrite_o : out std_logic_vector(NUMBER_WORDS-1 downto 0);
1717
    txControlSymbol_o : out std_logic_vector(12*NUMBER_WORDS downto 0);
1718
    rxControlWrite_o : out std_logic_vector(NUMBER_WORDS-1 downto 0);
1719
    rxControlSymbol_o : out std_logic_vector(12*NUMBER_WORDS downto 0);
1720
 
1721
    ackIdStatus_o : out std_logic_vector(4 downto 0);
1722
    linkInitialized_o : out std_logic;
1723
 
1724
    writeFrameFull_i : in std_logic;
1725
    writeFrame_o : out std_logic;
1726
    writeFrameAbort_o : out std_logic;
1727
    writeContent_o : out std_logic;
1728
    writeContentWords_o : out std_logic_vector(1 downto 0);
1729
    writeContentData_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0));
1730
end entity;
1731
 
1732 4 magro732
-------------------------------------------------------------------------------
1733
-- 
1734
-------------------------------------------------------------------------------
1735 11 magro732
architecture RioReceiverImpl of RioReceiver is
1736
 
1737
  component RioReceiverCore is
1738
    generic(
1739
      NUMBER_WORDS : natural range 1 to 4 := 1);
1740
    port(
1741
      clk : in std_logic;
1742
      areset_n : in std_logic;
1743
 
1744
      -- Status signals used for maintenance.
1745
      portEnable_i : in std_logic;
1746
 
1747
      -- Support for localAckIdCSR.
1748
      -- REMARK: Add support for this???
1749
      localAckIdWrite_i : in std_logic;
1750
      inboundAckId_i : in std_logic_vector(4 downto 0);
1751
      inboundAckId_o : out std_logic_vector(4 downto 0);
1752
 
1753
      -- Port input interface.
1754
      portInitialized_i : in std_logic;
1755
      rxEmpty_i : in std_logic;
1756
      rxRead_o : out std_logic;
1757
      rxType_i : in std_logic_vector(1 downto 0);
1758
      rxData_i : in std_logic_vector(31 downto 0);
1759
 
1760
      -- Receiver has received a control symbol containing:
1761
      -- packet-accepted, packet-retry, packet-not-accepted, 
1762
      -- status, VC_status, link-response
1763
      txControlWrite_o : out std_logic;
1764
      txControlSymbol_o : out std_logic_vector(12 downto 0);
1765
 
1766
      -- Reciever wants to signal the link partner:
1767
      -- a new frame has been accepted => packet-accepted(rxAckId, bufferStatus)
1768
      -- a frame needs to be retransmitted due to buffering =>
1769
      -- packet-retry(rxAckId, bufferStatus)
1770
      -- a frame is rejected due to errors => packet-not-accepted
1771
      -- a link-request should be answered => link-response
1772
      rxControlWrite_o : out std_logic;
1773
      rxControlSymbol_o : out std_logic_vector(12 downto 0);
1774
 
1775
      -- Status signals used internally.
1776
      ackIdStatus_o : out std_logic_vector(4 downto 0);
1777
      linkInitialized_o : out std_logic;
1778
 
1779
      -- Core->Core cascading signals.
1780
      enable_o : out std_logic;
1781
      operational_i : in std_logic;
1782
      operational_o : out std_logic;
1783
      inputRetryStopped_i : in std_logic;
1784
      inputRetryStopped_o : out std_logic;
1785
      inputErrorStopped_i : in std_logic;
1786
      inputErrorStopped_o : out std_logic;
1787
      ackId_i : in unsigned(4 downto 0);
1788
      ackId_o : out unsigned(4 downto 0);
1789
      frameIndex_i : in std_logic_vector(6 downto 0);
1790
      frameIndex_o : out std_logic_vector(6 downto 0);
1791
      frameWordCounter_i : in std_logic_vector(1 downto 0);
1792
      frameWordCounter_o : out std_logic_vector(1 downto 0);
1793
      frameContent_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0);
1794
      frameContent_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0);
1795
      crc_i : in std_logic_vector(15 downto 0);
1796
      crc_o : out std_logic_vector(15 downto 0);
1797
 
1798
      -- Frame buffering interface.
1799
      writeFrameFull_i : in std_logic;
1800
      writeFrame_o : out std_logic;
1801
      writeFrameAbort_o : out std_logic;
1802
      writeContent_o : out std_logic;
1803
      writeContentWords_o : out std_logic_vector(1 downto 0);
1804
      writeContentData_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0));
1805
  end component;
1806
 
1807
  signal enable : std_logic_vector(NUMBER_WORDS-1 downto 0);
1808
  signal operationalCurrent, operationalNext : std_logic_vector(NUMBER_WORDS-1 downto 0);
1809
  signal inputRetryStoppedCurrent, inputRetryStoppedNext : std_logic_vector(NUMBER_WORDS-1 downto 0);
1810
  signal inputErrorStoppedCurrent, inputErrorStoppedNext : std_logic_vector(NUMBER_WORDS-1 downto 0);
1811
  signal ackIdCurrent, ackIdNext : unsigned(5*NUMBER_WORDS-1 downto 0);
1812
  signal frameIndexCurrent, frameIndexNext : std_logic_vector(7*NUMBER_WORDS-1 downto 0);
1813
  signal frameWordCounterCurrent, frameWordCounterNext : std_logic_vector(2*NUMBER_WORDS-1 downto 0);
1814
  signal frameContentCurrent, frameContentNext : std_logic_vector(32*NUMBER_WORDS-1 downto 0);
1815
  signal crcCurrent, crcNext : std_logic_vector(16*NUMBER_WORDS-1 downto 0);
1816
 
1817
  signal txControlWrite : std_logic_vector(NUMBER_WORDS-1 downto 0);
1818
  signal rxControlWrite : std_logic_vector(NUMBER_WORDS-1 downto 0);
1819
 
1820
  signal writeFrame : std_logic_vector(NUMBER_WORDS-1 downto 0);
1821
  signal writeFrameAbort : std_logic_vector(NUMBER_WORDS-1 downto 0);
1822
  signal writeContent : std_logic_vector(NUMBER_WORDS-1 downto 0);
1823
  signal writeContentWords : std_logic_vector(2*NUMBER_WORDS-1 downto 0);
1824
  signal writeContentData : std_logic_vector(32*NUMBER_WORDS-1 downto 0);
1825
 
1826
begin
1827
 
1828
  -----------------------------------------------------------------------------
1829
  -- Output generation to packet buffer.
1830
  -----------------------------------------------------------------------------
1831
  process(enable, writeFrame, writeFrameAbort,
1832
          writeContent, writeContentWords, writeContentData)
1833
  begin
1834
    writeFrame_o <= '0';
1835
    writeFrameAbort_o <= '0';
1836
    writeContent_o <= '0';
1837
    writeContentWords_o <= (others=>'0');
1838
    writeContentData_o <= (others=>'0');
1839
    for i in 0 to NUMBER_WORDS-1 loop
1840
      if ((writeFrame(i) = '1') and (enable(i) = '1')) then
1841
        writeFrame_o <= '1';
1842
      end if;
1843
 
1844
      if ((writeFrameAbort(i) = '1') and (enable(i) = '1')) then
1845
        writeFrameAbort_o <= '1';
1846
      end if;
1847
 
1848
      if ((writeContent(i) = '1') and (enable(i) = '1')) then
1849
        writeContent_o <= '1';
1850
        writeContentWords_o <= writeContentWords(2*(i+1)-1 downto 2*i);
1851
        writeContentData_o <= writeContentData(32*(i+1)-1 downto 32*i);
1852
      end if;
1853
    end loop;
1854
  end process;
1855
 
1856
  -----------------------------------------------------------------------------
1857
  -- Protocol core and synchronization.
1858
  -----------------------------------------------------------------------------
1859
  process(clk, areset_n)
1860
  begin
1861
    if (areset_n = '0') then
1862
      operationalCurrent <= (others=>'0');
1863
      inputRetryStoppedCurrent <= (others=>'0');
1864
      inputErrorStoppedCurrent <= (others=>'0');
1865
      ackIdCurrent <= (others=>'0');
1866
      frameIndexCurrent <= (others => '0');
1867
      frameWordCounterCurrent <= (others=>'0');
1868
      frameContentCurrent <= (others=>'0');
1869
      crcCurrent <= (others=>'0');
1870
    elsif (clk'event and clk = '1') then
1871
      if (enable(0) = '1') then
1872
        operationalCurrent <= operationalNext;
1873
        inputRetryStoppedCurrent <= inputRetryStoppedNext;
1874
        inputErrorStoppedCurrent <= inputErrorStoppedNext;
1875
        ackIdCurrent <= ackIdNext;
1876
        frameIndexCurrent <= frameIndexNext;
1877
        frameWordCounterCurrent <= frameWordCounterNext;
1878
        frameContentCurrent <= frameContentNext;
1879
        crcCurrent <= crcNext;
1880
      end if;
1881
    end if;
1882
  end process;
1883
 
1884
  CoreGeneration: for i in 0 to NUMBER_WORDS-1 generate
1885
    txControlWrite_o(i) <= txControlWrite(i) and enable(i);
1886
    rxControlWrite_o(i) <= rxControlWrite(i);
1887
 
1888
    ReceiverCore: RioReceiverCore
1889
      generic map(NUMBER_WORDS=>NUMBER_WORDS)
1890
      port map(
1891
        clk=>clk,
1892
        areset_n=>areset_n,
1893
        portEnable_i=>portEnable_i,
1894
        localAckIdWrite_i=>localAckIdWrite_i,
1895
        inboundAckId_i=>inboundAckId_i,
1896
        inboundAckId_o=>inboundAckId_o,
1897
        portInitialized_i=>portInitialized_i,
1898
        rxEmpty_i=>rxEmpty_i,
1899
        rxRead_o=>rxRead_o,
1900
        rxType_i=>rxType_i,
1901
        rxData_i=>rxData_i,
1902
        txControlWrite_o=>txControlWrite(i),
1903
        txControlSymbol_o=>txControlSymbol_o(13*(i+1)-1 downto 13*i),
1904
        rxControlWrite_o=>rxControlWrite(i),
1905
        rxControlSymbol_o=>rxControlSymbol_o(13*(i+1)-1 downto 13*i),
1906
        ackIdStatus_o=>ackIdStatus_o,
1907
        linkInitialized_o=>linkInitialized_o,
1908
        enable_o=>enable(i),
1909
        operational_i=>operationalCurrent(i),
1910
        operational_o=>operationalNext(i),
1911
        inputRetryStopped_i=>inputRetryStoppedCurrent(i),
1912
        inputRetryStopped_o=>inputRetryStoppedNext(i),
1913
        inputErrorStopped_i=>inputErrorStoppedCurrent(i),
1914
        inputErrorStopped_o=>inputErrorStoppedNext(i),
1915
        ackId_i=>ackIdCurrent(5*(i+1)-1 downto 5*i),
1916
        ackId_o=>ackIdNext(5*(i+1)-1 downto 5*i),
1917
        frameIndex_i=>frameIndexCurrent(7*(i+1)-1 downto 7*i),
1918
        frameIndex_o=>frameIndexNext(7*(i+1)-1 downto 7*i),
1919
        frameWordCounter_i=>frameWordCounterCurrent(2*(i+1)-1 downto 2*i),
1920
        frameWordCounter_o=>frameWordCounterNext(2*(i+1)-1 downto 2*i),
1921
        frameContent_i=>frameContentCurrent(32*(i+1)-1 downto 32*i),
1922
        frameContent_o=>frameContentNext(32*(i+1)-1 downto 32*i),
1923
        crc_i=>crcCurrent(16*(i+1)-1 downto 16*i),
1924
        crc_o=>crcNext(16*(i+1)-1 downto 16*i),
1925
        writeFrameFull_i=>writeFrameFull_i,
1926
        writeFrame_o=>writeFrame(i),
1927
        writeFrameAbort_o=>writeFrameAbort(i),
1928
        writeContent_o=>writeContent(i),
1929
        writeContentWords_o=>writeContentWords(2*(i+1)-1 downto 2*i),
1930
        writeContentData_o=>writeContentData(32*(i+1)-1 downto 32*i));
1931
  end generate;
1932
 
1933
end architecture;
1934
 
1935
-------------------------------------------------------------------------------
1936
-- RioReceiverCore
1937
-------------------------------------------------------------------------------
1938
library ieee;
1939
use ieee.std_logic_1164.all;
1940
use ieee.numeric_std.all;
1941
use work.rio_common.all;
1942
 
1943
 
1944
-------------------------------------------------------------------------------
1945
-- 
1946
-------------------------------------------------------------------------------
1947
entity RioReceiverCore is
1948
  generic(
1949
    NUMBER_WORDS : natural range 1 to 4 := 1);
1950 4 magro732
  port(
1951
    clk : in std_logic;
1952
    areset_n : in std_logic;
1953
 
1954
    -- Status signals used for maintenance.
1955
    portEnable_i : in std_logic;
1956
 
1957
    -- Support for localAckIdCSR.
1958 11 magro732
    -- REMARK: Add support for this???
1959 4 magro732
    localAckIdWrite_i : in std_logic;
1960
    inboundAckId_i : in std_logic_vector(4 downto 0);
1961
    inboundAckId_o : out std_logic_vector(4 downto 0);
1962
 
1963
    -- Port input interface.
1964
    portInitialized_i : in std_logic;
1965
    rxEmpty_i : in std_logic;
1966
    rxRead_o : out std_logic;
1967 11 magro732
    rxType_i : in std_logic_vector(1 downto 0);
1968 4 magro732
    rxData_i : in std_logic_vector(31 downto 0);
1969
 
1970
    -- Receiver has received a control symbol containing:
1971
    -- packet-accepted, packet-retry, packet-not-accepted, 
1972
    -- status, VC_status, link-response
1973
    txControlWrite_o : out std_logic;
1974
    txControlSymbol_o : out std_logic_vector(12 downto 0);
1975
 
1976
    -- Reciever wants to signal the link partner:
1977
    -- a new frame has been accepted => packet-accepted(rxAckId, bufferStatus)
1978
    -- a frame needs to be retransmitted due to buffering =>
1979
    -- packet-retry(rxAckId, bufferStatus)
1980
    -- a frame is rejected due to errors => packet-not-accepted
1981
    -- a link-request should be answered => link-response
1982
    rxControlWrite_o : out std_logic;
1983
    rxControlSymbol_o : out std_logic_vector(12 downto 0);
1984
 
1985
    -- Status signals used internally.
1986
    ackIdStatus_o : out std_logic_vector(4 downto 0);
1987
    linkInitialized_o : out std_logic;
1988
 
1989 11 magro732
    -- Core->Core cascading signals.
1990
    enable_o : out std_logic;
1991
    operational_i : in std_logic;
1992
    operational_o : out std_logic;
1993
    inputRetryStopped_i : in std_logic;
1994
    inputRetryStopped_o : out std_logic;
1995
    inputErrorStopped_i : in std_logic;
1996
    inputErrorStopped_o : out std_logic;
1997
    ackId_i : in unsigned(4 downto 0);
1998
    ackId_o : out unsigned(4 downto 0);
1999
    frameIndex_i : in std_logic_vector(6 downto 0);
2000
    frameIndex_o : out std_logic_vector(6 downto 0);
2001
    frameWordCounter_i : in std_logic_vector(1 downto 0);
2002
    frameWordCounter_o : out std_logic_vector(1 downto 0);
2003
    frameContent_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0);
2004
    frameContent_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0);
2005
    crc_i : in std_logic_vector(15 downto 0);
2006
    crc_o : out std_logic_vector(15 downto 0);
2007
 
2008 4 magro732
    -- Frame buffering interface.
2009
    writeFrameFull_i : in std_logic;
2010
    writeFrame_o : out std_logic;
2011
    writeFrameAbort_o : out std_logic;
2012
    writeContent_o : out std_logic;
2013 11 magro732
    writeContentWords_o : out std_logic_vector(1 downto 0);
2014
    writeContentData_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0));
2015 4 magro732
end entity;
2016
 
2017
 
2018
-------------------------------------------------------------------------------
2019
-- 
2020
-------------------------------------------------------------------------------
2021 11 magro732
architecture RioReceiverCoreImpl of RioReceiverCore is
2022 4 magro732
 
2023
  component Crc5ITU is
2024
    port(
2025
      d_i : in  std_logic_vector(18 downto 0);
2026
      crc_o : out std_logic_vector(4 downto 0));
2027
  end component;
2028
 
2029
  component Crc16CITT is
2030
    port(
2031
      d_i : in  std_logic_vector(15 downto 0);
2032
      crc_i : in  std_logic_vector(15 downto 0);
2033
      crc_o : out std_logic_vector(15 downto 0));
2034
  end component;
2035
 
2036 11 magro732
  signal symbolEnable0, symbolEnable1 : std_logic;
2037
  signal symbolType0 : std_logic_vector(1 downto 0);
2038
  signal symbolContent0, symbolContent1 : std_logic_vector(31 downto 0);
2039
  signal crc5Valid : std_logic;
2040 4 magro732
  signal crc5 : std_logic_vector(4 downto 0);
2041
 
2042 11 magro732
  signal symbolValid : std_logic;
2043
  signal stype0Status : std_logic;
2044
  signal stype1Start : std_logic;
2045
  signal stype1End : std_logic;
2046
  signal stype1Stomp : std_logic;
2047
  signal stype1Restart : std_logic;
2048
  signal stype1LinkRequest : std_logic;
2049
  signal symbolData : std_logic;
2050
 
2051 4 magro732
  signal crc16Data : std_logic_vector(31 downto 0);
2052
  signal crc16Current : std_logic_vector(15 downto 0);
2053
  signal crc16Temp : std_logic_vector(15 downto 0);
2054
  signal crc16Next : std_logic_vector(15 downto 0);
2055 11 magro732
  signal crc16Valid : std_logic;
2056
 
2057
  signal frameContent : std_logic_vector(32*NUMBER_WORDS-1 downto 0);
2058
 
2059
  signal rxControlWrite : std_logic;
2060
  signal rxControlSymbol : std_logic_vector(12 downto 0);
2061 4 magro732
 
2062
begin
2063
 
2064 11 magro732
  linkInitialized_o <= operational_i;
2065
  ackIdStatus_o <= std_logic_vector(ackId_i);
2066
  inboundAckId_o <= std_logic_vector(ackId_i);
2067
 
2068 4 magro732
  -----------------------------------------------------------------------------
2069 11 magro732
  -- First pipeline stage.
2070
  -- Check the validity of the symbol, CRC5 on control symbols, and save the
2071
  -- symbol content for the next stage.
2072 4 magro732
  -----------------------------------------------------------------------------
2073
 
2074 11 magro732
  -- Read the fifo immediatly.
2075
  rxRead_o <= not rxEmpty_i;
2076 4 magro732
 
2077 11 magro732
  Crc5Calculator: Crc5ITU
2078
    port map(
2079
      d_i=>rxData_i(31 downto 13), crc_o=>crc5);
2080
 
2081
  process(clk, areset_n)
2082
  begin
2083
    if (areset_n = '0') then
2084
      crc5Valid <= '0';
2085
      symbolType0 <= (others => '0');
2086
      symbolContent0 <= (others => '0');
2087
    elsif (clk'event and clk = '1') then
2088
      if (rxEmpty_i = '0') then
2089
        if (crc5 = rxData_i(12 downto 8)) then
2090
          crc5Valid <= '1';
2091
        else
2092
          crc5Valid <= '0';
2093
        end if;
2094
        symbolEnable0 <= '1';
2095
        symbolType0 <= rxType_i;
2096
        symbolContent0 <= rxData_i;
2097
      else
2098
        symbolEnable0 <= '0';
2099
      end if;
2100
    end if;
2101
  end process;
2102
 
2103 4 magro732
  -----------------------------------------------------------------------------
2104 11 magro732
  -- Second pipeline stage.
2105
  -- Separate the part of the control symbol that are going to the transmitter
2106
  -- side and check the type of symbol for this side. 
2107 4 magro732
  -----------------------------------------------------------------------------
2108
 
2109 11 magro732
  process(clk, areset_n)
2110
  begin
2111
    if (areset_n = '0') then
2112
      txControlWrite_o <= '0';
2113
      txControlSymbol_o <= (others => '0');
2114 4 magro732
 
2115 11 magro732
      symbolValid <= '0';
2116
      stype0Status <= '0';
2117
      stype1Start <= '0';
2118
      stype1End <= '0';
2119
      stype1Stomp <= '0';
2120
      stype1Restart <= '0';
2121
      stype1LinkRequest <= '0';
2122
      symbolData <= '0';
2123
 
2124
      symbolContent1 <= (others => '0');
2125
    elsif (clk'event and clk = '1') then
2126
      if (symbolEnable0 = '1') then
2127
        symbolEnable1 <= '1';
2128
        symbolContent1 <= symbolContent0;
2129
 
2130
        if (symbolType0 = SYMBOL_CONTROL) then
2131
          if (crc5Valid = '1') then
2132
            -- REMARK: Check if stype0 is nop and dont forward it???
2133
            symbolValid <= '1';
2134
            txControlWrite_o <= '1';
2135
            txControlSymbol_o <= symbolContent0(31 downto 19);
2136
          else
2137
            symbolValid <= '0';
2138
            txControlWrite_o <= '0';
2139
            txControlSymbol_o <= (others => '0');
2140
          end if;
2141
        else
2142
          symbolValid <= '1';
2143
        end if;
2144
 
2145
        if ((symbolType0 = SYMBOL_CONTROL) and
2146
            (symbolContent0(31 downto 29) = STYPE0_STATUS)) then
2147
          stype0Status <= '1';
2148
        else
2149
          stype0Status <= '0';
2150
        end if;
2151
        if ((symbolType0 = SYMBOL_CONTROL) and
2152
            (symbolContent0(18 downto 16) = STYPE1_START_OF_PACKET)) then
2153
          stype1Start <= '1';
2154
        else
2155
          stype1Start <= '0';
2156
        end if;
2157
        if ((symbolType0 = SYMBOL_CONTROL) and
2158
            (symbolContent0(18 downto 16) = STYPE1_END_OF_PACKET)) then
2159
          stype1End <= '1';
2160
        else
2161
          stype1End <= '0';
2162
        end if;
2163
        if ((symbolType0 = SYMBOL_CONTROL) and
2164
            (symbolContent0(18 downto 16) = STYPE1_STOMP)) then
2165
          stype1Stomp <= '1';
2166
        else
2167
          stype1Stomp <= '0';
2168
        end if;
2169
        if ((symbolType0 = SYMBOL_CONTROL) and
2170
            (symbolContent0(18 downto 16) = STYPE1_RESTART_FROM_RETRY)) then
2171
          stype1Restart <= '1';
2172
        else
2173
          stype1Restart <= '0';
2174
        end if;
2175
        if ((symbolType0 = SYMBOL_CONTROL) and
2176
            (symbolContent0(18 downto 16) = STYPE1_LINK_REQUEST)) then
2177
          stype1LinkRequest <= '1';
2178
        else
2179
          stype1LinkRequest <= '0';
2180
        end if;
2181
        if (symbolType0 = SYMBOL_DATA) then
2182
          symbolData <= '1';
2183
        else
2184
          symbolData <= '0';
2185
        end if;
2186
      else
2187
        symbolEnable1 <= '0';
2188
      end if;
2189
    end if;
2190
  end process;
2191
 
2192 4 magro732
  -----------------------------------------------------------------------------
2193 11 magro732
  -- Third pipeline stage.
2194
  -- Update the CRC16 for the packet.
2195
  -- Update the buffered data and write it to the packet buffer if needed.
2196
  -- Update the main receiver state machine.
2197
  -- Generate reply symbols to the link-partner.
2198
  -- Note that this stage cannot contain any registers as it could be cascaded
2199
  -- to other cores.
2200 4 magro732
  -----------------------------------------------------------------------------
2201 11 magro732
 
2202
  -----------------------------------------------------------------------------
2203
  -- CRC-calculation.
2204
  -- Add a data symbol to the calculated CRC for the packet.
2205
  -- controlSymbol->just forward old crc16.
2206
  -- first data-symbol in packet->crc_o is product of 11111 and the
2207
  -- symbolContent1 without ackid.
2208
  -- not first data-symbol->crc_o is product of crc_i and symbolContent1.
2209
  -----------------------------------------------------------------------------
2210 4 magro732
 
2211 11 magro732
  crc16Data(31 downto 26) <= "000000" when (unsigned(frameIndex_i) = 1) else
2212
                             symbolContent1(31 downto 26);
2213
  crc16Data(25 downto 0) <= symbolContent1(25 downto 0);
2214 4 magro732
 
2215 11 magro732
  crc16Current <= crc_i when (unsigned(frameIndex_i) /= 1) else
2216
                  (others => '1');
2217
 
2218
  Crc16Msb: Crc16CITT
2219 4 magro732
    port map(
2220
      d_i=>crc16Data(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp);
2221 11 magro732
  Crc16Lsb: Crc16CITT
2222 4 magro732
    port map(
2223
      d_i=>crc16Data(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next);
2224
 
2225 11 magro732
  crc_o <= crc_i when (symbolData = '0') else
2226
           crc16Next;
2227
 
2228
  crc16Valid <= '1' when (crc_i = x"0000") else '0';
2229
 
2230 4 magro732
  -----------------------------------------------------------------------------
2231 11 magro732
  -- Update buffered data.
2232 4 magro732
  -----------------------------------------------------------------------------
2233
 
2234 11 magro732
  -- Append the new symbol content to the end of the
2235
  -- current frame content if the symbol is a data symbol.
2236
  frameContentSingle:
2237
  if (NUMBER_WORDS = 1) generate
2238
    frameContent <= symbolContent1;
2239
  end generate;
2240
  frameContentMulti:
2241
  if (NUMBER_WORDS > 1) generate
2242
    frameContent <=
2243
      (frameContent_i((32*(NUMBER_WORDS-1))-1 downto 0) & symbolContent1) when (symbolData = '1') else
2244
      frameContent_i;
2245
  end generate;
2246 4 magro732
 
2247 11 magro732
  -- Update outputs.
2248
  enable_o <= symbolEnable1;
2249
  frameContent_o <= frameContent;
2250
  writeContentData_o <= frameContent;
2251 4 magro732
 
2252 11 magro732
  -----------------------------------------------------------------------------
2253
  -- Main inbound symbol handler.
2254
  -----------------------------------------------------------------------------
2255
  process(portInitialized_i, portEnable_i, writeFrameFull_i,
2256
          operational_i, ackId_i, frameIndex_i, frameWordCounter_i,
2257
          inputRetryStopped_i, inputErrorStopped_i,
2258
          symbolValid,
2259
          stype0Status,
2260
          stype1Start, stype1End, stype1Stomp, stype1Restart, stype1LinkRequest,
2261
          symbolData,
2262
          symbolContent1,
2263
          frameContent,
2264
          crc16Valid)
2265
  begin
2266
    operational_o <= operational_i;
2267
    ackId_o <= ackId_i;
2268
    frameIndex_o <= frameIndex_i;
2269
    frameWordCounter_o <= frameWordCounter_i;
2270
    inputRetryStopped_o <= inputRetryStopped_i;
2271
    inputErrorStopped_o <= inputErrorStopped_i;
2272
 
2273
    rxControlWrite <= '0';
2274
    rxControlSymbol <= (others => '0');
2275
 
2276
    writeFrame_o <= '0';
2277
    writeFrameAbort_o <= '0';
2278
    writeContent_o <= '0';
2279
    writeContentWords_o <= (others => '0');
2280 4 magro732
 
2281 11 magro732
    -- Act on the current state.
2282
    if (operational_i = '0') then
2283
      ---------------------------------------------------------------------
2284
      -- The port is not operational and is waiting for status control
2285
      -- symbols to be received on the link. Count the number
2286
      -- of error-free status symbols and considder the link operational
2287
      -- when enough of them has been received. Frames are not allowed
2288
      -- here.
2289
      ---------------------------------------------------------------------
2290
 
2291
      -- Check if the port is initialized.
2292
      if (portInitialized_i = '1') then
2293
        -- Port is initialized.
2294
 
2295
        -- Check if the control symbol has a valid checksum.
2296
        if (symbolValid = '1') then
2297
          -- The control symbol has a valid checksum.
2298 4 magro732
 
2299 11 magro732
          -- Check the stype0 part if we should count the number of
2300
          -- error-free status symbols.
2301
          if (stype0Status = '1') then
2302
            -- The symbol is a status.
2303 4 magro732
 
2304 11 magro732
            -- Check if enough status symbols have been received.
2305
            if (unsigned(frameIndex_i) = 7) then
2306
              -- Enough status symbols have been received.
2307 4 magro732
 
2308 11 magro732
              -- Reset all packets.
2309
              frameIndex_o <= (others => '0');
2310
              writeFrameAbort_o <= '1';
2311
 
2312
              -- Set the link as initialized.
2313
              operational_o <= '1';
2314 4 magro732
            else
2315 11 magro732
              -- Increase the number of error-free status symbols that
2316
              -- has been received.
2317
              frameIndex_o <= std_logic_vector(unsigned(frameIndex_i) + 1);
2318 4 magro732
            end if;
2319 11 magro732
          else
2320
            -- The symbol is not a status.
2321
            -- Dont do anything.
2322
          end if;
2323
        else
2324
          -- A control symbol with CRC5 error was recevied.
2325
          frameIndex_o <= (others => '0');
2326
        end if;
2327
      else
2328
        -- The port has become uninitialized.
2329
        frameIndex_o <= (others => '0');
2330
      end if;
2331
    else
2332
      ---------------------------------------------------------------------
2333
      -- The port has been initialized and enough error free status symbols
2334
      -- have been received. Forward data frames to the frame buffer
2335
      -- interface. This is the normal operational state.
2336
      ---------------------------------------------------------------------
2337
 
2338
      -- Check that the port is initialized.
2339
      if (portInitialized_i = '1') then
2340
        -- The port and link is initialized.
2341
 
2342
        -- Check if the control symbol has a valid CRC-5.
2343
        if (symbolValid = '1') then
2344
          -- The symbol is correct.
2345 4 magro732
 
2346 11 magro732
          if ((stype1Start = '1') and
2347
              (inputRetryStopped_i = '0') and (inputErrorStopped_i = '0')) then
2348
            -------------------------------------------------------------
2349
            -- Start the reception of a new frame or end a currently
2350
            -- ongoing frame and start a new one.
2351
            -------------------------------------------------------------
2352 4 magro732
 
2353 11 magro732
            -- Check if a frame has already been started.
2354
            if (unsigned(frameIndex_i) /= 0) then
2355
              -- A frame is already started.
2356
              -- Complete the last frame and start to ackumulate a new one
2357
              -- and update the ackId.
2358 4 magro732
 
2359 11 magro732
              if (unsigned(frameIndex_i) > 3) then
2360 4 magro732
 
2361 11 magro732
                -- Reset the frame index to indicate the frame is started.
2362
                frameIndex_o <= "0000001";
2363
                frameWordCounter_o <= (others=>'0');
2364
 
2365
                -- Check the CRC-16 and the length of the received frame.
2366
                if (crc16Valid = '1') then
2367
                  -- The CRC-16 is ok.
2368
 
2369
                  -- Check if there are any unwritten buffered packet content
2370
                  -- and write it if there is.
2371
                  -- REMARK: Multi-symbol support...
2372
                  if (unsigned(frameWordCounter_i) /= 0) then
2373
                    writeContent_o <= '1';
2374
                  end if;
2375 4 magro732
 
2376 11 magro732
                  -- Update the frame buffer to indicate that the frame has
2377
                  -- been completly received.
2378
                  writeFrame_o <= '1';
2379 4 magro732
 
2380 11 magro732
                  -- Update ackId.
2381
                  ackId_o <= ackId_i + 1;
2382 4 magro732
 
2383 11 magro732
                  -- Send packet-accepted.
2384
                  -- The buffer status is appended by the transmitter
2385
                  -- when sent to get the latest number.
2386
                  rxControlWrite <= '1';
2387
                  rxControlSymbol <= STYPE0_PACKET_ACCEPTED &
2388
                                     std_logic_vector(ackId_i) &
2389
                                     "11111";
2390
                else
2391
                  -- The CRC-16 is not ok.
2392 4 magro732
 
2393 11 magro732
                  -- Make the transmitter send a packet-not-accepted to indicate
2394
                  -- that the received packet contained a CRC error.
2395
                  rxControlWrite <= '1';
2396
                  rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
2397
                                     "00000" &
2398
                                     PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
2399
                  inputErrorStopped_o <= '1';
2400 4 magro732
                end if;
2401
              else
2402 11 magro732
                -- This packet is too small.
2403
                -- Make the transmitter send a packet-not-accepted to indicated
2404
                -- that the received packet was too small.
2405
                rxControlWrite <= '1';
2406
                rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
2407
                                   "00000" &
2408
                                   PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR;
2409
                inputErrorStopped_o <= '1';
2410 4 magro732
              end if;
2411
            else
2412 11 magro732
              -- No frame has been started.
2413
 
2414
              -- Reset the frame index to indicate the frame is started.
2415
              frameIndex_o <= "0000001";
2416
              frameWordCounter_o <= (others=>'0');
2417 4 magro732
            end if;
2418 11 magro732
          end if;
2419
 
2420
          if ((stype1End = '1') and
2421
              (inputRetryStopped_i = '0') and (inputErrorStopped_i = '0')) then
2422
            -------------------------------------------------------------
2423
            -- End the reception of an old frame.
2424
            -------------------------------------------------------------
2425 4 magro732
 
2426 11 magro732
            -- Check if a frame has already been started.
2427
            if (unsigned(frameIndex_i) > 3) then
2428
              -- A frame has been started and it is large enough.
2429 4 magro732
 
2430 11 magro732
              -- Reset frame reception to indicate that no frame is ongoing.
2431
              frameIndex_o <= (others => '0');
2432
 
2433
              -- Check the CRC-16 and the length of the received frame.
2434
              if (crc16Valid = '1') then
2435
                -- The CRC-16 is ok.
2436 4 magro732
 
2437 11 magro732
                -- Check if there are any unwritten buffered packet content
2438
                -- and write it if there is.
2439
                -- REMARK: Multi-symbol support...
2440
                if (unsigned(frameWordCounter_i) /= 0) then
2441
                  writeContent_o <= '1';
2442
                end if;
2443 4 magro732
 
2444 11 magro732
                -- Update the frame buffer to indicate that the frame has
2445
                -- been completly received.
2446
                writeFrame_o <= '1';
2447 4 magro732
 
2448 11 magro732
                -- Update ackId.
2449
                ackId_o <= ackId_i + 1;
2450 4 magro732
 
2451 11 magro732
                -- Send packet-accepted.
2452
                -- The buffer status is appended by the transmitter
2453
                -- when sent to get the latest number.
2454
                rxControlWrite <= '1';
2455
                rxControlSymbol <= STYPE0_PACKET_ACCEPTED &
2456
                                   std_logic_vector(ackId_i) &
2457
                                   "11111";
2458
              else
2459
                -- The CRC-16 is not ok.
2460 4 magro732
 
2461 11 magro732
                -- Make the transmitter send a packet-not-accepted to indicate
2462
                -- that the received packet contained a CRC error.
2463
                rxControlWrite <= '1';
2464
                rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
2465
                                   "00000" &
2466
                                   PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
2467
                inputErrorStopped_o <= '1';
2468 4 magro732
              end if;
2469
            else
2470 11 magro732
              -- This packet is too small.
2471
              -- Make the transmitter send a packet-not-accepted to indicate
2472
              -- that the received packet was too small.
2473
              rxControlWrite <= '1';
2474
              rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
2475
                                 "00000" &
2476
                                 PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR;
2477
              inputErrorStopped_o <= '1';
2478 4 magro732
            end if;
2479 11 magro732
          end if;
2480 4 magro732
 
2481 11 magro732
          if ((stype1Stomp = '1') and
2482
              (inputRetryStopped_i = '0') and (inputErrorStopped_i = '0')) then
2483
            -------------------------------------------------------------
2484
            -- Restart the reception of an old frame.
2485
            -------------------------------------------------------------
2486
            -- See 5.10 in the standard.
2487 4 magro732
 
2488 11 magro732
            -- Make the transmitter send a packet-retry to indicate
2489
            -- that the packet cannot be accepted.
2490
            rxControlWrite <= '1';
2491
            rxControlSymbol <= STYPE0_PACKET_RETRY &
2492
                               std_logic_vector(ackId_i) &
2493
                               "11111";
2494
 
2495
            -- Enter the input retry-stopped state.
2496
            inputRetryStopped_o <= '1';
2497
          end if;
2498 4 magro732
 
2499 11 magro732
          if (stype1Restart = '1') then
2500
            if (inputRetryStopped_i = '1') then
2501
              -------------------------------------------------------------
2502
              -- The receiver indicates a restart from a retry sent
2503
              -- from us.
2504
              -------------------------------------------------------------
2505 4 magro732
 
2506 11 magro732
              -- Abort the frame and reset frame reception.
2507
              frameIndex_o <= (others => '0');
2508
              writeFrameAbort_o <= '1';
2509
 
2510
              -- Go back to the normal operational state.
2511
              inputRetryStopped_o <= '0';
2512
            else
2513
              -------------------------------------------------------------
2514
              -- The receiver indicates a restart from a retry sent
2515
              -- from us.
2516
              -------------------------------------------------------------
2517
              -- See 5.10 in the standard.
2518
              -- Protocol error, this symbol should not be received here since
2519
              -- we should have been in input-retry-stopped. 
2520
 
2521
              -- Send a packet-not-accepted to indicate that a protocol
2522
              -- error has occurred.
2523
              rxControlWrite <= '1';
2524
              rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
2525
                                 "00000" &
2526
                                 PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR;
2527
              inputErrorStopped_o <= '1';
2528
            end if;
2529
          end if;
2530 4 magro732
 
2531 11 magro732
          if (stype1LinkRequest = '1') then
2532
            -------------------------------------------------------------
2533
            -- Reply to a LINK-REQUEST.
2534
            -------------------------------------------------------------
2535
 
2536
            -- Check the command part.
2537
            if (symbolContent1(15 downto 13) = "100") then
2538
              -- Return input port status command.
2539
              -- This functions as a link-request(restart-from-error)
2540
              -- control symbol under error situations.
2541 4 magro732
 
2542 11 magro732
              if (inputErrorStopped_i = '1') then
2543
                rxControlWrite <= '1';
2544
                rxControlSymbol <= STYPE0_LINK_RESPONSE &
2545
                                   std_logic_vector(ackId_i) &
2546
                                   "00101";
2547
              elsif (inputRetryStopped_i = '1') then
2548
                rxControlWrite <= '1';
2549
                rxControlSymbol <= STYPE0_LINK_RESPONSE &
2550
                                   std_logic_vector(ackId_i) &
2551
                                   "00100";
2552 4 magro732
              else
2553 11 magro732
                -- Send a link response containing an ok reply.
2554
                rxControlWrite <= '1';
2555
                rxControlSymbol <= STYPE0_LINK_RESPONSE &
2556
                                   std_logic_vector(ackId_i) &
2557
                                   "10000";
2558 4 magro732
              end if;
2559
            else
2560 11 magro732
              -- Reset device command or other unsupported command.
2561
              -- Discard this.
2562 4 magro732
            end if;
2563
 
2564 11 magro732
            -- Abort the frame and reset frame reception.
2565
            inputRetryStopped_o <= '0';
2566
            inputErrorStopped_o <= '0';
2567
            frameIndex_o <= (others=>'0');
2568
            writeFrameAbort_o <= '1';
2569
          end if;
2570 4 magro732
 
2571 11 magro732
          if ((symbolData = '1')  and
2572
              (inputRetryStopped_i = '0') and (inputErrorStopped_i = '0')) then
2573
            -------------------------------------------------------------
2574
            -- This is a data symbol.
2575
            -------------------------------------------------------------
2576
            -- REMARK: Add check for in-the-middle-crc here...
2577 4 magro732
 
2578 11 magro732
            case frameIndex_i is
2579
              when "0000000" | "1000110" =>
2580
                -- A frame has not been started or is too long.
2581
                -- Send packet-not-accepted.
2582
                rxControlWrite <= '1';
2583
                rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
2584
                                   "00000" &
2585
                                   PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR;
2586
                inputErrorStopped_o <= '1';
2587
              when "0000001" =>
2588
                if (unsigned(symbolContent1(31 downto 27)) = ackId_i) then
2589
                  if ((portEnable_i = '1') or
2590
                      (symbolContent1(19 downto 16) = FTYPE_MAINTENANCE_CLASS)) then
2591
 
2592
                    -- Check if there are buffers available to store the new
2593
                    -- packet.
2594
                    if (writeFrameFull_i = '0') then
2595
                      -- There are buffering space available to store the new
2596
                      -- data.
2597
 
2598
                      -- Check if the buffer entry is ready to be written
2599
                      -- into the packet buffer.
2600
                      -- REMARK: Multi-symbol support...
2601
                      if (unsigned(frameWordCounter_i) = (NUMBER_WORDS-1)) then
2602
                        -- Write the data to the frame FIFO.
2603
                        frameWordCounter_o <= (others=>'0');
2604
                        writeContent_o <= '1';
2605
                        writeContentWords_o <= frameWordCounter_i;
2606
                      else
2607
                        frameWordCounter_o <= std_logic_vector(unsigned(frameWordCounter_i) + 1);
2608
                      end if;
2609 4 magro732
 
2610 11 magro732
                      -- Increment the number of received data symbols.
2611
                      frameIndex_o <= std_logic_vector(unsigned(frameIndex_i) + 1);
2612
                    else
2613
                      -- The packet buffer is full.
2614
                      -- Let the link-partner resend the packet.
2615
                      rxControlWrite <= '1';
2616
                      rxControlSymbol <= STYPE0_PACKET_RETRY &
2617
                                         std_logic_vector(ackId_i) &
2618
                                         "11111";
2619
                      inputRetryStopped_o <= '1';
2620
                    end if;
2621 4 magro732
                  else
2622 11 magro732
                    -- A non-maintenance packets are not allowed.
2623
                    -- Send packet-not-accepted.
2624
                    rxControlWrite <= '1';
2625
                    rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
2626
                                       "00000" &
2627
                                       PACKET_NOT_ACCEPTED_CAUSE_NON_MAINTENANCE_STOPPED;
2628
                    inputErrorStopped_o <= '1';
2629 4 magro732
                  end if;
2630
                else
2631 11 magro732
                  -- The ackId is unexpected.
2632
                  -- Send packet-not-accepted.
2633
                  rxControlWrite <= '1';
2634
                  rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
2635
                                     "00000" &
2636
                                     PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID;
2637
                  inputErrorStopped_o <= '1';
2638 4 magro732
                end if;
2639 11 magro732
              when others =>
2640
                -- A frame has been started and is not too long.
2641
                -- Check if the buffer entry is ready to be written
2642
                -- into the packet buffer.
2643
                -- REMARK: Multi-symbol support...
2644
                if (unsigned(frameWordCounter_i) = (NUMBER_WORDS-1)) then
2645
                  -- Write the data to the frame FIFO.
2646
                  frameWordCounter_o <= (others=>'0');
2647
                  writeContent_o <= '1';
2648
                  writeContentWords_o <= frameWordCounter_i;
2649
                else
2650
                  frameWordCounter_o <= std_logic_vector(unsigned(frameWordCounter_i) + 1);
2651
                end if;
2652 4 magro732
 
2653 11 magro732
                -- Increment the number of received data symbols.
2654
                frameIndex_o <= std_logic_vector(unsigned(frameIndex_i) + 1);
2655
            end case;
2656
          end if;
2657
        else
2658
          -- A control symbol contains a crc error.
2659 4 magro732
 
2660 11 magro732
          -- Send a packet-not-accepted to indicate that a corrupted
2661
          -- control-symbol has been received and change state.
2662
          rxControlWrite <= '1';
2663
          rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
2664
                             "00000" &
2665
                             PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC;
2666
          inputErrorStopped_o <= '1';
2667
        end if;
2668
      else
2669
        -- The port has become uninitialized.
2670
        -- Go back to the uninitialized state.
2671
        operational_o <= '0';
2672 4 magro732
      end if;
2673
    end if;
2674
  end process;
2675
 
2676 11 magro732
  -----------------------------------------------------------------------------
2677
  -- Fourth pipeline stage.
2678
  -----------------------------------------------------------------------------
2679
  -- REMARK: Do more stuff in this stage, convert a one-hot to the symbol to
2680
  -- send...
2681
  -- REMARK: Register other outputs here like writeContent_o...
2682
 
2683
  process(clk, areset_n)
2684
  begin
2685
    if (areset_n = '0') then
2686
      rxControlWrite_o <= '0';
2687
      rxControlSymbol_o <= (others=>'0');
2688
    elsif (clk'event and clk = '1') then
2689
      rxControlWrite_o <= rxControlWrite and symbolEnable1;
2690
      rxControlSymbol_o <= rxControlSymbol;
2691
    end if;
2692
  end process;
2693
 
2694 4 magro732
end architecture;
2695
 
2696
 
2697
 
2698
-------------------------------------------------------------------------------
2699
--
2700
---------------------------------------------------------------------------------
2701
library ieee;
2702
use ieee.std_logic_1164.all;
2703
 
2704
 
2705
-------------------------------------------------------------------------------
2706
-- 
2707
-------------------------------------------------------------------------------
2708
entity RioFifo1 is
2709
  generic(
2710
    WIDTH : natural);
2711
  port(
2712
    clk : in std_logic;
2713
    areset_n : in std_logic;
2714
 
2715
    empty_o : out std_logic;
2716
    read_i : in std_logic;
2717
    data_o : out std_logic_vector(WIDTH-1 downto 0);
2718
 
2719
    full_o : out std_logic;
2720
    write_i : in std_logic;
2721
    data_i : in std_logic_vector(WIDTH-1 downto 0));
2722
end entity;
2723
 
2724
 
2725
-------------------------------------------------------------------------------
2726
-- 
2727
-------------------------------------------------------------------------------
2728
architecture RioFifo1Impl of RioFifo1 is
2729
  signal empty : std_logic;
2730
  signal full : std_logic;
2731
begin
2732
 
2733
  empty_o <= empty;
2734
  full_o <= full;
2735
 
2736
  process(areset_n, clk)
2737
  begin
2738
    if (areset_n = '0') then
2739
      empty <= '1';
2740
      full <= '0';
2741
      data_o <= (others => '0');
2742
    elsif (clk'event and clk = '1') then
2743
      if (empty = '1') then
2744
        if (write_i = '1') then
2745
          empty <= '0';
2746
          full <= '1';
2747
          data_o <= data_i;
2748
        end if;
2749
      else
2750
        if (read_i = '1') then
2751
          empty <= '1';
2752
          full <= '0';
2753
        end if;
2754
      end if;
2755
    end if;
2756
  end process;
2757
 
2758
end architecture;
2759
 
2760
 
2761
 
2762
-------------------------------------------------------------------------------
2763
-- A CRC-5 calculator following the implementation proposed in the 2.2
2764
-- standard.
2765
-------------------------------------------------------------------------------
2766
library ieee;
2767
use ieee.std_logic_1164.all;
2768
 
2769
 
2770
-------------------------------------------------------------------------------
2771
-- 
2772
-------------------------------------------------------------------------------
2773
entity Crc5ITU is
2774
  port(
2775
    d_i : in  std_logic_vector(18 downto 0);
2776
    crc_o : out std_logic_vector(4 downto 0));
2777
end entity;
2778
 
2779
 
2780
-------------------------------------------------------------------------------
2781
-- 
2782
-------------------------------------------------------------------------------
2783
architecture Crc5Impl of Crc5ITU is
2784
  signal d : std_logic_vector(0 to 18);
2785
  signal c : std_logic_vector(0 to 4);
2786
 
2787
begin
2788
  -- Reverse the bit vector indexes to make them the same as in the standard.
2789
  d(18) <= d_i(0); d(17) <= d_i(1); d(16) <= d_i(2); d(15) <= d_i(3);
2790
  d(14) <= d_i(4); d(13) <= d_i(5); d(12) <= d_i(6); d(11) <= d_i(7);
2791
  d(10) <= d_i(8); d(9) <= d_i(9); d(8) <= d_i(10); d(7) <= d_i(11);
2792
  d(6) <= d_i(12); d(5) <= d_i(13); d(4) <= d_i(14); d(3) <= d_i(15);
2793
  d(2) <= d_i(16); d(1) <= d_i(17); d(0) <= d_i(18);
2794
 
2795
  -- Calculate the resulting crc.
2796
  c(0) <= d(18) xor d(16) xor d(15) xor d(12) xor
2797
          d(10) xor d(5) xor d(4) xor d(3) xor
2798
          d(1) xor d(0);
2799
  c(1) <= (not d(18)) xor d(17) xor d(15) xor d(13) xor
2800
          d(12) xor d(11) xor d(10) xor d(6) xor
2801
          d(3) xor d(2) xor d(0);
2802
  c(2) <= (not d(18)) xor d(16) xor d(14) xor d(13) xor
2803
          d(12) xor d(11) xor d(7) xor d(4) xor
2804
          d(3) xor d(1);
2805
  c(3) <= (not d(18)) xor d(17) xor d(16) xor d(14) xor
2806
          d(13) xor d(10) xor d(8) xor d(3) xor
2807
          d(2) xor d(1);
2808
  c(4) <= d(18) xor d(17) xor d(15) xor d(14) xor
2809
          d(11) xor d(9) xor d(4) xor d(3) xor
2810
          d(2) xor d(0);
2811
 
2812
  -- Reverse the bit vector indexes to make them the same as in the standard.
2813
  crc_o(4) <= c(0); crc_o(3) <= c(1); crc_o(2) <= c(2); crc_o(1) <= c(3);
2814
  crc_o(0) <= c(4);
2815
end architecture;
2816 11 magro732
 
2817
 
2818
-------------------------------------------------------------------------------
2819
-- 
2820
-------------------------------------------------------------------------------
2821
library ieee;
2822
use ieee.std_logic_1164.all;
2823
use ieee.numeric_std.all;
2824
use work.rio_common.all;
2825
 
2826
-------------------------------------------------------------------------------
2827
-- 
2828
-------------------------------------------------------------------------------
2829
entity Crc16Calculator is
2830
 
2831
  generic (
2832
    NUMBER_WORDS : natural range 1 to 8 := 1);
2833
 
2834
  port (
2835
    clk : in std_logic;
2836
    areset_n : in std_logic;
2837
 
2838
    write_i : in std_logic;
2839
    crc_i : in std_logic_vector(15 downto 0);
2840
    data_i : in std_logic_vector((32*NUMBER_WORDS)-1 downto 0);
2841
 
2842
    crc_o : out std_logic_vector(15 downto 0);
2843
    done_o : out std_logic);
2844
 
2845
end Crc16Calculator;
2846
 
2847
-------------------------------------------------------------------------------
2848
-- 
2849
-------------------------------------------------------------------------------
2850
architecture Crc16CalculatorImpl of Crc16Calculator is
2851
 
2852
  component Crc16CITT is
2853
    port(
2854
      d_i : in  std_logic_vector(15 downto 0);
2855
      crc_i : in  std_logic_vector(15 downto 0);
2856
      crc_o : out std_logic_vector(15 downto 0));
2857
  end component;
2858
 
2859
  signal iterator : natural range 0 to 2*NUMBER_WORDS;
2860
  signal crcData : std_logic_vector((32*NUMBER_WORDS)-1 downto 0);
2861
  signal crcCurrent : std_logic_vector(15 downto 0);
2862
  signal crcNext : std_logic_vector(15 downto 0);
2863
 
2864
begin
2865
 
2866
  process(areset_n, clk)
2867
  begin
2868
    if (areset_n = '0') then
2869
      iterator <= 0;
2870
      done_o <= '0';
2871
      crc_o <= (others => '0');
2872
    elsif (clk'event and clk = '1') then
2873
      if (write_i = '1') then
2874
        iterator <= 2*NUMBER_WORDS-1;
2875
        crcData <= data_i;
2876
        crcCurrent <= crc_i;
2877
        done_o <= '0';
2878
      else
2879
        if (iterator /= 0) then
2880
          iterator <= iterator - 1;
2881
          crcData <= crcData(((32*NUMBER_WORDS)-1)-16 downto 0) & x"0000";
2882
          crcCurrent <= crcNext;
2883
        else
2884
          crc_o <= crcNext;
2885
          done_o <= '1';
2886
        end if;
2887
      end if;
2888
    end if;
2889
  end process;
2890
 
2891
  Crc16Inst: Crc16CITT
2892
    port map(
2893
      d_i=>crcData((32*NUMBER_WORDS)-1 downto (32*NUMBER_WORDS)-16),
2894
      crc_i=>crcCurrent, crc_o=>crcNext);
2895
 
2896
end architecture;
2897
 

powered by: WebSVN 2.1.0

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