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 37

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

powered by: WebSVN 2.1.0

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