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

Subversion Repositories rio

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 34 to Rev 35
    Reverse comparison

Rev 34 → Rev 35

/rio/branches/singleSymbol/rtl/vhdl/RioSerial.vhd
49,11 → 49,6
-- Generics
-- --------
-- TIMEOUT_WIDTH - The number of bits to be used in the portLinkTimeout signal.
-- NUMBER_WORDS - The number of parallell words that the data symbols can
-- contain. This sizes the data buses. It can be used to increase the bandwidth
-- of the core. Note that it cannot be larger than 4. This is since two
-- packets may be completed at the same tick and the interface to the
-- packetBuffer cannot handle more than one packets in one tick.
--
-- Signals
-- -------
179,6 → 174,13
-------------------------------------------------------------------------------
-- REMARK: Remove multi-symbol support to make the code more readable...
-- REMARK: Make more signals synchronous...
-- REMARK: Add support for the change of ackIds...
-- REMARK: Update all comments...
-- REMARK: Make sure that RioPacketBuffer can handle simultanous accesses at
-- the window-pins and the normal-pins... Add another singlememory...
-- REMARK: Make the pipe-line stages into block-statements to make the code more readable...
-- REMARK: Be consistent, tx->outbound and rx->inbound or egress/ingress...
-- REMARK: Add enable to fifo:s...
 
library ieee;
use ieee.std_logic_1164.all;
191,11 → 193,15
-------------------------------------------------------------------------------
entity RioSerial is
generic(
TIMEOUT_WIDTH : natural := 20);
TIMEOUT_WIDTH : natural := 20;
SYMBOL_COUNTER_WIDTH : natural := 8;
TICKS_SEND_STATUS_STARTUP : natural := 15;
TICKS_SEND_STATUS_OPERATIONAL : natural := 255);
port(
-- System signals.
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
-- Status signals for maintenance operations.
portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
235,12 → 241,14
 
-- PCS layer signals.
portInitialized_i : in std_logic;
outboundSymbolFull_i : in std_logic;
outboundSymbolWrite_o : out std_logic;
outboundSymbol_o : out std_logic_vector(((2+32)-1) downto 0);
inboundSymbolEmpty_i : in std_logic;
inboundSymbolRead_o : out std_logic;
inboundSymbol_i : in std_logic_vector(((2+32)-1) downto 0));
outboundControlValid_o : out std_logic;
outboundControlSymbol_o : out std_logic_vector(23 downto 0);
outboundDataValid_o : out std_logic;
outboundDataSymbol_o : out std_logic_vector(31 downto 0);
inboundControlValid_i : in std_logic;
inboundControlSymbol_i : in std_logic_vector(23 downto 0);
inboundDataValid_i : in std_logic;
inboundDataSymbol_i : in std_logic_vector(31 downto 0));
end entity;
 
 
268,14 → 276,18
component RioTransmitter is
generic(
TIMEOUT_WIDTH : natural;
NUMBER_WORDS : natural range 1 to 4 := 1);
NUMBER_SYMBOLS : natural range 1 to 1 := 1;
SYMBOL_COUNTER_WIDTH : natural;
TICKS_SEND_STATUS_STARTUP : natural;
TICKS_SEND_STATUS_OPERATIONAL : natural);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
portEnable_i : in std_logic;
 
localAckIdWrite_i : in std_logic;
clrOutstandingAckId_i : in std_logic;
outstandingAckId_i : in std_logic_vector(4 downto 0);
282,22 → 294,23
outboundAckId_i : in std_logic_vector(4 downto 0);
outstandingAckId_o : out std_logic_vector(4 downto 0);
outboundAckId_o : out std_logic_vector(4 downto 0);
portInitialized_i : in std_logic;
txFull_i : in std_logic;
txWrite_o : out std_logic;
txType_o : out std_logic_vector(2*NUMBER_WORDS-1 downto 0);
txData_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0);
txControlValid_o : out std_logic;
txControlSymbol_o : out std_logic_vector(23 downto 0);
txDataValid_o : out std_logic;
txDataSymbol_o : out std_logic_vector(31 downto 0);
 
txControlEmpty_i : in std_logic_vector(NUMBER_WORDS-1 downto 0);
txControlSymbol_i : in std_logic_vector(12*NUMBER_WORDS downto 0);
txControlUpdate_o : out std_logic_vector(NUMBER_WORDS-1 downto 0);
rxControlEmpty_i : in std_logic_vector(NUMBER_WORDS-1 downto 0);
rxControlSymbol_i : in std_logic_vector(12*NUMBER_WORDS downto 0);
rxControlUpdate_o : out std_logic_vector(NUMBER_WORDS-1 downto 0);
txControlEmpty_i : in std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
txControlSymbol_i : in std_logic_vector(12*NUMBER_SYMBOLS downto 0);
txControlUpdate_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
 
rxControlEmpty_i : in std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
rxControlSymbol_i : in std_logic_vector(12*NUMBER_SYMBOLS downto 0);
rxControlUpdate_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
 
linkInitialized_o : out std_logic;
linkInitialized_i : in std_logic;
linkInitialized_o : out std_logic;
ackIdStatus_i : in std_logic_vector(4 downto 0);
 
readFrameEmpty_i : in std_logic;
310,13 → 323,12
readContentEmpty_i : in std_logic;
readContent_o : out std_logic;
readContentEnd_i : in std_logic;
readContentWords_i : in std_logic_vector(1 downto 0);
readContentData_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0));
readContentData_i : in std_logic_vector(32*NUMBER_SYMBOLS-1 downto 0));
end component;
 
component RioReceiver is
generic(
NUMBER_WORDS : natural range 1 to 4 := 1);
NUMBER_SYMBOLS : natural range 1 to 1 := 1);
port(
clk : in std_logic;
areset_n : in std_logic;
328,15 → 340,15
inboundAckId_o : out std_logic_vector(4 downto 0);
portInitialized_i : in std_logic;
rxEmpty_i : in std_logic;
rxRead_o : out std_logic;
rxType_i : in std_logic_vector(2*NUMBER_WORDS-1 downto 0);
rxData_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0);
rxControlValid_i : in std_logic;
rxControlSymbol_i : in std_logic_vector(23 downto 0);
rxDataValid_i : in std_logic;
rxDataSymbol_i : in std_logic_vector(31 downto 0);
 
txControlWrite_o : out std_logic_vector(NUMBER_WORDS-1 downto 0);
txControlSymbol_o : out std_logic_vector(12*NUMBER_WORDS downto 0);
rxControlWrite_o : out std_logic_vector(NUMBER_WORDS-1 downto 0);
rxControlSymbol_o : out std_logic_vector(12*NUMBER_WORDS downto 0);
txControlWrite_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
txControlSymbol_o : out std_logic_vector(12*NUMBER_SYMBOLS downto 0);
rxControlWrite_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
rxControlSymbol_o : out std_logic_vector(12*NUMBER_SYMBOLS downto 0);
 
ackIdStatus_o : out std_logic_vector(4 downto 0);
linkInitialized_o : out std_logic;
345,34 → 357,27
writeFrame_o : out std_logic;
writeFrameAbort_o : out std_logic;
writeContent_o : out std_logic;
writeContentWords_o : out std_logic_vector(1 downto 0);
writeContentData_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0));
writeContentData_o : out std_logic_vector(32*NUMBER_SYMBOLS-1 downto 0));
end component;
 
constant NUMBER_WORDS : natural := 1;
constant NUMBER_SYMBOLS : natural := 1;
signal linkInitializedRx : std_logic;
signal linkInitializedTx : std_logic;
signal ackIdStatus : std_logic_vector(4 downto 0);
signal txControlWrite : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal txControlWriteSymbol : std_logic_vector(12*NUMBER_WORDS downto 0);
signal txControlReadEmpty : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal txControlRead : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal txControlReadSymbol : std_logic_vector(12*NUMBER_WORDS downto 0);
signal txControlWrite : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal txControlWriteSymbol : std_logic_vector(12*NUMBER_SYMBOLS downto 0);
signal txControlReadEmpty : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal txControlRead : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal txControlReadSymbol : std_logic_vector(12*NUMBER_SYMBOLS downto 0);
 
signal rxControlWrite : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal rxControlWriteSymbol : std_logic_vector(12*NUMBER_WORDS downto 0);
signal rxControlReadEmpty : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal rxControlRead : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal rxControlReadSymbol : std_logic_vector(12*NUMBER_WORDS downto 0);
signal rxControlWrite : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal rxControlWriteSymbol : std_logic_vector(12*NUMBER_SYMBOLS downto 0);
signal rxControlReadEmpty : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal rxControlRead : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal rxControlReadSymbol : std_logic_vector(12*NUMBER_SYMBOLS downto 0);
 
signal outboundType : std_logic_vector(1 downto 0);
signal outboundData : std_logic_vector(32*NUMBER_WORDS-1 downto 0);
 
signal inboundType : std_logic_vector(1 downto 0);
signal inboundData : std_logic_vector(32*NUMBER_WORDS-1 downto 0);
 
begin
 
linkInitialized_o <=
382,13 → 387,15
-- Serial layer modules.
-----------------------------------------------------------------------------
outboundSymbol_o <= outboundType & outboundData;
Transmitter: RioTransmitter
generic map(
TIMEOUT_WIDTH=>TIMEOUT_WIDTH,
NUMBER_WORDS=>NUMBER_WORDS)
NUMBER_SYMBOLS=>NUMBER_SYMBOLS,
SYMBOL_COUNTER_WIDTH=>SYMBOL_COUNTER_WIDTH,
TICKS_SEND_STATUS_STARTUP=>TICKS_SEND_STATUS_STARTUP,
TICKS_SEND_STATUS_OPERATIONAL=>TICKS_SEND_STATUS_OPERATIONAL)
port map(
clk=>clk, areset_n=>areset_n,
clk=>clk, areset_n=>areset_n, enable=>enable,
portLinkTimeout_i=>portLinkTimeout_i,
portEnable_i=>outputPortEnable_i,
localAckIdWrite_i=>localAckIdWrite_i,
398,10 → 405,10
outstandingAckId_o=>outstandingAckId_o,
outboundAckId_o=>outboundAckId_o,
portInitialized_i=>portInitialized_i,
txFull_i=>outboundSymbolFull_i,
txWrite_o=>outboundsymbolWrite_o,
txType_o=>outboundType,
txData_o=>outboundData,
txControlValid_o=>outboundControlValid_o,
txControlSymbol_o=>outboundControlSymbol_o,
txDataValid_o=>outboundDataValid_o,
txDataSymbol_o=>outboundDataSymbol_o,
txControlEmpty_i=>txControlReadEmpty,
txControlSymbol_i=>txControlReadSymbol,
txControlUpdate_o=>txControlRead,
421,10 → 428,9
readContentEmpty_i=>readContentEmpty_i,
readContent_o=>readContent_o,
readContentEnd_i=>readContentEnd_i,
readContentWords_i=>"00",
readContentData_i=>readContentData_i(32*NUMBER_WORDS-1 downto 0));
readContentData_i=>readContentData_i(32*NUMBER_SYMBOLS-1 downto 0));
 
SymbolFifo: for i in 0 to NUMBER_WORDS-1 generate
SymbolFifo: for i in 0 to NUMBER_SYMBOLS-1 generate
TxSymbolFifo: RioFifo
generic map(DEPTH_WIDTH=>5, DATA_WIDTH=>13)
port map(
446,10 → 452,8
data_i=>rxControlWriteSymbol(12*(i+1) downto 12*i));
end generate;
inboundType <= inboundSymbol_i(2+(32*NUMBER_WORDS-1) downto 1+(32*NUMBER_WORDS-1));
inboundData <= inboundSymbol_i(32*NUMBER_WORDS-1 downto 0);
Receiver: RioReceiver
generic map(NUMBER_WORDS=>NUMBER_WORDS)
generic map(NUMBER_SYMBOLS=>NUMBER_SYMBOLS)
port map(
clk=>clk, areset_n=>areset_n,
portEnable_i=>inputPortEnable_i,
457,10 → 461,10
inboundAckId_i=>inboundAckId_i,
inboundAckId_o=>inboundAckId_o,
portInitialized_i=>portInitialized_i,
rxEmpty_i=>inboundSymbolEmpty_i,
rxRead_o=>inboundSymbolRead_o,
rxType_i=>inboundType,
rxData_i=>inboundData,
rxControlValid_i=>rxControlValid_i,
rxControlSymbol_i=>rxControlSymbol_i,
rxDataValid_i=>rxDataValid_i,
rxDataSymbol_i=>rxDataSymbol_i,
txControlWrite_o=>txControlWrite,
txControlSymbol_o=>txControlWriteSymbol,
rxControlWrite_o=>rxControlWrite,
471,8 → 475,7
writeFrame_o=>writeFrame_o,
writeFrameAbort_o=>writeFrameAbort_o,
writeContent_o=>writeContent_o,
writeContentWords_o=>open,
writeContentData_o=>writeContentData_o(32*NUMBER_WORDS-1 downto 0));
writeContentData_o=>writeContentData_o(32*NUMBER_SYMBOLS-1 downto 0));
end architecture;
 
479,7 → 482,7
 
 
-------------------------------------------------------------------------------
-- RioTransmitter
-- RioTransmitter.
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
493,11 → 496,15
entity RioTransmitter is
generic(
TIMEOUT_WIDTH : natural;
NUMBER_WORDS : natural range 1 to 4 := 1);
NUMBER_SYMBOLS : natural range 1 to 1 := 1;
SYMBOL_COUNTER_WIDTH : natural;
TICKS_SEND_STATUS_STARTUP : natural;
TICKS_SEND_STATUS_OPERATIONAL : natural);
port(
-- System signals.
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
-- Status signals used for maintenance.
portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
513,20 → 520,20
-- Port output interface.
portInitialized_i : in std_logic;
txFull_i : in std_logic;
txWrite_o : out std_logic;
txType_o : out std_logic_vector(2*NUMBER_WORDS-1 downto 0);
txData_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0);
txControlValid_o : out std_logic;
txControlSymbol_o : out std_logic_vector(23 downto 0);
txDataValid_o : out std_logic;
txDataSymbol_o : out std_logic_vector(31 downto 0);
 
-- Control symbols aimed to the transmitter.
txControlEmpty_i : in std_logic_vector(NUMBER_WORDS-1 downto 0);
txControlSymbol_i : in std_logic_vector(12*NUMBER_WORDS downto 0);
txControlUpdate_o : out std_logic_vector(NUMBER_WORDS-1 downto 0);
txControlEmpty_i : in std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
txControlSymbol_i : in std_logic_vector(12*NUMBER_SYMBOLS downto 0);
txControlUpdate_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
 
