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

Subversion Repositories rio

[/] [rio/] [branches/] [2.0.0-development/] [rtl/] [vhdl/] [RioSerial.vhd] - Blame information for rev 48

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

powered by: WebSVN 2.1.0

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