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

Subversion Repositories rio

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

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

powered by: WebSVN 2.1.0

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