-- Control symbols from the receiver to send.
rxControlEmpty_i : in std_logic_vector(NUMBER_WORDS-1 downto 0);
rxControlSymbol_i : in std_logic_vector(12*NUMBER_WORDS downto 0);
rxControlUpdate_o : out std_logic_vector(NUMBER_WORDS-1 downto 0);
rxControlEmpty_i : in std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
rxControlSymbol_i : in std_logic_vector(12*NUMBER_SYMBOLS downto 0);
rxControlUpdate_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
 
-- Internal signalling from the receiver part.
linkInitialized_o : out std_logic;
544,8 → 551,7
readContentEmpty_i : in std_logic;
readContent_o : out std_logic;
readContentEnd_i : in std_logic;
readContentWords_i : in std_logic_vector(1 downto 0);
readContentData_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0));
readContentData_i : in std_logic_vector(32*NUMBER_SYMBOLS-1 downto 0));
end entity;
 
 
554,46 → 560,40
-------------------------------------------------------------------------------
architecture RioTransmitterImpl of RioTransmitter is
 
constant NUMBER_STATUS_TRANSMIT : natural := 15;
constant NUMBER_LINK_RESPONSE_RETRIES : natural := 2;
 
component RioTransmitterCore is
generic(
NUMBER_WORDS : natural range 1 to 4 := 1);
SYMBOL_COUNTER_WIDTH : natural;
TICKS_SEND_STATUS_STARTUP : natural;
TICKS_SEND_STATUS_OPERATIONAL : natural);
port(
-- System signals.
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
-- Status signals used for maintenance.
portEnable_i : in std_logic;
 
-- Port output interface.
portInitialized_i : in std_logic;
txFull_i : in std_logic;
txWrite_o : out std_logic;
txType_o : out std_logic_vector(2*NUMBER_WORDS-1 downto 0);
txData_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0);
txControlValid_o : out std_logic;
txControlSymbol_o : out std_logic_vector(23 downto 0);
txDataValid_o : out std_logic;
txDataSymbol_o : out std_logic_vector(31 downto 0);
 
-- Control symbols aimed to the transmitter.
txControlEmpty_i : in std_logic;
txControlSymbol_i : in std_logic_vector(13*NUMBER_WORDS-1 downto 0);
txControlSymbol_i : in std_logic_vector(12 downto 0);
txControlUpdate_o : out std_logic;
 
-- Control symbols from the receiver to send.
rxControlEmpty_i : in std_logic;
rxControlSymbol_i : in std_logic_vector(13*NUMBER_WORDS-1 downto 0);
rxControlSymbol_i : in std_logic_vector(12 downto 0);
rxControlUpdate_o : out std_logic;
 
-- Internal signalling from the receiver part.
linkInitialized_o : out std_logic;
linkInitialized_i : in std_logic;
ackIdStatus_i : in std_logic_vector(4 downto 0);
 
-- Internal core variables for cascading.
timeSentSet_o : out std_logic;
timeSentReset_o : out std_logic;
timeSentExpired_i : in std_logic;
 
operational_i : in std_logic;
operational_o : out std_logic;
ackId_i : in std_logic_vector(4 downto 0);
616,16 → 616,13
ackIdWindow_o : out std_logic_vector(4 downto 0);
frameState_i : in std_logic_vector(3 downto 0);
frameState_o : out std_logic_vector(3 downto 0);
frameWordCounter_i : in std_logic_vector(1 downto 0);
frameWordCounter_o : out std_logic_vector(1 downto 0);
frameContent_i : in std_logic_vector(31 downto 0);
frameContent_o : out std_logic_vector(31 downto 0);
counter_i : in std_logic_vector(3 downto 0);
counter_o : out std_logic_vector(3 downto 0);
symbolsTransmitted_i : in std_logic_vector(7 downto 0);
symbolsTransmitted_o : out std_logic_vector(7 downto 0);
-- Frame buffer interface.
statusCounter_i : in std_logic_vector(3 downto 0);
statusCounter_o : out std_logic_vector(3 downto 0);
symbolCounter_i : in std_logic_vector(SYMBOL_COUNTER_WIDTH-1 downto 0);
symbolCounter_o : out std_logic_vector(SYMBOL_COUNTER_WIDTH-1 downto 0);
 
readFrameEmpty_i : in std_logic;
readFrame_o : out std_logic;
readFrameRestart_o : out std_logic;
636,8 → 633,7
readContentEmpty_i : in std_logic;
readContent_o : out std_logic;
readContentEnd_i : in std_logic;
readContentWords_i : in std_logic_vector(1 downto 0);
readContentData_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0));
readContentData_i : in std_logic_vector(31 downto 0));
end component;
component MemorySimpleDualPortAsync is
667,27 → 663,26
signal timeSentReadAddress : std_logic_vector(4 downto 0);
signal timeSentReadData : std_logic_vector(TIMEOUT_WIDTH downto 0);
signal operationalCurrent, operationalNext : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal ackIdCurrent, ackIdNext : std_logic_vector(5*NUMBER_WORDS-1 downto 0);
signal bufferStatusCurrent, bufferStatusNext : std_logic_vector(5*NUMBER_WORDS-1 downto 0);
signal statusReceivedCurrent, statusReceivedNext : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal numberSentLinkRequestsCurrent, numberSentLinkRequestsNext : std_logic_vector(2*NUMBER_WORDS-1 downto 0);
signal outputErrorStoppedCurrent, outputErrorStoppedNext : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal fatalErrorCurrent, fatalErrorNext : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal recoverActiveCurrent, recoverActiveNext : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal recoverCounterCurrent, recoverCounterNext : std_logic_vector(5*NUMBER_WORDS-1 downto 0);
signal ackIdWindowCurrent, ackIdWindowNext : std_logic_vector(5*NUMBER_WORDS-1 downto 0);
signal frameStateCurrent, frameStateNext : std_logic_vector(4*NUMBER_WORDS-1 downto 0);
signal frameWordCounterCurrent, frameWordCounterNext : std_logic_vector(2*NUMBER_WORDS-1 downto 0);
signal frameContentCurrent, frameContentNext : std_logic_vector(32*NUMBER_WORDS-1 downto 0);
signal counterCurrent, counterNext : std_logic_vector(4*NUMBER_WORDS-1 downto 0);
signal symbolsTransmittedCurrent, symbolsTransmittedNext : std_logic_vector(8*NUMBER_WORDS-1 downto 0);
signal operationalCurrent, operationalNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal ackIdCurrent, ackIdNext : std_logic_vector(5*NUMBER_SYMBOLS-1 downto 0);
signal bufferStatusCurrent, bufferStatusNext : std_logic_vector(5*NUMBER_SYMBOLS-1 downto 0);
signal statusReceivedCurrent, statusReceivedNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal numberSentLinkRequestsCurrent, numberSentLinkRequestsNext : std_logic_vector(2*NUMBER_SYMBOLS-1 downto 0);
signal outputErrorStoppedCurrent, outputErrorStoppedNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal fatalErrorCurrent, fatalErrorNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal recoverActiveCurrent, recoverActiveNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal recoverCounterCurrent, recoverCounterNext : std_logic_vector(5*NUMBER_SYMBOLS-1 downto 0);
signal ackIdWindowCurrent, ackIdWindowNext : std_logic_vector(5*NUMBER_SYMBOLS-1 downto 0);
signal frameStateCurrent, frameStateNext : std_logic_vector(4*NUMBER_SYMBOLS-1 downto 0);
signal frameContentCurrent, frameContentNext : std_logic_vector(32*NUMBER_SYMBOLS-1 downto 0);
signal statusCounterCurrent, statusCounterNext : std_logic_vector(4*NUMBER_SYMBOLS-1 downto 0);
signal symbolCounterCurrent, symbolCounterNext : std_logic_vector(8*NUMBER_SYMBOLS-1 downto 0);
 
signal readFrame : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal readFrameRestart : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal readWindowReset : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal readWindowNext : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal readContent : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal readFrame : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal readFrameRestart : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal readWindowReset : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal readWindowNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal readContent : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
begin
 
-----------------------------------------------------------------------------
701,7 → 696,7
readWindowReset_o <= '0';
readWindowNext_o <= '0';
readContent_o <= '0';
for i in 0 to NUMBER_WORDS-1 loop
for i in 0 to NUMBER_SYMBOLS-1 loop
if (readFrame(i) = '1') then
readFrame_o <= '1';
end if;
747,7 → 742,7
timeSentExpired <= timeSentDelta(TIMEOUT_WIDTH);
timeSentEnable <= (not txFull_i) and (timeSentSet or timeSentReset);
timeSentEnable <= enable and (timeSentSet or timeSentReset);
timeSentWriteAddress <= ackIdWindowCurrent when timeSentSet = '1' else
ackIdCurrent;
timeSentReadAddress <= ackIdCurrent;
776,12 → 771,11
recoverCounterCurrent <= (others=>'0');
ackIdWindowCurrent <= (others=>'0');
frameStateCurrent <= (others=>'0');
frameWordCounterCurrent <= (others=>'0');
frameContentCurrent <= (others=>'0');
counterCurrent <= (others=>'0');
symbolsTransmittedCurrent <= (others=>'0');
statusCounterCurrent <= (others=>'0');
symbolCounterCurrent <= (others=>'0');
elsif (clk'event and clk = '1') then
if (txFull_i = '0') then
if (enable = '0') then
operationalCurrent <= operationalNext;
ackIdCurrent <= ackIdNext;
bufferStatusCurrent <= bufferStatusNext;
793,25 → 787,26
recoverCounterCurrent <= recoverCounterNext;
ackIdWindowCurrent <= ackIdWindowNext;
frameStateCurrent <= frameStateNext;
frameWordCounterCurrent <= frameWordCounterNext;
frameContentCurrent <= frameContentNext;
counterCurrent <= counterNext;
symbolsTransmittedCurrent <= symbolsTransmittedNext;
statusCounterCurrent <= statusCounterNext;
symbolCounterCurrent <= symbolCounterNext;
end if;
end if;
end process;
 
CoreGeneration: for i in 0 to NUMBER_WORDS-1 generate
CoreGeneration: for i in 0 to NUMBER_SYMBOLS-1 generate
TxCore: RioTransmitterCore
generic map(NUMBER_WORDS=>NUMBER_WORDS)
generic map(SYMBOL_COUNTER_WIDTH=>SYMBOL_COUNTER_WIDTH,
TICKS_SEND_STATUS_STARTUP=>TICKS_SEND_STATUS_STARTUP,
TICKS_SEND_STATUS_OPERATIONAL=>TICKS_SEND_STATUS_OPERATIONAL)
port map(
clk=>clk, areset_n=>areset_n,
clk=>clk, areset_n=>areset_n, enable=>enable,
portEnable_i=>portEnable_i,
portInitialized_i=>portInitialized_i,
txFull_i=>txFull_i,
txWrite_o=>txWrite_o,
txType_o=>txType_o,
txData_o=>txData_o,
txControlValid_o=>txControlValid_o,
txControlSymbol_o=>txControlSymbol_o,
txDataValid_o=>txDataValid_o,
txDataSymbol_o=>txDataSymbol_o,
txControlEmpty_i=>txControlEmpty_i(i),
txControlSymbol_i=>txControlSymbol_i(13*(i+1)-1 downto 13*i),
txControlUpdate_o=>txControlUpdate_o(i),
846,14 → 841,12
ackIdWindow_o=>ackIdWindowNext(5*(i+1)-1 downto 5*i),
frameState_i=>frameStateCurrent(4*(i+1)-1 downto 4*i),
frameState_o=>frameStateNext(4*(i+1)-1 downto 4*i),
frameWordCounter_i=>frameWordCounterCurrent(2*(i+1)-1 downto 2*i),
frameWordCounter_o=>frameWordCounterNext(2*(i+1)-1 downto 2*i),
frameContent_i=>frameContentCurrent(32*(i+1)-1 downto 32*i),
frameContent_o=>frameContentNext(32*(i+1)-1 downto 32*i),
counter_i=>counterCurrent(4*(i+1)-1 downto 4*i),
counter_o=>counterNext(4*(i+1)-1 downto 4*i),
symbolsTransmitted_i=>symbolsTransmittedCurrent(8*(i+1)-1 downto 8*i),
symbolsTransmitted_o=>symbolsTransmittedNext(8*(i+1)-1 downto 8*i),
statusCounter_i=>statusCounterCurrent(4*(i+1)-1 downto 4*i),
statusCounter_o=>statusCounterNext(4*(i+1)-1 downto 4*i),
symbolCounter_i=>symbolCounterCurrent(SYMBOL_COUNTER_WIDTH*(i+1)-1 downto SYMBOL_COUNTER_WIDTH*i),
symbolCounter_o=>symbolCounterNext(SYMBOL_COUNTER_WIDTH*(i+1)-1 downto SYMBOL_COUNTER_WIDTH*i),
readFrameEmpty_i=>readFrameEmpty_i,
readFrame_o=>readFrame(i),
readFrameRestart_o=>readFrameRestart(i),
864,7 → 857,6
readContentEmpty_i=>readContentEmpty_i,
readContent_o=>readContent(i),
readContentEnd_i=>readContentEnd_i,
readContentWords_i=>readContentWords_i,
readContentData_i=>readContentData_i);
end generate;
874,6 → 866,17
 
-------------------------------------------------------------------------------
-- RioTransmitterCore
-- This module generate control- and data-symbols each clock tick. A
-- tick when nothing is generated it is assumed that an idle sequence is
-- generated.
--
-- TICKS_SEND_STATUS - The number of consequtive ticks sending nothing to wait
-- before a status-control-symbol is transmitted.
--
-- txControlValid_o='0' and txDataValid_o='0': nothing to send.
-- txControlValid_o='0' and txDataValid_o='1': txDataSymbol_o contains a data-symbol.
-- txControlValid_o='1' and txDataValid_o='0': txControlSymbol_o contains a control-symbol.
-- txControlValid_o='1' and txDataValid_o='1': an error has occurred.
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
885,11 → 888,14
-------------------------------------------------------------------------------
entity RioTransmitterCore is
generic(
NUMBER_WORDS : natural range 1 to 4 := 1);
SYMBOL_COUNTER_WIDTH : natural;
TICKS_SEND_STATUS_STARTUP : natural;
TICKS_SEND_STATUS_OPERATIONAL : natural);
port(
-- System signals.
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
-- Status signals used for maintenance.
portEnable_i : in std_logic;
896,19 → 902,19
 
-- Port output interface.
portInitialized_i : in std_logic;
txFull_i : in std_logic;
txWrite_o : out std_logic;
txType_o : out std_logic_vector(2*NUMBER_WORDS-1 downto 0);
txData_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0);
txControlValid_o : out std_logic;
txControlSymbol_o : out std_logic_vector(23 downto 0);
txDataValid_o : out std_logic;
txDataSymbol_o : out std_logic_vector(31 downto 0);
 
