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

Subversion Repositories rio

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

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

powered by: WebSVN 2.1.0

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