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

Subversion Repositories rio

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

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

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

powered by: WebSVN 2.1.0

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