-- Control symbols aimed to the transmitter.
txControlEmpty_i : in std_logic;
txControlSymbol_i : in std_logic_vector(13*NUMBER_WORDS-1 downto 0);
txControlSymbol_i : in std_logic_vector(12 downto 0);
txControlUpdate_o : out std_logic;
 
-- Control symbols from the receiver to send.
rxControlEmpty_i : in std_logic;
rxControlSymbol_i : in std_logic_vector(13*NUMBER_WORDS-1 downto 0);
rxControlSymbol_i : in std_logic_vector(12 downto 0);
rxControlUpdate_o : out std_logic;
 
-- Internal signalling from the receiver part.
944,14 → 950,12
ackIdWindow_o : out std_logic_vector(4 downto 0);
frameState_i : in std_logic_vector(3 downto 0);
frameState_o : out std_logic_vector(3 downto 0);
frameWordCounter_i : in std_logic_vector(1 downto 0);
frameWordCounter_o : out std_logic_vector(1 downto 0);
frameContent_i : in std_logic_vector(31 downto 0);
frameContent_o : out std_logic_vector(31 downto 0);
counter_i : in std_logic_vector(3 downto 0);
counter_o : out std_logic_vector(3 downto 0);
symbolsTransmitted_i : in std_logic_vector(7 downto 0);
symbolsTransmitted_o : out std_logic_vector(7 downto 0);
statusCounter_i : in std_logic_vector(3 downto 0);
statusCounter_o : out std_logic_vector(3 downto 0);
symbolCounter_i : in std_logic_vector(SYMBOL_COUNTER_WIDTH-1 downto 0);
symbolCounter_o : out std_logic_vector(SYMBOL_COUNTER_WIDTH-1 downto 0);
-- Frame buffer interface.
readFrameEmpty_i : in std_logic;
964,8 → 968,7
readContentEmpty_i : in std_logic;
readContent_o : out std_logic;
readContentEnd_i : in std_logic;
readContentWords_i : in std_logic_vector(1 downto 0);
readContentData_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0));
readContentData_i : in std_logic_vector(31 downto 0));
end entity;
 
 
974,9 → 977,14
-------------------------------------------------------------------------------
architecture RioTransmitterCoreImpl of RioTransmitterCore is
 
constant NUMBER_STATUS_TRANSMIT : std_logic_vector := "1111";
constant NUMBER_LINK_RESPONSE_RETRIES : std_logic_vector := "10";
-- The number of statuses to transmit at link initialization before starting
-- to send packets.
constant NUMBER_STATUS_TRANSMIT : std_logic_vector(3 downto 0) := "1111";
 
-- The number of retries to make when a link-request has not been answered.
constant NUMBER_LINK_RESPONSE_RETRIES : std_logic_vector(1 downto 0) := "10";
 
-- States for frame transmission.
constant FRAME_IDLE : std_logic_vector(3 downto 0) := "0000";
constant FRAME_BUFFER : std_logic_vector(3 downto 0) := "0001";
constant FRAME_START : std_logic_vector(3 downto 0) := "0010";
988,7 → 996,8
constant FRAME_START_CONTINUE : std_logic_vector(3 downto 0) := "1000";
constant FRAME_END : std_logic_vector(3 downto 0) := "1001";
constant FRAME_DISCARD : std_logic_vector(3 downto 0) := "1010";
 
-- CRC-5 calculation unit for control-symbol generation.
component Crc5ITU is
port(
d_i : in std_logic_vector(18 downto 0);
995,10 → 1004,15
crc_o : out std_logic_vector(4 downto 0));
end component;
 
-- Stage-1 signals.
alias txControlStype0 : std_logic_vector(2 downto 0) is txControlSymbol_i(12 downto 10);
alias txControlParameter0 : std_logic_vector(4 downto 0) is txControlSymbol_i(9 downto 5);
alias txControlParameter1 : std_logic_vector(4 downto 0) is txControlSymbol_i(4 downto 0);
signal txControlUpdateOut : std_logic;
signal sendRestartFromRetry, sendRestartFromRetryOut : std_logic;
signal sendLinkRequest, sendLinkRequestOut : std_logic;
 
-- Stage-2 signals.
signal readFrameOut : std_logic;
signal readFrameRestartOut : std_logic;
signal readWindowResetOut : std_logic;
1012,6 → 1026,10
signal symbolDataOut, symbolData : std_logic;
signal symbolDataContentOut, symbolDataContent : std_logic_vector(31 downto 0);
 
-- Stage-3 signals.
alias rxControlStype0 : std_logic_vector(2 downto 0) is rxControlSymbol_i(12 downto 10);
alias rxControlParameter0 : std_logic_vector(4 downto 0) is rxControlSymbol_i(9 downto 5);
alias rxControlParameter1 : std_logic_vector(4 downto 0) is rxControlSymbol_i(4 downto 0);
signal rxControlUpdateOut : std_logic;
signal symbolControlStype1 : std_logic;
signal controlValidOut, controlValid : std_logic;
1022,17 → 1040,12
signal cmd : std_logic_vector(2 downto 0);
signal dataValid : std_logic;
signal dataContent : std_logic_vector(31 downto 0);
signal controlContent : std_logic_vector(31 downto 0);
 
-- Stage-4 signals.
signal sendStatusRequiredOut, sendStatusRequired : std_logic;
signal controlContent : std_logic_vector(23 downto 0);
signal crc5 : std_logic_vector(4 downto 0);
signal txControlStype0 : std_logic_vector(2 downto 0);
signal txControlParameter0 : std_logic_vector(4 downto 0);
signal txControlParameter1 : std_logic_vector(4 downto 0);
 
signal rxControlStype0 : std_logic_vector(2 downto 0);
signal rxControlParameter0 : std_logic_vector(4 downto 0);
signal rxControlParameter1 : std_logic_vector(4 downto 0);
 
begin
 
1039,45 → 1052,15
linkInitialized_o <= operational_i;
-----------------------------------------------------------------------------
-- Assign control symbol from fifo signals.
-----------------------------------------------------------------------------
txControlStype0 <= txControlSymbol_i(12 downto 10);
txControlParameter0 <= txControlSymbol_i(9 downto 5);
txControlParameter1 <= txControlSymbol_i(4 downto 0);
 
rxControlStype0 <= rxControlSymbol_i(12 downto 10);
rxControlParameter0 <= rxControlSymbol_i(9 downto 5);
rxControlParameter1 <= rxControlSymbol_i(4 downto 0);
 
-----------------------------------------------------------------------------
-- First pipeline stage.
-- Receive stuff from link-partner and timeout supervision.
-- Receive control-symbols from our link-partner and supervise timeouts.
-- Input: ackId, ackIdWindow, timeoutExpired
-- Output: sendLinkRequest, sendRestartFromRetry, ackId
-----------------------------------------------------------------------------
-- REMARK: Update the comment above...
 
