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

Subversion Repositories rio

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

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

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

powered by: WebSVN 2.1.0

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