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

Subversion Repositories rio

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

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

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

powered by: WebSVN 2.1.0

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