txControlUpdate_o <= txControlUpdateOut and (not txFull_i);
txControlUpdate_o <= txControlUpdateOut and enable;
process(clk, areset_n)
begin
if (areset_n = '0') then
readFrame_o <= '0';
sendRestartFromRetry <= '0';
sendLinkRequest <= '0';
elsif (clk'event and clk = '1') then
readFrame_o <= '0';
if (txFull_i = '0') then
readFrame_o <= readFrameOut or discardFrameOut;
sendRestartFromRetry <= sendRestartFromRetryOut;
sendLinkRequest <= sendLinkRequestOut;
end if;
end if;
end process;
process(outputErrorStopped_i, recoverActive_i, recoverCounter_i,
ackId_i, ackIdWindow_i, bufferStatus_i, statusReceived_i,
numberSentLinkRequests_i,
1290,6 → 1273,25
end if;
end process;
process(clk, areset_n)
begin
if (areset_n = '0') then
readFrame_o <= '0';
sendRestartFromRetry <= '0';
sendLinkRequest <= '0';
elsif (clk'event and clk = '1') then
readFrame_o <= '0';
if (enable = '1') then
readFrame_o <= readFrameOut or discardFrameOut;
sendRestartFromRetry <= sendRestartFromRetryOut;
sendLinkRequest <= sendLinkRequestOut;
end if;
end if;
end process;
-----------------------------------------------------------------------------
-- Second pipeline stage.
-- Create stype1-part of symbols and data symbols. Save the time when a
1300,38 → 1302,17
-- symbolControlLinkRequest, symbolData2, symbolData2Content.
-----------------------------------------------------------------------------
 
readFrameRestart_o <= readFrameRestartOut and (not txFull_i);
readWindowReset_o <= readWindowResetOut and (not txFull_i);
readWindowNext_o <= readWindowNextOut and (not txFull_i);
readContent_o <= readContentOut and (not txFull_i);
readFrameRestart_o <= readFrameRestartOut and enable;
readWindowReset_o <= readWindowResetOut and enable;
readWindowNext_o <= readWindowNextOut and enable;
readContent_o <= readContentOut and enable;
 
process(clk, areset_n)
begin
if (areset_n = '0') then
symbolControlRestart <= '0';
symbolControlLinkRequest <= '0';
symbolControlStart <= '0';
symbolControlEnd <= '0';
symbolData <= '0';
symbolDataContent <= (others => '0');
elsif (clk'event and clk = '1') then
if (txFull_i = '0') then
symbolControlRestart <= symbolControlRestartOut;
symbolControlLinkRequest <= symbolControlLinkRequestOut;
symbolControlStart <= symbolControlStartOut;
symbolControlEnd <= symbolControlEndOut;
symbolData <= symbolDataOut;
symbolDataContent <= symbolDataContentOut;
end if;
end if;
end process;
-- This process decide which stype1-part of a control symbols to send as well
-- as all data symbols.
process(readWindowEmpty_i, bufferStatus_i,
readContentData_i, readContentWords_i, readContentEnd_i,
readContentData_i, readContentEnd_i,
recoverActive_i, ackId_i, operational_i, outputErrorStopped_i, portEnable_i,
frameState_i, frameWordCounter_i, frameContent_i,
frameState_i, frameContent_i,
ackIdWindow_i,
sendRestartFromRetry, sendLinkRequest,
rxControlEmpty_i,
1343,7 → 1324,6
readContentOut <= '0';
 
frameState_o <= frameState_i;
frameWordCounter_o <= frameWordCounter_i;
frameContent_o <= frameContent_i;
ackIdWindow_o <= ackIdWindow_i;
1358,6 → 1338,7
 
discardFrameOut <= '0';
 
-- Check if allowed to send anything.
if ((fatalError_i = '1') or (recoverActive_i = '1') or
(operational_i = '0')) then
-----------------------------------------------------------------------
1367,9 → 1348,9
-----------------------------------------------------------------------
-- Initialize framing before entering the operational state.
readWindowResetOut <= '1';
frameState_o <= FRAME_IDLE;
ackIdWindow_o <= ackId_i;
readWindowResetOut <= '1';
else
-------------------------------------------------------------------
-- This state is the operational state. It relays frames and handle
1601,6 → 1582,27
end if;
end process;
 
process(clk, areset_n)
begin
if (areset_n = '0') then
symbolControlRestart <= '0';
symbolControlLinkRequest <= '0';
symbolControlStart <= '0';
symbolControlEnd <= '0';
symbolData <= '0';
symbolDataContent <= (others => '0');
elsif (clk'event and clk = '1') then
if (enable = '1') then
symbolControlRestart <= symbolControlRestartOut;
symbolControlLinkRequest <= symbolControlLinkRequestOut;
symbolControlStart <= symbolControlStartOut;
symbolControlEnd <= symbolControlEndOut;
symbolData <= symbolDataOut;
symbolDataContent <= symbolDataContentOut;
end if;
end if;
end process;
-----------------------------------------------------------------------------
-- Third pipeline stage.
-- Create the stype0 and stype1 part of a control symbol.
1610,57 → 1612,18
-- before the operational-state is entered.
-- Input: symbolControlStart, symbolControlEnd, symbolControlRestart,
-- symbolControlLinkRequest, symbolData, symbolDataContent
-- Output: symbolsTransmitted_o, operational_o,
-- Output: symbolCounter_o, operational_o,
-- symbolControl, stype0, parameter0, parameter1, stype1, cmd
-----------------------------------------------------------------------------
 
rxControlUpdate_o <= rxControlUpdateOut and (not txFull_i);
rxControlUpdate_o <= rxControlUpdateOut and enable;
process(clk, areset_n)
begin
if (areset_n = '0') then
controlValid <= '0';
stype0 <= (others=>'0');
parameter0 <= (others=>'0');
parameter1 <= (others=>'0');
stype1 <= STYPE1_NOP;
cmd <= (others=>'0');
dataValid <= '0';
dataContent <= (others=>'0');
elsif (clk'event and clk = '1') then
if (txFull_i = '0') then
controlValid <= controlValidOut;
stype0 <= stype0Out;
parameter0 <= parameter0Out;
parameter1 <= parameter1Out;
stype1 <= STYPE1_NOP;
cmd <= "000";
dataValid <= symbolData;
dataContent <= symbolDataContent;
if (symbolControlStart = '1') then
stype1 <= STYPE1_START_OF_PACKET;
end if;
if (symbolControlEnd = '1') then
stype1 <= STYPE1_END_OF_PACKET;
end if;
if (symbolControlRestart = '1') then
stype1 <= STYPE1_RESTART_FROM_RETRY;
end if;
if (symbolControlLinkRequest = '1') then
stype1 <= STYPE1_LINK_REQUEST;
cmd <= LINK_REQUEST_CMD_INPUT_STATUS;
end if;
end if;
end if;
end process;
 
symbolControlStype1 <=
symbolControlRestart or symbolControlLinkRequest or
symbolControlStart or symbolControlEnd;
process(linkInitialized_i, ackIdStatus_i, portInitialized_i,
operational_i, counter_i, statusReceived_i, symbolsTransmitted_i,
operational_i, statusCounter_i, statusReceived_i,
rxControlEmpty_i,
symbolControlStype1, symbolData,
rxControlStype0, rxControlParameter0, rxControlParameter1,
1667,8 → 1630,8
fatalError_i)
begin
operational_o <= operational_i;
counter_o <= counter_i;
symbolsTransmitted_o <= symbolsTransmitted_i;
statusCounter_o <= statusCounter_i;
 
rxControlUpdateOut <= '0';
controlValidOut <= '0';
1677,9 → 1640,9
parameter1Out <= "11111";
if (fatalError_i = '1') then
-- Reset when a fatal error occurrs.
operational_o <= '0';
counter_o <= NUMBER_STATUS_TRANSMIT;
symbolsTransmitted_o <= (others=>'0');
statusCounter_o <= NUMBER_STATUS_TRANSMIT;
else
-- Check the operational state.
if (operational_i = '0') then
1701,42 → 1664,31
---------------------------------------------------------------------
 
-- Check if we are ready to change state to operational.
if ((linkInitialized_i = '1') and
(unsigned(counter_i) = 0)) then
if ((linkInitialized_i = '1') and (unsigned(statusCounter_i) = 0)) then
-- Receiver has received enough error free status symbols and we
-- have transmitted enough.
-- Considder ourselfs operational.
operational_o <= '1';
else
-- Not ready to change state to operational.
-- Dont do anything.
end if;
-- Check if idle sequence or a status symbol should be transmitted.
if (((statusReceived_i = '0') and (symbolsTransmitted_i = x"ff")) or
((statusReceived_i = '1') and (symbolsTransmitted_i > x"0f"))) then
-- Check if a status symbol should be transmitted.
if (sendStatusRequired = '1') then
-- A status symbol should be transmitted.
-- Send a status control symbol to the link partner.
controlValidOut <= '1';
 
-- Reset idle sequence transmission counter.
symbolsTransmitted_o <= (others=>'0');
 
-- Check if the number of transmitted statuses should be updated.
if (statusReceived_i = '1') and (unsigned(counter_i) /= 0) then
counter_o <= std_logic_vector(unsigned(counter_i) - 1);
if (statusReceived_i = '1') and (unsigned(statusCounter_i) /= 0) then
statusCounter_o <= std_logic_vector(unsigned(statusCounter_i) - 1);
end if;
else
-- Increment the idle sequence transmission counter.
symbolsTransmitted_o <= std_logic_vector(unsigned(symbolsTransmitted_i) + 1);
end if;
else
-- The port is not initialized.
-- Reset initialization variables.
counter_o <= NUMBER_STATUS_TRANSMIT;
symbolsTransmitted_o <= (others=>'0');
operational_o <= '0';
statusCounter_o <= NUMBER_STATUS_TRANSMIT;
end if;
else
---------------------------------------------------------------------
1747,60 → 1699,103
-- Check if the port is still initialized.
if (portInitialized_i = '1') then
-- The port is still initialized.
-- Check if a status must be sent.
-- A status must be sent when there are no other stype0 value to
-- send or if too many symbols without buffer-status has been sent.
-- REMARK: Is there a risk of a race when a generated status-symbol
-- is sent before another symbol stored in the rx-control fifo???
if (((symbolControlStype1 = '1') and (rxControlEmpty_i = '1')) or
((symbolControlStype1 = '0') and (symbolData = '0') and
(symbolsTransmitted_i = x"ff"))) then
-- A control symbol is about to be sent without pending symbol from
-- receiver or too many idle symbols has been sent.
 
-- Force the sending of a status containing the bufferStatus.
controlValidOut <= '1';
symbolsTransmitted_o <= (others=>'0');
elsif ((symbolData = '0') and (rxControlEmpty_i = '0')) then
-- A control symbol is about to be sent and there is a pending
-- symbol from the receiver.
-- Remove the symbol from the fifo.
rxControlUpdateOut <= '1';
-- Send the receiver symbol.
controlValidOut <= '1';
stype0Out <= rxControlStype0;
parameter0Out <= rxControlParameter0;
parameter1Out <= rxControlParameter1;
-- Check if the transmitted symbol contains status about
-- available buffers.
if ((rxControlStype0 = STYPE0_PACKET_ACCEPTED) or
(rxControlStype0 = STYPE0_PACKET_RETRY)) then
-- A symbol containing the bufferStatus has been sent.
symbolsTransmitted_o <= (others=>'0');
-- Check if any dataSymbol is about to be sent.
if (symbolData = '0') then
-- No pending data symbol.
 
-- Check if there is a pending control-symbol from the receiver.
if (rxControlEmpty_i = '1') then
-- No pending control-symbol from the receiver.
 
-- Check if there is a pending control-symbol from ourselfs.
if (symbolControlStype1 = '0') then
-- No pending control-symbol from ourselfs.
 
-- Check if we need to send a status-control-symbol.
if (sendStatusRequired = '0') then
-- Not required to send a status-control-symbol.
-- Don't send anything.
else
-- Required to send a status-control-symbol.
-- Indicate a status-control-symbol is ready.
controlValidOut <= '1';
end if;
else
-- Pending control-symbol from ourselfs.
-- Send it and reset the counter since a status-control-symbol
-- will be combined with it.
controlValidOut <= '1';
end if;
else
-- A symbol not containing the bufferStatus has been sent.
symbolsTransmitted_o <= std_logic_vector(unsigned(symbolsTransmitted_i) + 1);
-- Pending control-symbol from the receiver.
-- If there is a pending control-symbol from ourselfs they will be
-- combined.
-- Remove the control-symbol from the fifo.
rxControlUpdateOut <= '1';
-- Send the receiver symbol.
controlValidOut <= '1';
stype0Out <= rxControlStype0;
parameter0Out <= rxControlParameter0;
parameter1Out <= rxControlParameter1;
end if;
else
-- A symbol not containing the bufferStatus has been sent.
controlValidOut <= '0';
symbolsTransmitted_o <= std_logic_vector(unsigned(symbolsTransmitted_i) + 1);
-- Pending data symbol.
-- Send the data symbol.
end if;
else
-- The port is not initialized anymore.
-- Change the operational state.
operational_o <= '0';
counter_o <= NUMBER_STATUS_TRANSMIT;
symbolsTransmitted_o <= (others=>'0');
statusCounter_o <= NUMBER_STATUS_TRANSMIT;
end if;
end if;
end if;
end process;
process(clk, areset_n)
begin
if (areset_n = '0') then
dataValid <= '0';
dataContent <= (others=>'0');
 
controlValid <= '0';
stype0 <= (others=>'0');
parameter0 <= (others=>'0');
parameter1 <= (others=>'0');
stype1 <= (others=>'0');
cmd <= (others=>'0');
elsif (clk'event and clk = '1') then
if (enable = '1') then
dataValid <= symbolData;
dataContent <= symbolDataContent;
controlValid <= controlValidOut;
stype0 <= stype0Out;
parameter0 <= parameter0Out;
parameter1 <= parameter1Out;
if (symbolControlStart = '1') then
stype1 <= STYPE1_START_OF_PACKET;
cmd <= "000";
elsif (symbolControlEnd = '1') then
stype1 <= STYPE1_END_OF_PACKET;
cmd <= "000";
elsif (symbolControlRestart = '1') then
stype1 <= STYPE1_RESTART_FROM_RETRY;
cmd <= "000";
elsif (symbolControlLinkRequest = '1') then
stype1 <= STYPE1_LINK_REQUEST;
cmd <= LINK_REQUEST_CMD_INPUT_STATUS;
else
stype1 <= STYPE1_NOP;
cmd <= "000";
end if;
end if;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Fourth pipeline stage.
-- Make all symbols ready for transmission, i.e. calculate the CRC5 on
1808,35 → 1803,57
-- Inputs: controlValid, stype0, parameter0, parameter1, stype1, cmd
-----------------------------------------------------------------------------
 
controlContent(31 downto 29) <= stype0;
controlContent(28 downto 24) <= parameter0;
controlContent(23 downto 19) <= parameter1;
controlContent(18 downto 16) <= stype1;
controlContent(15 downto 13) <= cmd;
controlContent(12 downto 8) <= crc5;
controlContent(7 downto 0) <= x"00";
process(controlValid, stype0, portInitialized_i, symbolCounter_i)
begin
if ((controlValid = '1') and
((stype0 = STYPE0_STATUS) or
(stype0 = STYPE0_PACKET_ACCEPTED) or
(stype0 = STYPE0_PACKET_RETRY))) then
if (portInitialized_i = '0') then
symbolCounter_o <=
std_logic_vector(to_unsigned(TICKS_SEND_STATUS_STARTUP,
SYMBOL_COUNTER_WIDTH));
else
symbolCounter_o <=
std_logic_vector(to_unsigned(TICKS_SEND_STATUS_OPERATIONAL,
SYMBOL_COUNTER_WIDTH));
end if;
else
if (unsigned(symbolCounter_i) = 0) then
sendStatusRequiredOut <= '1';
else
sendStatusRequiredOut <= '0';
symbolCounter_o <= std_logic_vector(unsigned(symbolCounter_i) - 1);
end if;
end if;
end process;
controlContent(23 downto 21) <= stype0;
controlContent(20 downto 16) <= parameter0;
controlContent(15 downto 11) <= parameter1;
controlContent(10 downto 8) <= stype1;
controlContent(7 downto 5) <= cmd;
controlContent(4 downto 0) <= crc5;
 
Crc5Calculator: Crc5ITU
port map(
d_i=>controlContent(31 downto 13), crc_o=>crc5);
d_i=>controlContent(23 downto 5), crc_o=>crc5);
 
txWrite_o <= not txFull_i;
process(clk, areset_n)
begin
if (areset_n = '0') then
txType_o <= SYMBOL_IDLE;
txData_o <= (others=>'0');
sendStatusRequired <= '0';
txControlValid_o <= '0';
txControlSymbol_o <= (others=>'0');
txDataValid_o <= '0';
txDataSymbol_o <= (others=>'0');
elsif (clk'event and clk = '1') then
if (txFull_i = '0') then
txType_o <= SYMBOL_IDLE;
if (controlValid = '1') then
txType_o <= SYMBOL_CONTROL;
txData_o <= controlContent;
end if;
if (dataValid = '1') then
txType_o <= SYMBOL_DATA;
txData_o <= dataContent;
end if;
if (enable = '1') then
sendStatusRequired <= sendStatusRequiredOut;
txControlValid_o <= controlValid;
txControlSymbol_o <= controlContent;
txDataValid_o <= dataValid;
txDataSymbol_o <= dataContent;
end if;
end if;
end process;
1846,7 → 1863,7
 
 
-------------------------------------------------------------------------------
--
-- RioReciever.
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
1854,12 → 1871,16
use work.rio_common.all;
 
 
-------------------------------------------------------------------------------
-- Entity for RioReceiver.
-------------------------------------------------------------------------------
entity RioReceiver is
generic(
NUMBER_WORDS : natural range 1 to 4 := 1);
NUMBER_SYMBOLS : natural range 1 to 1 := 1);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
portEnable_i : in std_logic;
1868,15 → 1889,15
inboundAckId_o : out std_logic_vector(4 downto 0);
portInitialized_i : in std_logic;
rxEmpty_i : in std_logic;
rxRead_o : out std_logic;
rxType_i : in std_logic_vector(2*NUMBER_WORDS-1 downto 0);
rxData_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0);
rxControlValid_i : in std_logic;
rxControlSymbol_i : in std_logic_vector(23 downto 0);
rxDataValid_i : in std_logic;
rxDataSymbol_i : in std_logic_vector(31 downto 0);
txControlWrite_o : out std_logic_vector(NUMBER_WORDS-1 downto 0);
txControlSymbol_o : out std_logic_vector(12*NUMBER_WORDS downto 0);
rxControlWrite_o : out std_logic_vector(NUMBER_WORDS-1 downto 0);
rxControlSymbol_o : out std_logic_vector(12*NUMBER_WORDS downto 0);
txControlWrite_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
txControlSymbol_o : out std_logic_vector(12*NUMBER_SYMBOLS downto 0);
rxControlWrite_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
rxControlSymbol_o : out std_logic_vector(12*NUMBER_SYMBOLS downto 0);
ackIdStatus_o : out std_logic_vector(4 downto 0);
linkInitialized_o : out std_logic;
1885,21 → 1906,22
writeFrame_o : out std_logic;
writeFrameAbort_o : out std_logic;
writeContent_o : out std_logic;
writeContentWords_o : out std_logic_vector(1 downto 0);
writeContentData_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0));
writeContentData_o : out std_logic_vector(32*NUMBER_SYMBOLS-1 downto 0));
end entity;
 
 
-------------------------------------------------------------------------------
--
-- Architecture for RioReceiver.
-------------------------------------------------------------------------------
architecture RioReceiverImpl of RioReceiver is
 
component RioReceiverCore is
generic(
NUMBER_WORDS : natural range 1 to 4 := 1);
NUMBER_SYMBOLS : natural range 1 to 1 := 1);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
-- Status signals used for maintenance.
portEnable_i : in std_logic;
1912,10 → 1934,10
-- Port input interface.
portInitialized_i : in std_logic;
rxEmpty_i : in std_logic;
rxRead_o : out std_logic;
rxType_i : in std_logic_vector(1 downto 0);
rxData_i : in std_logic_vector(31 downto 0);
rxControlValid_i : in std_logic;
rxControlSymbol_i : in std_logic_vector(23 downto 0);
rxDataValid_i : in std_logic;
rxDataSymbol_i : in std_logic_vector(31 downto 0);
 
-- Receiver has received a control symbol containing:
-- packet-accepted, packet-retry, packet-not-accepted,
1923,7 → 1945,7
txControlWrite_o : out std_logic;
txControlSymbol_o : out std_logic_vector(12 downto 0);
 
-- Reciever wants to signal the link partner:
-- Receiver wants to signal the link partner:
-- a new frame has been accepted => packet-accepted(rxAckId, bufferStatus)
-- a frame needs to be retransmitted due to buffering =>
-- packet-retry(rxAckId, bufferStatus)
1948,10 → 1970,6
ackId_o : out unsigned(4 downto 0);
frameIndex_i : in std_logic_vector(6 downto 0);
frameIndex_o : out std_logic_vector(6 downto 0);
frameWordCounter_i : in std_logic_vector(1 downto 0);
frameWordCounter_o : out std_logic_vector(1 downto 0);
frameContent_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0);
frameContent_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0);
crc_i : in std_logic_vector(15 downto 0);
crc_o : out std_logic_vector(15 downto 0);
1960,60 → 1978,28
writeFrame_o : out std_logic;
writeFrameAbort_o : out std_logic;
writeContent_o : out std_logic;
writeContentWords_o : out std_logic_vector(1 downto 0);
writeContentData_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0));
writeContentData_o : out std_logic_vector(32*NUMBER_SYMBOLS-1 downto 0));
end component;
 
signal enable : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal operationalCurrent, operationalNext : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal inputRetryStoppedCurrent, inputRetryStoppedNext : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal inputErrorStoppedCurrent, inputErrorStoppedNext : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal ackIdCurrent, ackIdNext : unsigned(5*NUMBER_WORDS-1 downto 0);
signal frameIndexCurrent, frameIndexNext : std_logic_vector(7*NUMBER_WORDS-1 downto 0);
signal frameWordCounterCurrent, frameWordCounterNext : std_logic_vector(2*NUMBER_WORDS-1 downto 0);
signal frameContentCurrent, frameContentNext : std_logic_vector(32*NUMBER_WORDS-1 downto 0);
signal crcCurrent, crcNext : std_logic_vector(16*NUMBER_WORDS-1 downto 0);
signal operationalCurrent, operationalNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal inputRetryStoppedCurrent, inputRetryStoppedNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal inputErrorStoppedCurrent, inputErrorStoppedNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal ackIdCurrent, ackIdNext : unsigned(5*NUMBER_SYMBOLS-1 downto 0);
signal frameIndexCurrent, frameIndexNext : std_logic_vector(7*NUMBER_SYMBOLS-1 downto 0);
signal crcCurrent, crcNext : std_logic_vector(16*NUMBER_SYMBOLS-1 downto 0);
 
signal txControlWrite : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal rxControlWrite : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal txControlWrite : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal rxControlWrite : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal writeFrame : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal writeFrameAbort : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal writeContent : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal writeContentWords : std_logic_vector(2*NUMBER_WORDS-1 downto 0);
signal writeContentData : std_logic_vector(32*NUMBER_WORDS-1 downto 0);
signal writeFrame : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal writeFrameAbort : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal writeContent : std_logic_vector(NUMBER_SYMBOLS-1 downto 0);
signal writeContentWords : std_logic_vector(2*NUMBER_SYMBOLS-1 downto 0);
signal writeContentData : std_logic_vector(32*NUMBER_SYMBOLS-1 downto 0);
 
begin
 
-----------------------------------------------------------------------------
-- Output generation to packet buffer.
-----------------------------------------------------------------------------
process(enable, writeFrame, writeFrameAbort,
writeContent, writeContentWords, writeContentData)
begin
writeFrame_o <= '0';
writeFrameAbort_o <= '0';
writeContent_o <= '0';
writeContentWords_o <= (others=>'0');
writeContentData_o <= (others=>'0');
for i in 0 to NUMBER_WORDS-1 loop
if ((writeFrame(i) = '1') and (enable(i) = '1')) then
writeFrame_o <= '1';
end if;
if ((writeFrameAbort(i) = '1') and (enable(i) = '1')) then
writeFrameAbort_o <= '1';
end if;
 
if ((writeContent(i) = '1') and (enable(i) = '1')) then
writeContent_o <= '1';
writeContentWords_o <= writeContentWords(2*(i+1)-1 downto 2*i);
writeContentData_o <= writeContentData(32*(i+1)-1 downto 32*i);
end if;
end loop;
end process;
 
-----------------------------------------------------------------------------
-- Protocol core and synchronization.
-----------------------------------------------------------------------------
process(clk, areset_n)
2024,41 → 2010,38
inputErrorStoppedCurrent <= (others=>'0');
ackIdCurrent <= (others=>'0');
frameIndexCurrent <= (others => '0');
frameWordCounterCurrent <= (others=>'0');
frameContentCurrent <= (others=>'0');
crcCurrent <= (others=>'0');
elsif (clk'event and clk = '1') then
if (enable(0) = '1') then
if (enable = '1') then
operationalCurrent <= operationalNext;
inputRetryStoppedCurrent <= inputRetryStoppedNext;
inputErrorStoppedCurrent <= inputErrorStoppedNext;
ackIdCurrent <= ackIdNext;
frameIndexCurrent <= frameIndexNext;
frameWordCounterCurrent <= frameWordCounterNext;
frameContentCurrent <= frameContentNext;
crcCurrent <= crcNext;
end if;
end if;
end process;
 
CoreGeneration: for i in 0 to NUMBER_WORDS-1 generate
txControlWrite_o(i) <= txControlWrite(i) and enable(i);
CoreGeneration: for i in 0 to NUMBER_SYMBOLS-1 generate
txControlWrite_o(i) <= txControlWrite(i);
rxControlWrite_o(i) <= rxControlWrite(i);
ReceiverCore: RioReceiverCore
generic map(NUMBER_WORDS=>NUMBER_WORDS)
generic map(NUMBER_SYMBOLS=>NUMBER_SYMBOLS)
port map(
clk=>clk,
areset_n=>areset_n,
enable=>enable,
portEnable_i=>portEnable_i,
localAckIdWrite_i=>localAckIdWrite_i,
inboundAckId_i=>inboundAckId_i,
inboundAckId_o=>inboundAckId_o,
portInitialized_i=>portInitialized_i,
rxEmpty_i=>rxEmpty_i,
rxRead_o=>rxRead_o,
rxType_i=>rxType_i,
rxData_i=>rxData_i,
rxControlValid_i=>rxControlValid_i,
rxControlSymbol_i=>rxControlSymbol_i,
rxDataValid_i=>rxDataValid_i,
rxDataSymbol_i=>rxDataSymbol_i,
txControlWrite_o=>txControlWrite(i),
txControlSymbol_o=>txControlSymbol_o(13*(i+1)-1 downto 13*i),
rxControlWrite_o=>rxControlWrite(i),
2065,7 → 2048,6
rxControlSymbol_o=>rxControlSymbol_o(13*(i+1)-1 downto 13*i),
ackIdStatus_o=>ackIdStatus_o,
linkInitialized_o=>linkInitialized_o,
enable_o=>enable(i),
operational_i=>operationalCurrent(i),
operational_o=>operationalNext(i),
inputRetryStopped_i=>inputRetryStoppedCurrent(i),
2076,18 → 2058,13
ackId_o=>ackIdNext(5*(i+1)-1 downto 5*i),
frameIndex_i=>frameIndexCurrent(7*(i+1)-1 downto 7*i),
frameIndex_o=>frameIndexNext(7*(i+1)-1 downto 7*i),
frameWordCounter_i=>frameWordCounterCurrent(2*(i+1)-1 downto 2*i),
frameWordCounter_o=>frameWordCounterNext(2*(i+1)-1 downto 2*i),
frameContent_i=>frameContentCurrent(32*(i+1)-1 downto 32*i),
frameContent_o=>frameContentNext(32*(i+1)-1 downto 32*i),
crc_i=>crcCurrent(16*(i+1)-1 downto 16*i),
crc_o=>crcNext(16*(i+1)-1 downto 16*i),
writeFrameFull_i=>writeFrameFull_i,
writeFrame_o=>writeFrame(i),
writeFrameAbort_o=>writeFrameAbort(i),
writeContent_o=>writeContent(i),
writeContentWords_o=>writeContentWords(2*(i+1)-1 downto 2*i),
writeContentData_o=>writeContentData(32*(i+1)-1 downto 32*i));
writeFrame_o=>writeFrame_o,
writeFrameAbort_o=>writeFrameAbort_o,
writeContent_o=>writeContent_o,
writeContentData_o=>writeContentData_o(32*(i+1)-1 downto 32*i));
end generate;
end architecture;
2106,10 → 2083,11
-------------------------------------------------------------------------------
entity RioReceiverCore is
generic(
NUMBER_WORDS : natural range 1 to 4 := 1);
NUMBER_SYMBOLS : natural range 1 to 1 := 1);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
-- Status signals used for maintenance.
portEnable_i : in std_logic;
2122,10 → 2100,10
-- Port input interface.
portInitialized_i : in std_logic;
rxEmpty_i : in std_logic;
rxRead_o : out std_logic;
rxType_i : in std_logic_vector(1 downto 0);
rxData_i : in std_logic_vector(31 downto 0);
rxControlValid_i : in std_logic;
rxControlSymbol_i : in std_logic_vector(23 downto 0);
rxDataValid_i : in std_logic;
rxDataSymbol_i : in std_logic_vector(31 downto 0);
 
-- Receiver has received a control symbol containing:
-- packet-accepted, packet-retry, packet-not-accepted,
2147,7 → 2125,6
linkInitialized_o : out std_logic;
 
-- Core->Core cascading signals.
enable_o : out std_logic;
operational_i : in std_logic;
operational_o : out std_logic;
inputRetryStopped_i : in std_logic;
2158,10 → 2135,6
ackId_o : out unsigned(4 downto 0);
frameIndex_i : in std_logic_vector(6 downto 0);
frameIndex_o : out std_logic_vector(6 downto 0);
frameWordCounter_i : in std_logic_vector(1 downto 0);
frameWordCounter_o : out std_logic_vector(1 downto 0);
frameContent_i : in std_logic_vector(32*NUMBER_WORDS-1 downto 0);
frameContent_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0);
crc_i : in std_logic_vector(15 downto 0);
crc_o : out std_logic_vector(15 downto 0);
2170,8 → 2143,7
writeFrame_o : out std_logic;
writeFrameAbort_o : out std_logic;
writeContent_o : out std_logic;
writeContentWords_o : out std_logic_vector(1 downto 0);
writeContentData_o : out std_logic_vector(32*NUMBER_WORDS-1 downto 0));
writeContentData_o : out std_logic_vector(32*NUMBER_SYMBOLS-1 downto 0));
end entity;
 
 
2193,31 → 2165,37
crc_o : out std_logic_vector(15 downto 0));
end component;
 
signal symbolEnable0, symbolEnable1 : std_logic;
signal symbolType0 : std_logic_vector(1 downto 0);
signal symbolContent0, symbolContent1 : std_logic_vector(31 downto 0);
signal crc5 : std_logic_vector(4 downto 0);
signal crc5Valid : std_logic;
signal crc5 : std_logic_vector(4 downto 0);
 
signal symbolValid : std_logic;
signal symbolErrorValid0 : std_logic;
signal symbolControlValid0 : std_logic;
signal symbolControlContent0 : std_logic_vector(23 downto 0);
signal symbolDataValid0 : std_logic;
signal symbolDataContent0 : std_logic_vector(31 downto 0);
signal symbolErrorValid1 : std_logic;
signal symbolControlCrcValid1 : std_logic;
signal symbolControlValid1 : std_logic;
signal symbolControlContent1 : std_logic_vector(23 downto 0);
signal symbolDataValid1 : std_logic;
signal symbolDataContent1 : std_logic_vector(31 downto 0);
signal stype0Status : std_logic;
signal stype1Start : std_logic;
signal stype1End : std_logic;
signal stype1Stomp : std_logic;
signal stype1Restart : std_logic;
signal stype1RestartFromRetry : std_logic;
signal stype1LinkRequest : std_logic;
signal symbolData : std_logic;
 
signal writeFrameOut : std_logic;
signal writeFrameAbortOut : std_logic;
signal writeContentOut : std_logic;
signal crc16Data : std_logic_vector(31 downto 0);
signal crc16Current : std_logic_vector(15 downto 0);
signal crc16Temp : std_logic_vector(15 downto 0);
signal crc16Next : std_logic_vector(15 downto 0);
signal crc16Valid : std_logic;
 
signal frameContent : std_logic_vector(32*NUMBER_WORDS-1 downto 0);
 
signal rxControlWrite : std_logic;
signal rxControlSymbol : std_logic_vector(12 downto 0);
signal rxControlWriteOut : std_logic;
signal rxControlSymbolOut : std_logic_vector(12 downto 0);
begin
 
2231,31 → 2209,36
-- symbol content for the next stage.
-----------------------------------------------------------------------------
 
-- Read the fifo immediatly.
rxRead_o <= not rxEmpty_i;
 
Crc5Calculator: Crc5ITU
port map(
d_i=>rxData_i(31 downto 13), crc_o=>crc5);
port map(d_i=>rxControlSymbol_i(23 downto 5), crc_o=>crc5);
 
process(clk, areset_n)
begin
if (areset_n = '0') then
crc5Valid <= '0';
symbolType0 <= (others => '0');
symbolContent0 <= (others => '0');
symbolErrorValid0 <= '0';
symbolControlValid0 <= '0';
symbolControlContent0 <= (others=>'0');
symbolDataValid0 <= '0';
symbolDataContent0 <= (others=>'0');
elsif (clk'event and clk = '1') then
if (rxEmpty_i = '0') then
if (crc5 = rxData_i(12 downto 8)) then
if (enable = '1') then
if (crc5 = rxControlSymbol_i(4 downto 0)) then
crc5Valid <= '1';
else
crc5Valid <= '0';
end if;
symbolEnable0 <= '1';
symbolType0 <= rxType_i;
symbolContent0 <= rxData_i;
else
symbolEnable0 <= '0';
if (rxControlValid_i = '1') and (rxDataValid_i = '1') then
symbolErrorValid0 <= '1';
symbolControlValid0 <= '0';
symbolDataValid0 <= '0';
else
symbolErrorValid0 <= '0';
symbolControlValid0 <= rxControlValid_i;
symbolControlContent0 <= rxControlSymbol_i;
symbolDataValid0 <= rxDataValid_i;
symbolDataContent0 <= rxDataSymbol_i;
end if;
end if;
end if;
end process;
2272,79 → 2255,71
txControlWrite_o <= '0';
txControlSymbol_o <= (others => '0');
 
symbolValid <= '0';
symbolErrorValid1 <= '0';
symbolControlCrcValid1 <= '0';
symbolControlValid1 <= '0';
symbolControlContent1 <= (others => '0');
symbolDataValid1 <= '0';
symbolDataContent1 <= (others=>'0');
 
stype0Status <= '0';
stype1Start <= '0';
stype1End <= '0';
stype1Stomp <= '0';
stype1Restart <= '0';
stype1RestartFromRetry <= '0';
stype1LinkRequest <= '0';
symbolData <= '0';
symbolContent1 <= (others => '0');
elsif (clk'event and clk = '1') then
if (symbolEnable0 = '1') then
symbolEnable1 <= '1';
symbolContent1 <= symbolContent0;
if (enable = '1') then
symbolErrorValid1 <= symbolErrorValid0;
if (symbolType0 = SYMBOL_CONTROL) then
symbolControlCrcValid1 <= crc5Valid;
symbolControlValid1 <= symbolControlValid0;
symbolControlContent1 <= symbolControlContent0;
symbolDataValid1 <= symbolDataValid0;
symbolDataContent1 <= symbolDataContent0;
 
txControlWrite_o <= '0';
txControlSymbol_o <= symbolControlContent0(23 downto 11);
if (symbolControlValid0 = '1') then
if (crc5Valid = '1') then
-- REMARK: Check if stype0 is nop and dont forward it???
symbolValid <= '1';
-- Forward the part of the control-symbol that are targeted to the
-- transmitter.
txControlWrite_o <= '1';
txControlSymbol_o <= symbolContent0(31 downto 19);
end if;
if (symbolControlContent0(23 downto 21) = STYPE0_STATUS) then
stype0Status <= '1';
else
symbolValid <= '0';
txControlWrite_o <= '0';
txControlSymbol_o <= (others => '0');
stype0Status <= '0';
end if;
else
symbolValid <= '1';
if (symbolControlContent0(10 downto 8) = STYPE1_START_OF_PACKET) then
stype1Start <= '1';
else
stype1Start <= '0';
end if;
if (symbolControlContent0(10 downto 8) = STYPE1_END_OF_PACKET) then
stype1End <= '1';
else
stype1End <= '0';
end if;
if (symbolControlContent0(10 downto 8) = STYPE1_STOMP) then
stype1Stomp <= '1';
else
stype1Stomp <= '0';
end if;
if (symbolControlContent0(10 downto 8) = STYPE1_RESTART_FROM_RETRY) then
stype1RestartFromRetry <= '1';
else
stype1RestartFromRetry <= '0';
end if;
if (symbolControlContent0(10 downto 8) = STYPE1_LINK_REQUEST) then
stype1LinkRequest <= '1';
else
stype1LinkRequest <= '0';
end if;
end if;
if ((symbolType0 = SYMBOL_CONTROL) and
(symbolContent0(31 downto 29) = STYPE0_STATUS)) then
stype0Status <= '1';
else
stype0Status <= '0';
end if;
if ((symbolType0 = SYMBOL_CONTROL) and
(symbolContent0(18 downto 16) = STYPE1_START_OF_PACKET)) then
stype1Start <= '1';
else
stype1Start <= '0';
end if;
if ((symbolType0 = SYMBOL_CONTROL) and
(symbolContent0(18 downto 16) = STYPE1_END_OF_PACKET)) then
stype1End <= '1';
else
stype1End <= '0';
end if;
if ((symbolType0 = SYMBOL_CONTROL) and
(symbolContent0(18 downto 16) = STYPE1_STOMP)) then
stype1Stomp <= '1';
else
stype1Stomp <= '0';
end if;
if ((symbolType0 = SYMBOL_CONTROL) and
(symbolContent0(18 downto 16) = STYPE1_RESTART_FROM_RETRY)) then
stype1Restart <= '1';
else
stype1Restart <= '0';
end if;
if ((symbolType0 = SYMBOL_CONTROL) and
(symbolContent0(18 downto 16) = STYPE1_LINK_REQUEST)) then
stype1LinkRequest <= '1';
else
stype1LinkRequest <= '0';
end if;
if (symbolType0 = SYMBOL_DATA) then
symbolData <= '1';
else
symbolData <= '0';
end if;
else
symbolEnable1 <= '0';
end if;
end if;
end process;
2356,23 → 2331,22
-- Update the main receiver state machine.
-- Generate reply symbols to the link-partner.
-----------------------------------------------------------------------------
 
-- Set the output to save when writing new frame content.
writeFrame_o <= writeFrameOut and enable;
writeFrameAbort_o <= writeFrameAbortOut and enable;
writeContent_o <= writeContentOut and enable;
writeContentData_o <= symbolDataContent1;
-----------------------------------------------------------------------------
-- CRC-calculation.
-- Add a data symbol to the calculated CRC for the packet.
-- controlSymbol->just forward old crc16.
-- first data-symbol in packet->crc_o is product of 11111 and the
-- symbolContent1 without ackid.
-- not first data-symbol->crc_o is product of crc_i and symbolContent1.
-----------------------------------------------------------------------------
 
-- Create the new input depending on the current frame position.
crc16Data(31 downto 26) <= "000000" when (unsigned(frameIndex_i) = 1) else
symbolContent1(31 downto 26);
crc16Data(25 downto 0) <= symbolContent1(25 downto 0);
symbolDataContent1(31 downto 26);
crc16Data(25 downto 0) <= symbolDataContent1(25 downto 0);
 
crc16Current <= crc_i when (unsigned(frameIndex_i) /= 1) else
(others => '1');
-- Initialize the crc at frame start.
crc16Current <= crc_i when (unsigned(frameIndex_i) /= 1) else (others => '1');
 
-- Crc calculation units.
Crc16Msb: Crc16CITT
port map(
d_i=>crc16Data(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp);
2380,61 → 2354,34
port map(
d_i=>crc16Data(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next);
 
crc_o <= crc_i when (symbolData = '0') else
crc16Next;
-- Save the new CRC value when a dataSymbol was received.
crc_o <= crc_i when (symbolDataValid1 = '0') else crc16Next;
 
-- Check if the CRC is ok.
crc16Valid <= '1' when (crc_i = x"0000") else '0';
 
-----------------------------------------------------------------------------
-- Update buffered data.
-----------------------------------------------------------------------------
 
-- Append the new symbol content to the end of the
-- current frame content if the symbol is a data symbol.
frameContentSingle:
if (NUMBER_WORDS = 1) generate
frameContent <= symbolContent1;
end generate;
frameContentMulti:
if (NUMBER_WORDS > 1) generate
frameContent <=
(frameContent_i((32*(NUMBER_WORDS-1))-1 downto 0) & symbolContent1) when (symbolData = '1') else
frameContent_i;
end generate;
 
-- Update outputs.
enable_o <= symbolEnable1;
frameContent_o <= frameContent;
writeContentData_o <= frameContent;
-----------------------------------------------------------------------------
-- Main inbound symbol handler.
-----------------------------------------------------------------------------
-- The main protocol handling process.
process(portInitialized_i, portEnable_i, writeFrameFull_i,
operational_i, ackId_i, frameIndex_i, frameWordCounter_i,
operational_i, ackId_i, frameIndex_i,
inputRetryStopped_i, inputErrorStopped_i,
symbolValid,
symbolControlValid1, symbolControlCrcValid1, symbolControlContent1,
stype0Status,
stype1Start, stype1End, stype1Stomp, stype1Restart, stype1LinkRequest,
symbolData,
symbolContent1,
frameContent,
stype1Start, stype1End, stype1Stomp, stype1RestartFromRetry, stype1LinkRequest,
symbolDataValid1,
crc16Valid)
begin
operational_o <= operational_i;
ackId_o <= ackId_i;
frameIndex_o <= frameIndex_i;
frameWordCounter_o <= frameWordCounter_i;
inputRetryStopped_o <= inputRetryStopped_i;
inputErrorStopped_o <= inputErrorStopped_i;
ackId_o <= ackId_i;
rxControlWrite <= '0';
rxControlSymbol <= (others => '0');
rxControlWriteOut <= '0';
rxControlSymbolOut <= (others => '0');
writeFrame_o <= '0';
writeFrameAbort_o <= '0';
writeContent_o <= '0';
writeContentWords_o <= (others => '0');
writeFrameOut <= '0';
writeFrameAbortOut <= '0';
writeContentOut <= '0';
 
-- Act on the current state.
if (operational_i = '0') then
2445,13 → 2392,13
-- when enough of them has been received. Frames are not allowed
-- here.
---------------------------------------------------------------------
-- Check if the port is initialized.
if (portInitialized_i = '1') then
-- Port is initialized.
-- Check if the control symbol has a valid checksum.
if (symbolValid = '1') then
if (symbolControlCrcValid1 = '1') then
-- The control symbol has a valid checksum.
-- Check the stype0 part if we should count the number of
2463,12 → 2410,15
if (unsigned(frameIndex_i) = 7) then
-- Enough status symbols have been received.
 
-- Go to operational state and make sure all variables are
-- reset.
operational_o <= '1';
frameIndex_o <= (others => '0');
inputRetryStopped_o <= '0';
inputErrorStopped_o <= '0';
-- Reset all packets.
frameIndex_o <= (others => '0');
writeFrameAbort_o <= '1';
 
-- Set the link as initialized.
operational_o <= '1';
else
-- Increase the number of error-free status symbols that
-- has been received.
2496,12 → 2446,24
-- Check that the port is initialized.
if (portInitialized_i = '1') then
-- The port and link is initialized.
 
-- Check if an error has been detected by the PCS.
if (symbolErrorValid1 = '1') then
-- An error-symbol from the PCS has been received.
-- Send a packet-not-accepted and indicate the error.
rxControlWriteOut <= '1';
rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_INVALID_CHARACTER;
inputErrorStopped_o <= '1';
end if;
-- Check if the control symbol has a valid CRC-5.
if (symbolValid = '1') then
if (symbolControlCrcValid1 = '1') then
-- The symbol is correct.
 
if ((stype1Start = '1') and
-- Check if a packet is starting or ending.
if (((stype1Start = '1') or (stype1End = '1')) and
(inputRetryStopped_i = '0') and (inputErrorStopped_i = '0')) then
-------------------------------------------------------------
-- Start the reception of a new frame or end a currently
2509,28 → 2471,22
-------------------------------------------------------------
-- Check if a frame has already been started.
if (unsigned(frameIndex_i) /= 0) then
-- A frame is already started.
if ((unsigned(frameIndex_i) /= 0) or (stype1End = '1')) then
-- A frame is already started or is ending.
-- Complete the last frame and start to ackumulate a new one
-- and update the ackId.
 
-- Check if the frame is too short.
if (unsigned(frameIndex_i) > 3) then
-- The frame is not too short.
 
-- Reset the frame index to indicate the frame is started.
frameIndex_o <= "0000001";
frameWordCounter_o <= (others=>'0');
-- Check the CRC-16 and the length of the received frame.
if (crc16Valid = '1') then
-- The CRC-16 is ok.
 
-- Check if there are any unwritten buffered packet content
-- and write it if there is.
-- REMARK: Multi-symbol support...
if (unsigned(frameWordCounter_i) /= 0) then
writeContent_o <= '1';
end if;
-- Update the frame buffer to indicate that the frame has
-- been completly received.
writeFrame_o <= '1';
2541,120 → 2497,62
-- Send packet-accepted.
-- The buffer status is appended by the transmitter
-- when sent to get the latest number.
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_PACKET_ACCEPTED &
std_logic_vector(ackId_i) &
"11111";
-- REMARK: Move this out of this process and into pipeline
-- stage 4.
rxControlWriteOut <= '1';
rxControlSymbolOut <= STYPE0_PACKET_ACCEPTED &
std_logic_vector(ackId_i) &
"11111";
else
-- The CRC-16 is not ok.
 
-- Make the transmitter send a packet-not-accepted to indicate
-- that the received packet contained a CRC error.
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
rxControlWriteOut <= '1';
rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
inputErrorStopped_o <= '1';
end if;
else
-- This packet is too small.
-- The packet is too short.
-- Make the transmitter send a packet-not-accepted to indicated
-- that the received packet was too small.
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR;
rxControlWriteOut <= '1';
rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR;
inputErrorStopped_o <= '1';
end if;
else
-- No frame has been started.
-- This is the normal case when there was no frame started
-- before.
-- Reset the frame index to indicate the frame is started.
frameIndex_o <= "0000001";
frameWordCounter_o <= (others=>'0');
end if;
end if;
if ((stype1End = '1') and
(inputRetryStopped_i = '0') and (inputErrorStopped_i = '0')) then
-------------------------------------------------------------
-- End the reception of an old frame.
-------------------------------------------------------------
-- Check if a frame has already been started.
if (unsigned(frameIndex_i) > 3) then
-- A frame has been started and it is large enough.
-- Reset frame reception to indicate that no frame is ongoing.
frameIndex_o <= (others => '0');
-- Check the CRC-16 and the length of the received frame.
if (crc16Valid = '1') then
-- The CRC-16 is ok.
 
-- Check if there are any unwritten buffered packet content
-- and write it if there is.
-- REMARK: Multi-symbol support...
if (unsigned(frameWordCounter_i) /= 0) then
writeContent_o <= '1';
end if;
-- Update the frame buffer to indicate that the frame has
-- been completly received.
writeFrame_o <= '1';
 
-- Update ackId.
ackId_o <= ackId_i + 1;
 
-- Send packet-accepted.
-- The buffer status is appended by the transmitter
-- when sent to get the latest number.
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_PACKET_ACCEPTED &
std_logic_vector(ackId_i) &
"11111";
else
-- The CRC-16 is not ok.
 
-- Make the transmitter send a packet-not-accepted to indicate
-- that the received packet contained a CRC error.
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
inputErrorStopped_o <= '1';
end if;
else
-- This packet is too small.
-- Make the transmitter send a packet-not-accepted to indicate
-- that the received packet was too small.
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR;
inputErrorStopped_o <= '1';
end if;
end if;
 
if ((stype1Stomp = '1') and
(inputRetryStopped_i = '0') and (inputErrorStopped_i = '0')) then
-------------------------------------------------------------
-- Restart the reception of an old frame.
-------------------------------------------------------------
-- See 5.10 in the standard.
-- See 5.10 in the 2.2 standard.
-- Make the transmitter send a packet-retry to indicate
-- that the packet cannot be accepted.
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_PACKET_RETRY &
std_logic_vector(ackId_i) &
"11111";
rxControlWriteOut <= '1';
rxControlSymbolOut <= STYPE0_PACKET_RETRY &
std_logic_vector(ackId_i) &
"11111";
-- Enter the input retry-stopped state.
inputRetryStopped_o <= '1';
end if;
 
if (stype1Restart = '1') then
if (stype1RestartFromRetry = '1') then
if (inputRetryStopped_i = '1') then
-------------------------------------------------------------
-- The receiver indicates a restart from a retry sent
2678,10 → 2576,10
-- Send a packet-not-accepted to indicate that a protocol
-- error has occurred.
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR;
rxControlWriteOut <= '1';
rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR;
inputErrorStopped_o <= '1';
end if;
end if;
2692,27 → 2590,27
-------------------------------------------------------------
-- Check the command part.
if (symbolContent1(15 downto 13) = "100") then
if (symbolControlContent1(15 downto 13) = "100") then
-- Return input port status command.
-- This functions as a link-request(restart-from-error)
-- control symbol under error situations.
 
if (inputErrorStopped_i = '1') then
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_LINK_RESPONSE &
std_logic_vector(ackId_i) &
"00101";
rxControlWriteOut <= '1';
rxControlSymbolOut <= STYPE0_LINK_RESPONSE &
std_logic_vector(ackId_i) &
"00101";
elsif (inputRetryStopped_i = '1') then
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_LINK_RESPONSE &
std_logic_vector(ackId_i) &
"00100";
rxControlWriteOut <= '1';
rxControlSymbolOut <= STYPE0_LINK_RESPONSE &
std_logic_vector(ackId_i) &
"00100";
else
-- Send a link response containing an ok reply.
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_LINK_RESPONSE &
std_logic_vector(ackId_i) &
"10000";
rxControlWriteOut <= '1';
rxControlSymbolOut <= STYPE0_LINK_RESPONSE &
std_logic_vector(ackId_i) &
"10000";
end if;
else
-- Reset device command or other unsupported command.
2725,103 → 2623,90
frameIndex_o <= (others=>'0');
writeFrameAbort_o <= '1';
end if;
else
-- A control symbol contains a crc error.
 
if ((symbolData = '1') and
(inputRetryStopped_i = '0') and (inputErrorStopped_i = '0')) then
-------------------------------------------------------------
-- This is a data symbol.
-------------------------------------------------------------
-- REMARK: Add check for in-the-middle-crc here...
-- Send a packet-not-accepted to indicate that a corrupted
-- control-symbol has been received and change state.
rxControlWriteOut <= '1';
rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC;
inputErrorStopped_o <= '1';
end if;
if ((symbolDataValid1 = '1') and
(inputRetryStopped_i = '0') and (inputErrorStopped_i = '0')) then
-------------------------------------------------------------
-- This is a data symbol.
-------------------------------------------------------------
-- REMARK: Add check for in-the-middle-crc here...
 
case frameIndex_i is
when "0000000" | "1000110" =>
-- A frame has not been started or is too long.
-- Send packet-not-accepted.
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR;
inputErrorStopped_o <= '1';
when "0000001" =>
if (unsigned(symbolContent1(31 downto 27)) = ackId_i) then
if ((portEnable_i = '1') or
(symbolContent1(19 downto 16) = FTYPE_MAINTENANCE_CLASS)) then
case frameIndex_i is
when "0000000" | "1000110" =>
-- A frame has not been started or is too long.
-- Send packet-not-accepted.
rxControlWriteOut <= '1';
rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR;
inputErrorStopped_o <= '1';
when "0000001" =>
-- Check if the packet contains the correct ackId.
if (unsigned(symbolDataContent1(31 downto 27)) = ackId_i) then
-- The packet has a correct ackId.
-- Check if the packet is allowed.
if ((portEnable_i = '1') or
(symbolDataContent1(19 downto 16) = FTYPE_MAINTENANCE_CLASS)) then
-- The packet is allowed.
 
-- Check if there are buffers available to store the new
-- packet.
if (writeFrameFull_i = '0') then
-- There are buffering space available to store the new
-- data.
-- Check if the buffer entry is ready to be written
-- into the packet buffer.
-- REMARK: Multi-symbol support...
if (unsigned(frameWordCounter_i) = (NUMBER_WORDS-1)) then
-- Write the data to the frame FIFO.
frameWordCounter_o <= (others=>'0');
writeContent_o <= '1';
writeContentWords_o <= frameWordCounter_i;
else
frameWordCounter_o <= std_logic_vector(unsigned(frameWordCounter_i) + 1);
end if;
-- Increment the number of received data symbols.
frameIndex_o <= std_logic_vector(unsigned(frameIndex_i) + 1);
else
-- The packet buffer is full.
-- Let the link-partner resend the packet.
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_PACKET_RETRY &
std_logic_vector(ackId_i) &
"11111";
inputRetryStopped_o <= '1';
end if;
-- Check if there are buffers available to store the new
-- packet.
if (writeFrameFull_i = '0') then
-- There are buffering space available to store the new
-- data.
-- Write the symbol content and increment the number of
-- received data symbols.
writeContent_o <= '1';
frameIndex_o <= std_logic_vector(unsigned(frameIndex_i) + 1);
else
-- A non-maintenance packets are not allowed.
-- Send packet-not-accepted.
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_NON_MAINTENANCE_STOPPED;
inputErrorStopped_o <= '1';
-- The packet buffer is full.
-- Let the link-partner resend the packet.
rxControlWriteOut <= '1';
rxControlSymbolOut <= STYPE0_PACKET_RETRY &
std_logic_vector(ackId_i) &
"11111";
inputRetryStopped_o <= '1';
end if;
else
-- The ackId is unexpected.
-- A non-maintenance packet is not allowed.
-- Send packet-not-accepted.
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID;
rxControlWriteOut <= '1';
rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_NON_MAINTENANCE_STOPPED;
inputErrorStopped_o <= '1';
end if;
when others =>
-- A frame has been started and is not too long.
-- Check if the buffer entry is ready to be written
-- into the packet buffer.
-- REMARK: Multi-symbol support...
if (unsigned(frameWordCounter_i) = (NUMBER_WORDS-1)) then
-- Write the data to the frame FIFO.
frameWordCounter_o <= (others=>'0');
writeContent_o <= '1';
writeContentWords_o <= frameWordCounter_i;
else
frameWordCounter_o <= std_logic_vector(unsigned(frameWordCounter_i) + 1);
end if;
else
-- The ackId is unexpected.
-- Send packet-not-accepted.
rxControlWriteOut <= '1';
rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID;
inputErrorStopped_o <= '1';
end if;
when others =>
-- A frame has been started and is not too long.
-- Check if the buffer entry is ready to be written
-- into the packet buffer.
writeContent_o <= '1';
 
-- Increment the number of received data symbols.
frameIndex_o <= std_logic_vector(unsigned(frameIndex_i) + 1);
end case;
end if;
else
-- A control symbol contains a crc error.
 
-- Send a packet-not-accepted to indicate that a corrupted
-- control-symbol has been received and change state.
rxControlWrite <= '1';
rxControlSymbol <= STYPE0_PACKET_NOT_ACCEPTED &
"00000" &
PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC;
inputErrorStopped_o <= '1';
-- Increment the number of received data symbols.
frameIndex_o <= std_logic_vector(unsigned(frameIndex_i) + 1);
end case;
end if;
else
-- The port has become uninitialized.
2831,13 → 2716,7
end if;
end process;
 
-----------------------------------------------------------------------------
-- Fourth pipeline stage.
-----------------------------------------------------------------------------
-- REMARK: Do more stuff in this stage, convert a one-hot to the symbol to
-- send...
-- REMARK: Register other outputs here like writeContent_o...
 
-- REMARK: Add writeContentXXX-registers...
process(clk, areset_n)
begin
if (areset_n = '0') then
2844,8 → 2723,10
rxControlWrite_o <= '0';
rxControlSymbol_o <= (others=>'0');
elsif (clk'event and clk = '1') then
rxControlWrite_o <= rxControlWrite and symbolEnable1;
rxControlSymbol_o <= rxControlSymbol;
if (enable = '1') then
rxControlWrite_o <= rxControlWriteOut and symbolControlValid1;
rxControlSymbol_o <= rxControlSymbolOut;
end if;
end if;
end process;
3023,85 → 2904,3
crc_o(4) <= c(0); crc_o(3) <= c(1); crc_o(2) <= c(2); crc_o(1) <= c(3);
crc_o(0) <= c(4);
end architecture;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
entity Crc16Calculator is
generic (
NUMBER_WORDS : natural range 1 to 8 := 1);
 
port (
clk : in std_logic;
areset_n : in std_logic;
write_i : in std_logic;
crc_i : in std_logic_vector(15 downto 0);
data_i : in std_logic_vector((32*NUMBER_WORDS)-1 downto 0);
 
crc_o : out std_logic_vector(15 downto 0);
done_o : out std_logic);
 
end Crc16Calculator;
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture Crc16CalculatorImpl of Crc16Calculator is
 
component Crc16CITT is
port(
d_i : in std_logic_vector(15 downto 0);
crc_i : in std_logic_vector(15 downto 0);
crc_o : out std_logic_vector(15 downto 0));
end component;
 
signal iterator : natural range 0 to 2*NUMBER_WORDS;
signal crcData : std_logic_vector((32*NUMBER_WORDS)-1 downto 0);
signal crcCurrent : std_logic_vector(15 downto 0);
signal crcNext : std_logic_vector(15 downto 0);
begin
 
process(areset_n, clk)
begin
if (areset_n = '0') then
iterator <= 0;
done_o <= '0';
crc_o <= (others => '0');
elsif (clk'event and clk = '1') then
if (write_i = '1') then
iterator <= 2*NUMBER_WORDS-1;
crcData <= data_i;
crcCurrent <= crc_i;
done_o <= '0';
else
if (iterator /= 0) then
iterator <= iterator - 1;
crcData <= crcData(((32*NUMBER_WORDS)-1)-16 downto 0) & x"0000";
crcCurrent <= crcNext;
else
crc_o <= crcNext;
done_o <= '1';
end if;
end if;
end if;
end process;
Crc16Inst: Crc16CITT
port map(
d_i=>crcData((32*NUMBER_WORDS)-1 downto (32*NUMBER_WORDS)-16),
crc_i=>crcCurrent, crc_o=>crcNext);
end architecture;
/rio/branches/singleSymbol/rtl/vhdl/RioLogicalCommon.vhd
2,14 → 2,16
-- RioLogicalCommon.
-------------------------------------------------------------------------------
-- Ingress:
-- * Removes in-the-middle-CRC.
-- * Removes in-the-middle and trailing CRC.
-- * Forwards packets to logical-layer handlers depending on ftype and
-- transaction (output as address).
-- * Outputs header and deviceIDs in seperate accesses to facilitate 8- and
-- 16-bit deviceAddress support. All fields are right-justified.
-- Egress:
-- * Adds CRC.
-- * Adds in-the-middle and trailing CRC.
-- * Receives packets from logical-layer handlers.
-- * Receives header and deviceIDs in seperate accesses to facilitate 8- and
-- 16-bit deviceAddress support. All fields are right-justified.
-------------------------------------------------------------------------------
-- REMARK: Egress; Places packets in different queues depending on the packet priority?
-- REMARK: Use inputOutput/message/maintenance/gsm/...-strobes instead?
83,6 → 85,7
-------------------------------------------------------------------------------
-- RioLogicalCommonIngress.
-------------------------------------------------------------------------------
-- REMARK: Check the destination address to see if it matches the one configured???
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
104,8 → 107,9
 
masterCyc_o : out std_logic;
masterStb_o : out std_logic;
masterAddress_o : out std_logic_vector(7 downto 0);
masterData_o : out std_logic_vector(31 downto 0);
masterAdr_o : out std_logic_vector(7 downto 0);
masterSel_o : out std_logic_vector(3 downto 0);
masterDat_o : out std_logic_vector(31 downto 0);
masterAck_i : in std_logic);
end entity;
 
175,8 → 179,9
--
---------------------------------------------------------------------
masterStb_o <= '1';
masterAddress_o <= ftype & transaction;
masterData_o <= x"0000" & packetContent(63 downto 48);
masterAdr_o <= ftype & transaction;
masterSel_o <= x"0011";
masterDat_o <= x"0000" & packetContent(63 downto 48);
packetContent <= packetContent(47 downto 0) & x"0000";
 
state <= SEND_DESTINATION;
187,10 → 192,12
---------------------------------------------------------------------
if (masterAck_i = '1') then
if (tt = "00") then
masterData_o <= x"000000" & packetContent(63 downto 56);
masterSel_o <= x"0001";
masterDat_o <= x"000000" & packetContent(63 downto 56);
packetContent <= packetContent(55 downto 0) & x"00";
elsif (tt = "01") then
masterData_o <= x"0000" & packetContent(63 downto 48);
masterSel_o <= x"0011";
masterDat_o <= x"0000" & packetContent(63 downto 48);
packetContent <= packetContent(31 downto 0) & readContentData_i;
readContent_o <= '1';
end if;
204,10 → 211,12
---------------------------------------------------------------------
if (masterAck_i = '1') then
if (tt = "00") then
masterData_o <= x"000000" & packetContent(63 downto 56);
masterSel_o <= x"0001";
masterDat_o <= x"000000" & packetContent(63 downto 56);
packetContent <= packetContent(55 downto 0) & x"00";
elsif (tt = "01") then
masterData_o <= x"0000" & packetContent(63 downto 48);
masterSel_o <= x"0011";
masterDat_o <= x"0000" & packetContent(63 downto 48);
packetContent <= packetContent(47 downto 0) & x"0000";
end if;
 
219,7 → 228,8
--
---------------------------------------------------------------------
if (masterAck_i = '1') then
masterData_o <= packetContent(63 downto 32);
masterSel_o <= x"1111";
masterDat_o <= packetContent(63 downto 32);
 
packetPosition <= packetPosition + 1;
 
248,8 → 258,10
---------------------------------------------------------------------
--
---------------------------------------------------------------------
-- REMARK: The last always contain the CRC?
if (masterAck_i = '1') then
masterData_o <= packetContent(63 downto 32);
masterSel_o <= x"1111";
masterDat_o <= packetContent(63 downto 32);
state <= END_PACKET;
end if;
339,9 → 351,9
---------------------------------------------------------------------
--
---------------------------------------------------------------------
packetPosition <= 0;
if (writeFrameFull_i = '0') then
state <= HEADER_GET;
packetPosition <= 0;
crc16Current <= x"ffff";
end if;
 
361,7 → 373,7
header <= slaveData_i(15 downto 0);
tt <= slaveData_i(5 downto 4);
else
-- Not supported.
-- REMARK: Not supported.
end if;
slaveAck_o <= '1';
608,7 → 620,6
port map(
d_i=>writeContentData(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next);
 
 
end architecture;
 
 
625,6 → 636,7
use ieee.numeric_std.all;
use work.rio_common.all;
 
 
-------------------------------------------------------------------------------
-- Entity for RioLogicalMaintenanceRequest.
-------------------------------------------------------------------------------
641,6 → 653,14
clk : in std_logic;
areset_n : in std_logic;
 
configStb_o : out std_logic;
configWe_o : out std_logic;
configAdr_o : out std_logic_vector(23 downto 0);
configDat_o : out std_logic_vector(63 downto 0);
configSel_o : out std_logic_vector(7 downto 0);
configDat_i : in std_logic_vector(63 downto 0);
configAck_i : in std_logic;
slaveCyc_i : in std_logic;
slaveStb_i : in std_logic;
slaveAdr_i : in std_logic_vector(7 downto 0);
649,12 → 669,27
 
masterCyc_o : out std_logic;
masterStb_o : out std_logic;
masterSel_o : out std_logic_vector(3 downto 0);
masterDat_o : out std_logic_vector(31 downto 0);
masterAck_i : in std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture RioLogicalMaintenanceRequest of RioLogicalMaintenanceRequest is
component MemorySinglePort is
generic(
ADDRESS_WIDTH : natural := 1;
DATA_WIDTH : natural := 1);
port(
clk_i : in std_logic;
enable_i : in std_logic;
writeEnable_i : in std_logic;
address_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
data_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
data_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
end component;
begin
 
664,198 → 699,529
if (areset_n = '0') then
 
elsif (clk'event and clk = '1') then
if (slaveCyc_i = '0') then
packetIndex <= 0;
elsif (slaveStb_i = '1') then
if (slaveAck = '0') then
if (slaveAddress_i = x"80") then
-- Maintenance read request.
case state is
when WAIT_PACKET =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (slaveCyc_i = '1') then
if (slaveAck = '0') then
if (slaveStb_i = '1') then
if (slaveAddress_i = x"80") then
-- Maintenance read request.
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
header <= slaveDat_i(15 downto 0);
when 1 =>
-- destId
destId <= slaveDat_i;
when 2 =>
-- srcId
srcId <= slaveDat_i;
when 3 =>
-- transaction & rdsize & srcTID & hop & config_offset(20:13)
size <= slaveDat_i(27 downto 24);
srcTid <= slaveDat_i(23 downto 16);
configOffset(20 downto 13) <= slaveDat_i(7 downto 0);
when 4 =>
-- config_offset(12:0) & wdptr & rsrv & crc(15:0)
configOffset(12 downto 0) <= slaveDat_i(31 downto 16);
wdptr <= slaveDat_i(18);
maintReadComplete <= '1';
when others =>
-- There should be no more content in a maintenance read request.
-- Discard.
end case;
elsif (slaveAddress_i = x"81") then
-- Maintenance write request.
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
header <= slaveDat_i(15 downto 0);
when 1 =>
-- destId
destId <= slaveDat_i;
when 2 =>
-- srcId
srcId <= slaveDat_i;
when 3 =>
-- transaction & wrsize & srcTID & hop & config_offset(20:13)
size <= slaveDat_i(27 downto 24);
srcTid <= slaveDat_i(23 downto 16);
configOffset(20 downto 13) <= slaveDat_i(7 downto 0);
when 4 =>
-- config_offset(12:0) & wdptr & rsrv & double-word(63:48)
configOffset(12 downto 0) <= slaveDat_i(31 downto 16);
configData(63 downto 48) <= slaveData_i(15 downto 0);
wdptr <= slaveDat_i(18);
memoryEnable <= '1';
memoryAddress <= 0;
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 =>
-- double-word(47:16)
configData(47 downto 16) <= slaveData_i;
when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 =>
-- double-word(15:0) & double-word(63:48)
memoryAddress <= memoryAddress + 1;
memoryWrite <= '1';
memoryDataIn <= configData(63 downto 16) & slaveData_i(31 downto 16);
configData(63 downto 48) <= slaveData_i(15 downto 0);
maintWriteComplete <= '1';
when others =>
-- There should be no more content in a maintenance read request.
-- Discard.
end case;
end if;
slaveAck <= '1';
end if;
else
packetIndex <= packetIndex + 1;
slaveAck <= '0';
end if;
else
if (maintReadComplete = '1') then
state <= CONFIG_READ;
configIterator <= bytes;
memoryEnable <= '1';
memoryAddress <= 0;
end if;
if (maintWriteComplete = '1') then
state <= CONFIG_WRITE;
end if;
packetIndex <= 0;
maintReadComplete <= '0';
maintWriteComplete <= '0';
end if;
 
when CONFIG_READ =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
configStb_o <= '1';
configWe_o <= '0';
configAdr_o <= configOffset;
configSel_o <= byteLanes;
configIterator <= configIterator - 1;
configSpaceState <= CONFIG_READ_ACK;
 
when CONFIG_READ_ACK =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (configAck_i = '1') then
memoryAddress <= memoryAddress + 1;
memoryWrite <= '1';
memoryDataIn <= configSpaceDat_i;
if (configIterator /= 0) then
configAdr_o <= configAdr_o + 1;
state <= CONFIG_READ;
else
configStb_o <= '0';
packetIndex <= 0;
state <= CONFIG_READ_RESPONSE;
end if;
end if;
 
when CONFIG_READ_RESPONSE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
masterCyc_o <= '1';
masterStb_o <= '1';
masterDat_o <= header;
packetIndex <= packetIndex + 1;
state <= CONFIG_READ_RESPONSE_ACK;
 
when CONFIG_READ_RESPONSE_ACK =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (masterAck_i = '1') then
masterCyc_o <= '1';
masterStb_o <= '1';
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
masterDat_o <= header;
when 1 =>
-- destId
-- destination is the source.
masterDat_o <= srcId;
when 2 =>
-- srcId
-- source is the destination.
masterDat_o <= destId;
when 3 =>
-- transaction & rdsize & srcTID & hop & config_offset(20:13)
-- transaction & status & targetTID & hop & reserved(7:0)
masterDat_o <= "0010" & "0000" & srcTid & x"ff" & x"00";
when 4 =>
-- config_offset(12:0) & wdptr & rsrv & crc(15:0)
when others =>
-- REMARK: Larger packets not supported.
end case;
elsif (slaveAddress_i = x"81") then
-- Maintenance write request.
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
when 1 =>
-- destId
when 2 =>
-- srcId
when 3 =>
-- transaction & wrsize & srcTID & hop & config_offset(20:13)
when 4 =>
-- config_offset(12:0) & wdptr & rsrv & double-word(63:48)
-- reserved(15:0) & double-word0(63:32)
masterDat_o <= x"0000" & memoryDataOut(63 downto 32);
when 5 =>
-- double-word(47:16)
when 6 =>
-- double-word(15:0) & crc(15:0)
masterDat_o <= memoryDataOut(31 downto 0) & x"0000";
-- REMARK: Add more here to send the full response...
when others =>
-- REMARK: Larger packets not supported.
state <= WAIT_PACKET;
end case;
packetIndex <= packetIndex + 1;
end if;
slaveAck <= '1';
else
packetIndex <= packetIndex + 1;
slaveAck <= '0';
end if;
end if;
 
when CONFIG_WRITE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
 
when others =>
 
end case;
end if;
end process;
 
-----------------------------------------------------------------------------
--
-----------------------------------------------------------------------------
-- REMARK: Make this a common component?
-- REMARK: Change bytes to double-words?
process(wdptr, size)
begin
case (wdptr & size) is
when "00000" =>
bytes <= 1;
byteLanes <= "10000000";
when "00001" =>
bytes <= 1;
byteLanes <= "01000000";
when "00010" =>
bytes <= 1;
byteLanes <= "00100000";
when "00011" =>
bytes <= 1;
byteLanes <= "00010000";
when "10000" =>
bytes <= 1;
byteLanes <= "00001000";
when "10001" =>
bytes <= 1;
byteLanes <= "00000100";
when "10010" =>
bytes <= 1;
byteLanes <= "00000010";
when "10011" =>
bytes <= 1;
byteLanes <= "00000001";
when "00100" =>
bytes <= 2;
byteLanes <= "11000000";
when "00101" =>
bytes <= 3;
byteLanes <= "11100000";
when "00110" =>
bytes <= 2;
byteLanes <= "00110000";
when "00111" =>
bytes <= 5;
byteLanes <= "11111000";
when "10100" =>
bytes <= 2;
byteLanes <= "00001100";
when "10101" =>
bytes <= 3;
byteLanes <= "00000111";
when "10110" =>
bytes <= 2;
byteLanes <= "00000011";
when "10111" =>
bytes <= 5;
byteLanes <= "00011111";
when "01000" =>
bytes <= 4;
byteLanes <= "11110000";
when "11000" =>
bytes <= 4;
byteLanes <= "00001111";
when "01001" =>
bytes <= 6;
byteLanes <= "11111100";
when "11001" =>
bytes <= 6;
byteLanes <= "00111111";
when "01010" =>
bytes <= 7;
byteLanes <= "11111110";
when "11010" =>
bytes <= 7;
byteLanes <= "01111111";
when "01011" =>
bytes <= 8;
byteLanes <= "11111111";
when "11011" =>
bytes <= 16;
byteLanes <= "11111111";
when "01100" =>
bytes <= 32;
byteLanes <= "11111111";
when "11100" =>
bytes <= 64;
byteLanes <= "11111111";
when "01101" =>
bytes <= 96;
byteLanes <= "11111111";
when "11101" =>
bytes <= 128;
byteLanes <= "11111111";
when "01110" =>
bytes <= 160;
byteLanes <= "11111111";
when "11110" =>
bytes <= 192;
byteLanes <= "11111111";
when "01111" =>
bytes <= 224;
byteLanes <= "11111111";
when "11111" =>
bytes <= 256;
byteLanes <= "11111111";
 
end case;
end process;
end architecture;
 
 
entity MaintenanceReadRequestInbound is
port(
clk : in std_logic;
areset_n : in std_logic;
 
slaveCyc_i : in std_logic;
slaveStb_i : in std_logic;
slaveAdr_i : in std_logic_vector(7 downto 0);
slaveDat_i : in std_logic_vector(31 downto 0);
slaveAck_o : out std_logic;
 
header_o : out std_logic_vector(15 downto 0);
dstId_o : out std_logic_vector(31 downto 0);
srcId_o : out std_logic_vector(31 downto 0);
tid_o : out std_logic_vector(7 downto 0);
configOffset_o : out std_logic_vector(21 downto 0);
configLength_o : out std_logic_vector(3 downto 0);
configSelect_o : out std_logic_vector(7 downto 0);
ready_o : out std_logic;
done_i : in std_logic);
end entity;
 
 
architecture MaintenanceReadRequestInbound of MaintenanceReadRequestInbound is
begin
 
ready_o <= maintReadComplete;
slaveAck_o <= slaveAck;
MaintenanceReadRequest: process(clk, areset_n)
begin
if (areset_n = '0') then
 
elsif (clk'event and clk = '1') then
case state is
when WAIT_PACKET =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (slaveCyc_i = '1') then
if (slaveAck = '0') then
if (slaveStb_i = '1') then
if (slaveAddress_i = x"80") then
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
header <= slaveDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
when 1 =>
-- destid
destId <= slaveDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcid
srcId <= slaveDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & rdsize & srcTID & hop & config_offset(20:13)
size <= slaveDat_i(27 downto 24);
srcTid <= slaveDat_i(23 downto 16);
configOffset(20 downto 13) <= slaveDat_i(7 downto 0);
packetIndex <= packetIndex + 1;
when 4 =>
-- config_offset(12:0) & wdptr & rsrv & crc(15:0)
configOffset(12 downto 0) <= slaveDat_i(31 downto 16);
wdptr <= slaveDat_i(18);
packetIndex <= packetIndex + 1;
maintReadComplete <= '1';
when others =>
-- There should be no more content in a maintenance read request.
-- Discard.
end case;
end if;
slaveAck <= '1';
end if;
else
slaveAck <= '0';
end if;
else
if (maintReadComplete = '1') then
state <= READY;
end if;
packetIndex <= 0;
end if;
 
when READY =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (done_i = '1') then
maintReadComplete <= '0';
state <= WAIT_PACKET;
end if;
when others =>
 
end case;
end if;
end process;
 
-----------------------------------------------------------------------------
-- findInPayload
-- find out number of the bytes and first byte's position in the payload.
--
-----------------------------------------------------------------------------
findInPayload: process(wdptr, size)
-- REMARK: Make this a common component?
-- REMARK: Change bytes to double-words?
process(wdptr, size)
begin
case size is
when "0000" =>
reserved <= '0';
numberOfByte <= 1;
if wdptr = '1' then
pos <= 4;
else
pos <= 0;
end if;
when "0001" =>
reserved <= '0';
numberOfByte <= 1;
if wdptr = '1' then
pos <= 5;
else
pos <= 1;
end if;
when "0010" =>
reserved <= '0';
numberOfByte <= 1;
if wdptr = '1' then
pos <= 6;
else
pos <= 2;
end if;
when "0011" =>
reserved <= '0';
numberOfByte <= 1;
if wdptr = '1' then
pos <= 7;
else
pos <= 3;
end if;
when "0100" =>
reserved <= '0';
numberOfByte <= 2;
if wdptr = '1' then
pos <= 4;
else
pos <= 0;
end if;
when "0101" =>
reserved <= '0';
numberOfByte <= 3;
if wdptr = '1' then
pos <= 5;
else
pos <= 0;
end if;
when "0110" =>
reserved <= '0';
numberOfByte <= 2;
if wdptr = '1' then
pos <= 6;
else
pos <= 2;
end if;
when "0111" =>
reserved <= '0';
numberOfByte <= 5;
if wdptr = '1' then
pos <= 3;
else
pos <= 0;
end if;
when "1000" =>
reserved <= '0';
numberOfByte <= 4;
if wdptr = '1' then
pos <= 4;
else
pos <= 0;
end if;
when "1001" =>
reserved <= '0';
numberOfByte <= 6;
if wdptr = '1' then
pos <= 2;
else
pos <= 0;
end if;
when "1010" =>
reserved <= '0';
numberOfByte <= 7;
if wdptr = '1' then
pos <= 1;
else
pos <= 0;
end if;
when "1011" =>
reserved <= '0';
if wdptr = '1' then
numberOfByte <= 16;
else
numberOfByte <= 8;
end if;
pos <= 0;
when "1100" =>
reserved <= '0';
if wdptr = '1' then
numberOfByte <= 64;
else
numberOfByte <= 32;
end if;
pos <= 0;
when "1101" =>
if wdptr = '1' then
reserved <= '0';
numberOfByte <= 128;
else
reserved <= '1';
numberOfByte <= 96;
end if;
pos <= 0;
when "1110" =>
if wdptr = '1' then
numberOfByte <= 192;
else
numberOfByte <= 160;
end if;
reserved <= '1';
pos <= 0;
when "1111" =>
if wdptr = '1' then
reserved <= '0';
numberOfByte <= 256;
else
reserved <= '1';
numberOfByte <= 224;
end if;
pos <= 0;
when others =>
reserved <= '1';
numberOfByte <= 0;
pos <= 0;
case (wdptr & size) is
when "00000" =>
bytes <= 1;
byteLanes <= "10000000";
when "00001" =>
bytes <= 1;
byteLanes <= "01000000";
when "00010" =>
bytes <= 1;
byteLanes <= "00100000";
when "00011" =>
bytes <= 1;
byteLanes <= "00010000";
when "10000" =>
bytes <= 1;
byteLanes <= "00001000";
when "10001" =>
bytes <= 1;
byteLanes <= "00000100";
when "10010" =>
bytes <= 1;
byteLanes <= "00000010";
when "10011" =>
bytes <= 1;
byteLanes <= "00000001";
when "00100" =>
bytes <= 2;
byteLanes <= "11000000";
when "00101" =>
bytes <= 3;
byteLanes <= "11100000";
when "00110" =>
bytes <= 2;
byteLanes <= "00110000";
when "00111" =>
bytes <= 5;
byteLanes <= "11111000";
when "10100" =>
bytes <= 2;
byteLanes <= "00001100";
when "10101" =>
bytes <= 3;
byteLanes <= "00000111";
when "10110" =>
bytes <= 2;
byteLanes <= "00000011";
when "10111" =>
bytes <= 5;
byteLanes <= "00011111";
when "01000" =>
bytes <= 4;
byteLanes <= "11110000";
when "11000" =>
bytes <= 4;
byteLanes <= "00001111";
when "01001" =>
bytes <= 6;
byteLanes <= "11111100";
when "11001" =>
bytes <= 6;
byteLanes <= "00111111";
when "01010" =>
bytes <= 7;
byteLanes <= "11111110";
when "11010" =>
bytes <= 7;
byteLanes <= "01111111";
when "01011" =>
bytes <= 8;
byteLanes <= "11111111";
when "11011" =>
bytes <= 16;
byteLanes <= "11111111";
when "01100" =>
bytes <= 32;
byteLanes <= "11111111";
when "11100" =>
bytes <= 64;
byteLanes <= "11111111";
when "01101" =>
bytes <= 96;
byteLanes <= "11111111";
when "11101" =>
bytes <= 128;
byteLanes <= "11111111";
when "01110" =>
bytes <= 160;
byteLanes <= "11111111";
when "11110" =>
bytes <= 192;
byteLanes <= "11111111";
when "01111" =>
bytes <= 224;
byteLanes <= "11111111";
when "11111" =>
bytes <= 256;
byteLanes <= "11111111";
 
end case;
end process;

powered by: WebSVN 2.1.0

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