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

Subversion Repositories rio

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /rio/tags
    from Rev 22 to Rev 23
    Reverse comparison

Rev 22 → Rev 23

/2.0.0-alpha/rtl/vhdl/RioSerial.vhd
0,0 → 1,3133
-------------------------------------------------------------------------------
--
-- RapidIO IP Library Core
--
-- This file is part of the RapidIO IP library project
-- http://www.opencores.org/cores/rio/
--
-- Description
-- Containing the transmission channel independent parts of the LP-Serial
-- Physical Layer Specification (RapidIO 2.2, part 6).
--
-- To Do:
-- -
--
-- Author(s):
-- - Magnus Rosenius, magro732@opencores.org
--
-------------------------------------------------------------------------------
--
-- Copyright (C) 2013 Authors and OPENCORES.ORG
--
-- This source file may be used and distributed without
-- restriction provided that this copyright statement is not
-- removed from the file and that any derivative work contains
-- the original copyright notice and the associated disclaimer.
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.opencores.org/lgpl.shtml
--
-------------------------------------------------------------------------------
 
 
-------------------------------------------------------------------------------
-- RioSerial
--
-- 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
-- -------
-- System signals.
-- clk - System clock.
-- areset_n - System reset. Asynchronous, active low.
--
-- Configuration signals. These are used to change the runtime behaviour.
-- portLinkTimeout_i - The number of ticks to wait for a packet-accepted before
-- a timeout occurrs.
-- linkInitialized_o - Indicates if a link partner is answering with valid
-- status-control-symbols.
-- inputPortEnable_i - Activate the input port for non-maintenance packets. If
-- deasserted, only non-maintenance packets are allowed.
-- outputPortEnable_i - Activate the output port for non-maintenance packets.
-- If deasserted, only non-maintenance packets are allowed.
--
-- This interface makes it possible to read and write ackId in both outbound
-- and inbound directions. All input signals are validated by localAckIdWrite.
-- localAckIdWrite_i - Indicate if a localAckId write operation is ongoing.
-- Usually this signal is high one tick.
-- clrOutstandingAckId_i - Clear outstanding ackId, i.e. reset the transmission
-- window. The signal is only read if localAckIdWrite_i is high.
-- inboundAckId_i - The value to set the inbound ackId (the ackId that the
-- next inbound packet should have) to. This signal is only read if localAckIdWrite
-- is high.
-- outstandingAckId_i - The value to set the outstanding ackId (the ackId
-- transmitted but not acknowledged) to. This signal is only read if localAckIdWrite
-- is high.
-- outboundAckId_i - The value to set the outbound ackId (the ackId that the
-- next outbound packet will have) to. This signal is only read if localAckIdWrite
-- is high.
-- inboundAckId_o - The current inbound ackId.
-- outstandingAckId_o - The current outstanding ackId.
-- outboundAckId_o - The current outbound ackId.
--
-- This is the interface to the packet buffering sublayer.
-- The window signals are used to send packets without removing them from the
-- memory storage. This way, many packet can be sent without awaiting
-- packet-accepted symbols and if a packet-accepted gets lost, it is possible
-- to revert and resend a packet. This is achived by reading readWindowEmpty
-- for new packet and asserting readWindowNext when a packet has been sent.
-- When the packet-accepted is received, readFrame should be asserted to remove the
-- packet from the storage. If a packet-accepted is missing, readWindowReset is
-- asserted to set the current packet to read to the one that has not received
-- a packet-accepted.
-- readFrameEmpty_i - Indicate if a packet is ready in the outbound direction.
-- Once deasserted, it is possible to read the packet content using
-- readContent_o to update readContentData and readContentEnd.
-- readFrame_o - Assert this signal for one tick to discard the oldest packet.
-- It should be used when a packet has been fully read, a linkpartner has
-- accepted it and the resources occupied by it should be returned to be
-- used for new packets.
-- readFrameRestart_o - Assert this signal to restart the reading of the
-- current packet. readContentData and readContentEnd will be reset to the
-- first content of the packet.
-- readFrameAborted_i - This signal is asserted if the current packet was
-- aborted while it was written. It is used when a transmitter starts to send a
-- packet before it has been fully received and it is cancelled before it is
-- completed. A one tick asserted readFrameRestart signal resets this signal.
-- readWindowEmpty_i - Indicate if there are more packets to send.
-- readWindowReset_o - Reset the current packet to the oldest stored in the memory.
-- readWindowNext_o - Indicate that a new packet should be read. Must only be
-- asserted if readWindowEmpty is deasserted. It should be high for one tick.
-- readContentEmpty_i - Indicate if there are any packet content to be read.
-- This signal is updated directly when packet content is written making it
-- possible to read packet content before the full packet has been written to
-- the memory storage.
-- readContent_o - Update readContentData and readContentEnd.
-- readContentEnd_i - Indicate if the end of the current packet has been
-- reached. When asserted, readContentData is not valid.
-- readContentData_i - The content of the current packet.
-- writeFrameFull_i - Indicate if the inbound packet storage is ready to accept
-- a new packet.
-- writeFrame_o - Indicate that a new complete inbound packet has been written.
-- writeFrameAbort_o - Indicate that the current packet is aborted and that all
-- data written for this packet should be discarded.
-- writeContent_o - Indicate that writeContentData is valid and should be
-- written into the packet content storage.
-- writeContentData_o - The content to write to the packet content storage.
--
-- This is the interface to the PCS (Physical Control Sublayer). Four types of
-- symbols exist, idle, control, data and error.
-- Idle symbols are transmitted when nothing else can be transmitted. They are
-- mainly intended to enforce a timing on the transmitted symbols. This is
-- needed to be able to guarantee that a status-control-symbol is transmitted
-- at least once every 256 symbol.
-- Control symbols contain control-symbols as described by the standard.
-- Data symbols contains a 32-bit fragment of a RapidIO packet.
-- Error symbols indicate that a corrupted symbol was received. This could be
-- used by a PCS layer to indicate that a transmission error was detected and
-- that the above layers should send link-requests to ensure the synchronism
-- between the link-partners.
-- The signals in this interface are:
-- portInitialized_i - An asserted signal on this pin indicates that the PCS
-- layer has established synchronization with the link and is ready to accept
-- symbols.
-- outboundSymbolEmpty_o - An asserted signal indicates that there are no
-- outbound symbols to read. Once deasserted, outboundSymbol_o will be
-- already be valid. This signal will be updated one tick after
-- outboundSymbolRead_i has been asserted.
-- outboundSymbolRead_i - Indicate that outboundSymbol_o has been read and a
-- new value could be accepted. It should be active for one tick.
-- REMARK: Update this comment...
-- outboundSymbol_o - The outbound symbol. It is divided into two parts,
-- symbolType and symbolContent.
-- symbolType - The two MSB bits are the type of the symbol according to
-- table below:
-- 00=IDLE, the rest of the bits are not used.
-- 01=CONTROL, the control symbols payload (24 bits) are placed in the MSB
-- part of the symbolContent.
-- 10=ERROR, the rest of the bits are not used.
-- 11=DATA, all the remaining bits contain the number of valid words and
-- the payload of the symbol.
-- symbolContent - The rest of the bits are symbol content. If there are
-- multiple words in the symbols they must be set to zero. The first
-- received word is placed in the MSB part of this field.
-- inboundSymbolFull_o - An asserted signal indicates that no more inbound
-- symbols can be accepted.
-- inboundSymbolWrite_i - Indicate that inboundSymbol_i contains valid
-- information that should be forwarded. Should be active for one tick.
-- inboundSymbol_i - The inbound symbol. See outboundSymbol_o for formating.
-------------------------------------------------------------------------------
-- REMARK: Multi-symbol support is not fully supported yet...
-- REMARK: Optimize the piggy-backing of symbols from the receiver, use the
-- number of words that remain to determine when to insert a control-symbol
-- into a stream of data-symbols...
-- REMARK: Optimize the transmitter better, too low performance...
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
 
-------------------------------------------------------------------------------
-- Entity for RioSerial.
-------------------------------------------------------------------------------
entity RioSerial is
generic(
TIMEOUT_WIDTH : natural := 20);
port(
-- System signals.
clk : in std_logic;
areset_n : in std_logic;
 
-- Status signals for maintenance operations.
portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
linkInitialized_o : out std_logic;
inputPortEnable_i : in std_logic;
outputPortEnable_i : in std_logic;
 
-- Support for portLocalAckIdCSR.
localAckIdWrite_i : in std_logic;
clrOutstandingAckId_i : in std_logic;
inboundAckId_i : in std_logic_vector(4 downto 0);
outstandingAckId_i : in std_logic_vector(4 downto 0);
outboundAckId_i : in std_logic_vector(4 downto 0);
inboundAckId_o : out std_logic_vector(4 downto 0);
outstandingAckId_o : out std_logic_vector(4 downto 0);
outboundAckId_o : out std_logic_vector(4 downto 0);
-- Outbound frame interface.
readFrameEmpty_i : in std_logic;
readFrame_o : out std_logic;
readFrameRestart_o : out std_logic;
readFrameAborted_i : in std_logic;
readWindowEmpty_i : in std_logic;
readWindowReset_o : out std_logic;
readWindowNext_o : out std_logic;
readContentEmpty_i : in std_logic;
readContent_o : out std_logic;
readContentEnd_i : in std_logic;
readContentData_i : in std_logic_vector(31 downto 0);
 
-- Inbound frame interface.
writeFrameFull_i : in std_logic;
writeFrame_o : out std_logic;
writeFrameAbort_o : out std_logic;
writeContent_o : out std_logic;
writeContentData_o : out std_logic_vector(31 downto 0);
 
-- 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));
end entity;
 
 
-------------------------------------------------------------------------------
-- Architecture for RioSerial.
-------------------------------------------------------------------------------
architecture RioSerialImpl of RioSerial is
 
component RioFifo is
generic(
DEPTH_WIDTH : natural;
DATA_WIDTH : natural);
port(
clk : in std_logic;
areset_n : in std_logic;
 
empty_o : out std_logic;
read_i : in std_logic;
data_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
 
write_i : in std_logic;
data_i : in std_logic_vector(DATA_WIDTH-1 downto 0));
end component;
component RioTransmitter is
generic(
TIMEOUT_WIDTH : natural;
NUMBER_WORDS : natural range 1 to 4 := 1);
port(
clk : in std_logic;
areset_n : 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);
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);
 
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);
 
linkInitialized_i : in std_logic;
linkInitialized_o : out std_logic;
ackIdStatus_i : in std_logic_vector(4 downto 0);
 
readFrameEmpty_i : in std_logic;
readFrame_o : out std_logic;
readFrameRestart_o : out std_logic;
readFrameAborted_i : in std_logic;
readWindowEmpty_i : in std_logic;
readWindowReset_o : out std_logic;
readWindowNext_o : out std_logic;
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));
end component;
 
component RioReceiver is
generic(
NUMBER_WORDS : natural range 1 to 4 := 1);
port(
clk : in std_logic;
areset_n : in std_logic;
 
portEnable_i : in std_logic;
localAckIdWrite_i : in std_logic;
inboundAckId_i : in std_logic_vector(4 downto 0);
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);
 
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);
 
ackIdStatus_o : out std_logic_vector(4 downto 0);
linkInitialized_o : out std_logic;
writeFrameFull_i : in std_logic;
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));
end component;
 
constant NUMBER_WORDS : 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 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 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 <=
'1' when ((linkInitializedRx = '1') and (linkInitializedTx = '1')) else '0';
-----------------------------------------------------------------------------
-- Serial layer modules.
-----------------------------------------------------------------------------
outboundSymbol_o <= outboundType & outboundData;
Transmitter: RioTransmitter
generic map(
TIMEOUT_WIDTH=>TIMEOUT_WIDTH,
NUMBER_WORDS=>NUMBER_WORDS)
port map(
clk=>clk, areset_n=>areset_n,
portLinkTimeout_i=>portLinkTimeout_i,
portEnable_i=>outputPortEnable_i,
localAckIdWrite_i=>localAckIdWrite_i,
clrOutstandingAckId_i=>clrOutstandingAckId_i,
outstandingAckId_i=>outstandingAckId_i,
outboundAckId_i=>outboundAckId_i,
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,
txControlEmpty_i=>txControlReadEmpty,
txControlSymbol_i=>txControlReadSymbol,
txControlUpdate_o=>txControlRead,
rxControlEmpty_i=>rxControlReadEmpty,
rxControlSymbol_i=>rxControlReadSymbol,
rxControlUpdate_o=>rxControlRead,
linkInitialized_o=>linkInitializedTx,
linkInitialized_i=>linkInitializedRx,
ackIdStatus_i=>ackIdStatus,
readFrameEmpty_i=>readFrameEmpty_i,
readFrame_o=>readFrame_o,
readFrameRestart_o=>readFrameRestart_o,
readFrameAborted_i=>readFrameAborted_i,
readWindowEmpty_i=>readWindowEmpty_i,
readWindowReset_o=>readWindowReset_o,
readWindowNext_o=>readWindowNext_o,
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));
 
SymbolFifo: for i in 0 to NUMBER_WORDS-1 generate
TxSymbolFifo: RioFifo
generic map(DEPTH_WIDTH=>5, DATA_WIDTH=>13)
port map(
clk=>clk, areset_n=>areset_n,
empty_o=>txControlReadEmpty(i),
read_i=>txControlRead(i),
data_o=>txControlReadSymbol(12*(i+1) downto 12*i),
write_i=>txControlWrite(i),
data_i=>txControlWriteSymbol(12*(i+1) downto 12*i));
 
RxSymbolFifo: RioFifo
generic map(DEPTH_WIDTH=>5, DATA_WIDTH=>13)
port map(
clk=>clk, areset_n=>areset_n,
empty_o=>rxControlReadEmpty(i),
read_i=>rxControlRead(i),
data_o=>rxControlReadSymbol(12*(i+1) downto 12*i),
write_i=>rxControlWrite(i),
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)
port map(
clk=>clk, areset_n=>areset_n,
portEnable_i=>inputPortEnable_i,
localAckIdWrite_i=>localAckIdWrite_i,
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,
txControlWrite_o=>txControlWrite,
txControlSymbol_o=>txControlWriteSymbol,
rxControlWrite_o=>rxControlWrite,
rxControlSymbol_o=>rxControlWriteSymbol,
ackIdStatus_o=>ackIdStatus,
linkInitialized_o=>linkInitializedRx,
writeFrameFull_i=>writeFrameFull_i,
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));
end architecture;
 
 
 
-------------------------------------------------------------------------------
-- RioTransmitter
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
 
-------------------------------------------------------------------------------
-- Entity for RioTransmitter.
-------------------------------------------------------------------------------
entity RioTransmitter is
generic(
TIMEOUT_WIDTH : natural;
NUMBER_WORDS : natural range 1 to 4 := 1);
port(
-- System signals.
clk : in std_logic;
areset_n : in std_logic;
 
-- Status signals used for maintenance.
portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
portEnable_i : in std_logic;
 
-- Support for localAckIdCSR.
localAckIdWrite_i : in std_logic;
clrOutstandingAckId_i : in std_logic;
outstandingAckId_i : in std_logic_vector(4 downto 0);
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);
-- 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);
 
-- 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);
 
-- 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);
 
-- 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);
 
-- Frame buffer interface.
readFrameEmpty_i : in std_logic;
readFrame_o : out std_logic;
readFrameRestart_o : out std_logic;
readFrameAborted_i : in std_logic;
readWindowEmpty_i : in std_logic;
readWindowReset_o : out std_logic;
readWindowNext_o : out std_logic;
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));
end entity;
 
 
-------------------------------------------------------------------------------
-- Architecture for RioTransmitter.
-------------------------------------------------------------------------------
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);
port(
-- System signals.
clk : in std_logic;
areset_n : 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);
 
-- Control symbols aimed to the transmitter.
txControlEmpty_i : in std_logic;
txControlSymbol_i : in std_logic_vector(13*NUMBER_WORDS-1 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);
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);
ackId_o : out std_logic_vector(4 downto 0);
bufferStatus_i : in std_logic_vector(4 downto 0);
bufferStatus_o : out std_logic_vector(4 downto 0);
statusReceived_i : in std_logic;
statusReceived_o : out std_logic;
numberSentLinkRequests_i : in std_logic_vector(1 downto 0);
numberSentLinkRequests_o : out std_logic_vector(1 downto 0);
outputErrorStopped_i : in std_logic;
outputErrorStopped_o : out std_logic;
fatalError_i : in std_logic;
fatalError_o : out std_logic;
recoverActive_i : in std_logic;
recoverActive_o : out std_logic;
recoverCounter_i : in std_logic_vector(4 downto 0);
recoverCounter_o : out std_logic_vector(4 downto 0);
ackIdWindow_i : in std_logic_vector(4 downto 0);
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(63 downto 0);
frameContent_o : out std_logic_vector(63 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);
maintenanceClass_i : in std_logic;
maintenanceClass_o : out std_logic;
-- Frame buffer interface.
readFrameEmpty_i : in std_logic;
readFrame_o : out std_logic;
readFrameRestart_o : out std_logic;
readFrameAborted_i : in std_logic;
readWindowEmpty_i : in std_logic;
readWindowReset_o : out std_logic;
readWindowNext_o : out std_logic;
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));
end component;
component MemorySimpleDualPortAsync is
generic(
ADDRESS_WIDTH : natural := 1;
DATA_WIDTH : natural := 1;
INIT_VALUE : std_logic := 'U');
port(
clkA_i : in std_logic;
enableA_i : in std_logic;
addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
 
addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
end component;
 
signal timeCurrent : std_logic_vector(TIMEOUT_WIDTH downto 0);
signal timeSentElapsed : unsigned(TIMEOUT_WIDTH downto 0);
signal timeSentDelta : unsigned(TIMEOUT_WIDTH downto 0);
signal timeSentExpired : std_logic;
signal timeSentSet : std_logic;
signal timeSentReset : std_logic;
 
signal timeSentEnable : std_logic;
signal timeSentWriteAddress : std_logic_vector(4 downto 0);
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(64*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 maintenanceClassCurrent, maintenanceClassNext : std_logic_vector(NUMBER_WORDS-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);
begin
 
-----------------------------------------------------------------------------
-- Output generation to packet buffer.
-----------------------------------------------------------------------------
process(readFrame, readFrameRestart,
readWindowReset, readWindowNext, readContent)
begin
readFrame_o <= '0';
readFrameRestart_o <= '0';
readWindowReset_o <= '0';
readWindowNext_o <= '0';
readContent_o <= '0';
for i in 0 to NUMBER_WORDS-1 loop
if (readFrame(i) = '1') then
readFrame_o <= '1';
end if;
if (readFrameRestart(i) = '1') then
readFrameRestart_o <= '1';
end if;
 
if (readWindowReset(i) = '1') then
readWindowReset_o <= '1';
end if;
 
if (readWindowNext(i) = '1') then
readWindowNext_o <= '1';
end if;
 
if (readContent(i) = '1') then
readContent_o <= '1';
end if;
end loop;
end process;
 
-----------------------------------------------------------------------------
-- Timeout logic.
-----------------------------------------------------------------------------
process(areset_n, clk)
begin
if (areset_n = '0') then
timeSentElapsed <= (others=>'0');
timeSentDelta <= (others=>'0');
timeCurrent <= (others=>'0');
elsif (clk'event and clk = '1') then
if (timeSentEnable = '0') then
timeSentElapsed <= unsigned(timeCurrent) - unsigned(timeSentReadData);
timeSentDelta <= unsigned('0' & portLinkTimeout_i) - timeSentElapsed;
else
timeSentElapsed <= (others=>'0');
timeSentDelta <= (others=>'0');
end if;
timeCurrent <= std_logic_vector(unsigned(timeCurrent) + 1);
end if;
end process;
timeSentExpired <= timeSentDelta(TIMEOUT_WIDTH);
timeSentEnable <= (not txFull_i) and (timeSentSet or timeSentReset);
timeSentWriteAddress <= ackIdWindowCurrent when timeSentSet = '1' else
ackIdCurrent;
timeSentReadAddress <= ackIdCurrent;
TimeoutMemory: MemorySimpleDualPortAsync
generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>TIMEOUT_WIDTH+1, INIT_VALUE=>'0')
port map(
clkA_i=>clk, enableA_i=>timeSentEnable,
addressA_i=>timeSentWriteAddress, dataA_i=>timeCurrent,
addressB_i=>timeSentReadAddress, dataB_o=>timeSentReadData);
 
-----------------------------------------------------------------------------
-- Protocol core and synchronization.
-----------------------------------------------------------------------------
process(areset_n, clk)
begin
if (areset_n = '0') then
operationalCurrent <= (others=>'0');
ackIdCurrent <= (others=>'0');
bufferStatusCurrent <= (others=>'0');
statusReceivedCurrent <= (others=>'0');
numberSentLinkRequestsCurrent <= (others=>'0');
outputErrorStoppedCurrent <= (others=>'0');
fatalErrorCurrent <= (others=>'0');
recoverActiveCurrent <= (others=>'0');
recoverCounterCurrent <= (others=>'0');
ackIdWindowCurrent <= (others=>'0');
frameStateCurrent <= (others=>'0');
frameWordCounterCurrent <= (others=>'0');
frameContentCurrent <= (others=>'0');
counterCurrent <= (others=>'0');
symbolsTransmittedCurrent <= (others=>'0');
maintenanceClassCurrent <= (others=>'0');
elsif (clk'event and clk = '1') then
if (txFull_i = '0') then
operationalCurrent <= operationalNext;
ackIdCurrent <= ackIdNext;
bufferStatusCurrent <= bufferStatusNext;
statusReceivedCurrent <= statusReceivedNext;
numberSentLinkRequestsCurrent <= numberSentLinkRequestsNext;
outputErrorStoppedCurrent <= outputErrorStoppedNext;
fatalErrorCurrent <= fatalErrorNext;
recoverActiveCurrent <= recoverActiveNext;
recoverCounterCurrent <= recoverCounterNext;
ackIdWindowCurrent <= ackIdWindowNext;
frameStateCurrent <= frameStateNext;
frameWordCounterCurrent <= frameWordCounterNext;
frameContentCurrent <= frameContentNext;
counterCurrent <= counterNext;
symbolsTransmittedCurrent <= symbolsTransmittedNext;
maintenanceClassCurrent <= maintenanceClassNext;
end if;
end if;
end process;
 
CoreGeneration: for i in 0 to NUMBER_WORDS-1 generate
TxCore: RioTransmitterCore
generic map(NUMBER_WORDS=>NUMBER_WORDS)
port map(
clk=>clk, areset_n=>areset_n,
portEnable_i=>portEnable_i,
portInitialized_i=>portInitialized_i,
txFull_i=>txFull_i,
txWrite_o=>txWrite_o,
txType_o=>txType_o,
txData_o=>txData_o,
txControlEmpty_i=>txControlEmpty_i(i),
txControlSymbol_i=>txControlSymbol_i(13*(i+1)-1 downto 13*i),
txControlUpdate_o=>txControlUpdate_o(i),
rxControlEmpty_i=>rxControlEmpty_i(i),
rxControlSymbol_i=>rxControlSymbol_i(13*(i+1)-1 downto 13*i),
rxControlUpdate_o=>rxControlUpdate_o(i),
linkInitialized_o=>linkInitialized_o,
linkInitialized_i=>linkInitialized_i,
ackIdStatus_i=>ackIdStatus_i,
timeSentSet_o=>timeSentSet,
timeSentReset_o=>timeSentReset,
timeSentExpired_i=>timeSentExpired,
operational_i=>operationalCurrent(i),
operational_o=>operationalNext(i),
ackId_i=>ackIdCurrent(5*(i+1)-1 downto 5*i),
ackId_o=>ackIdNext(5*(i+1)-1 downto 5*i),
bufferStatus_i=>bufferStatusCurrent(5*(i+1)-1 downto 5*i),
bufferStatus_o=>bufferStatusNext(5*(i+1)-1 downto 5*i),
statusReceived_i=>statusReceivedCurrent(i),
statusReceived_o=>statusReceivedNext(i),
numberSentLinkRequests_i=>numberSentLinkRequestsCurrent(2*(i+1)-1 downto 2*i),
numberSentLinkRequests_o=>numberSentLinkRequestsNext(2*(i+1)-1 downto 2*i),
outputErrorStopped_i=>outputErrorStoppedCurrent(i),
outputErrorStopped_o=>outputErrorStoppedNext(i),
fatalError_i=>fatalErrorCurrent(i),
fatalError_o=>fatalErrorNext(i),
recoverActive_i=>recoverActiveCurrent(i),
recoverActive_o=>recoverActiveNext(i),
recoverCounter_i=>recoverCounterCurrent(5*(i+1)-1 downto 5*i),
recoverCounter_o=>recoverCounterNext(5*(i+1)-1 downto 5*i),
ackIdWindow_i=>ackIdWindowCurrent(5*(i+1)-1 downto 5*i),
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(64*(i+1)-1 downto 64*i),
frameContent_o=>frameContentNext(64*(i+1)-1 downto 64*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),
maintenanceClass_i=>maintenanceClassCurrent(i),
maintenanceClass_o=>maintenanceClassNext(i),
readFrameEmpty_i=>readFrameEmpty_i,
readFrame_o=>readFrame(i),
readFrameRestart_o=>readFrameRestart(i),
readFrameAborted_i=>readFrameAborted_i,
readWindowEmpty_i=>readWindowEmpty_i,
readWindowReset_o=>readWindowReset(i),
readWindowNext_o=>readWindowNext(i),
readContentEmpty_i=>readContentEmpty_i,
readContent_o=>readContent(i),
readContentEnd_i=>readContentEnd_i,
readContentWords_i=>readContentWords_i,
readContentData_i=>readContentData_i);
end generate;
end architecture;
 
 
 
-------------------------------------------------------------------------------
-- RioTransmitterCore
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
-------------------------------------------------------------------------------
-- Entity for RioTransmitterCore.
-------------------------------------------------------------------------------
entity RioTransmitterCore is
generic(
NUMBER_WORDS : natural range 1 to 4 := 1);
port(
-- System signals.
clk : in std_logic;
areset_n : 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);
 
-- Control symbols aimed to the transmitter.
txControlEmpty_i : in std_logic;
txControlSymbol_i : in std_logic_vector(13*NUMBER_WORDS-1 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);
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);
 
-- Timeout signals.
timeSentSet_o : out std_logic;
timeSentReset_o : out std_logic;
timeSentExpired_i : in std_logic;
-- Internal core variables for cascading.
operational_i : in std_logic;
operational_o : out std_logic;
ackId_i : in std_logic_vector(4 downto 0);
ackId_o : out std_logic_vector(4 downto 0);
bufferStatus_i : in std_logic_vector(4 downto 0);
bufferStatus_o : out std_logic_vector(4 downto 0);
statusReceived_i : in std_logic;
statusReceived_o : out std_logic;
numberSentLinkRequests_i : in std_logic_vector(1 downto 0);
numberSentLinkRequests_o : out std_logic_vector(1 downto 0);
outputErrorStopped_i : in std_logic;
outputErrorStopped_o : out std_logic;
fatalError_i : in std_logic;
fatalError_o : out std_logic;
recoverActive_i : in std_logic;
recoverActive_o : out std_logic;
recoverCounter_i : in std_logic_vector(4 downto 0);
recoverCounter_o : out std_logic_vector(4 downto 0);
ackIdWindow_i : in std_logic_vector(4 downto 0);
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(63 downto 0);
frameContent_o : out std_logic_vector(63 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);
maintenanceClass_i : in std_logic;
maintenanceClass_o : out std_logic;
-- Frame buffer interface.
readFrameEmpty_i : in std_logic;
readFrame_o : out std_logic;
readFrameRestart_o : out std_logic;
readFrameAborted_i : in std_logic;
readWindowEmpty_i : in std_logic;
readWindowReset_o : out std_logic;
readWindowNext_o : out std_logic;
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));
end entity;
 
 
-------------------------------------------------------------------------------
-- Architecture for RioTransmitterCore.
-------------------------------------------------------------------------------
architecture RioTransmitterCoreImpl of RioTransmitterCore is
 
constant NUMBER_STATUS_TRANSMIT : std_logic_vector := "1111";
constant NUMBER_LINK_RESPONSE_RETRIES : std_logic_vector := "10";
 
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";
constant FRAME_FIRST : std_logic_vector(3 downto 0) := "0011";
constant FRAME_MIDDLE : std_logic_vector(3 downto 0) := "0100";
constant FRAME_LAST_0 : std_logic_vector(3 downto 0) := "0101";
constant FRAME_LAST_1 : std_logic_vector(3 downto 0) := "0110";
constant FRAME_END : std_logic_vector(3 downto 0) := "0111";
constant FRAME_DISCARD : std_logic_vector(3 downto 0) :="1000";
component Crc5ITU is
port(
d_i : in std_logic_vector(18 downto 0);
crc_o : out std_logic_vector(4 downto 0));
end component;
 
signal txControlUpdateOut : std_logic;
signal sendRestartFromRetry, sendRestartFromRetryOut : std_logic;
signal sendLinkRequest, sendLinkRequestOut : std_logic;
 
signal readFrameOut : std_logic;
signal readFrameRestartOut : std_logic;
signal readWindowResetOut : std_logic;
signal readWindowNextOut : std_logic;
signal readContentOut : std_logic;
signal symbolControlRestartOut, symbolControlRestart : std_logic;
signal symbolControlLinkRequestOut, symbolControlLinkRequest : std_logic;
signal symbolControlStartOut, symbolControlStart : std_logic;
signal symbolControlEndOut, symbolControlEnd : std_logic;
signal symbolDataOut, symbolData : std_logic;
signal symbolDataContentOut, symbolDataContent : std_logic_vector(31 downto 0);
 
signal rxControlUpdateOut : std_logic;
signal symbolControlStype1 : std_logic;
signal controlValidOut, controlValid : std_logic;
signal stype0Out, stype0 : std_logic_vector(2 downto 0);
signal parameter0Out, parameter0 : std_logic_vector(4 downto 0);
signal parameter1Out, parameter1 : std_logic_vector(4 downto 0);
signal stype1 : std_logic_vector(2 downto 0);
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);
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
 
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.
-- Input: ackId, ackIdWindow, timeoutExpired
-- Output: sendLinkRequest, sendRestartFromRetry, ackId,
-----------------------------------------------------------------------------
 
txControlUpdate_o <= txControlUpdateOut and (not txFull_i);
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;
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,
operational_i,
txControlEmpty_i, txControlStype0,
txControlParameter0, txControlParameter1,
timeSentExpired_i,
fatalError_i)
begin
outputErrorStopped_o <= outputErrorStopped_i;
fatalError_o <= fatalError_i;
recoverActive_o <= recoverActive_i;
recoverCounter_o <= recoverCounter_i;
ackId_o <= ackId_i;
bufferStatus_o <= bufferStatus_i;
statusReceived_o <= statusReceived_i;
numberSentLinkRequests_o <= numberSentLinkRequests_i;
 
timeSentReset_o <= '0';
txControlUpdateOut <= '0';
readFrameOut <= '0';
sendRestartFromRetryOut <= '0';
sendLinkRequestOut <= '0';
 
if (fatalError_i = '1') then
outputErrorStopped_o <= '0';
fatalError_o <= '0';
elsif (recoverActive_i = '1') then
if (ackId_i /= recoverCounter_i) then
ackId_o <= std_logic_vector(unsigned(ackId_i) + 1);
readFrameOut <= '1';
else
recoverActive_o <= '0';
outputErrorStopped_o <= '0';
end if;
else
if (operational_i = '0') then
-- Not operational mode.
 
-- Check if any new symbol has been received from the link-partner.
if (txControlEmpty_i = '0') then
-- New symbol from link-partner.
 
-- Check if the symbol is a status-control-symbol.
if (txControlStype0 = STYPE0_STATUS) then
-- A status-control symbol has been received.
-- Update variables from the input status control symbol.
ackId_o <= txControlParameter0;
bufferStatus_o <= txControlParameter1;
outputErrorStopped_o <= '0';
statusReceived_o <= '1';
else
-- Discard all other received symbols in this state.
end if;
txControlUpdateOut <= '1';
end if;
else
-- Operational mode.
-- Make sure to reset the status received flag.
statusReceived_o <= '0';
 
-- Check if the oldest frame timeout has expired.
if ((ackId_i /= ackIdWindow_i) and
(timeSentExpired_i = '1')) then
-- There has been a timeout on a transmitted frame.
 
-- Reset the timeout to expire when the transmitted link-request has
-- timed out instead.
timeSentReset_o <= '1';
 
-- Check if we are in the output-error-stopped state.
if (outputErrorStopped_i = '1') then
-- In the output-error-stopped state.
-- Count the number of link-requests that has been sent and abort if
-- there has been no reply for too many times.
if (unsigned(numberSentLinkRequests_i) /= 0) then
-- Not sent link-request too many times.
-- Send another link-request.
sendLinkRequestOut <= '1';
numberSentLinkRequests_o <= std_logic_vector(unsigned(numberSentLinkRequests_i) - 1);
else
-- No response for too many times.
-- Indicate that a fatal error has occurred.
fatalError_o <= '1';
end if;
else
-- Not in output-error-stopped and there is a timeout.
-- Enter output-error-stopped state and send a link-request.
sendLinkRequestOut <= '1';
numberSentLinkRequests_o <= NUMBER_LINK_RESPONSE_RETRIES;
outputErrorStopped_o <= '1';
end if;
else
-- There has been no timeout.
-- Check if any control symbol has been received from the link
-- partner.
if (txControlEmpty_i = '0') then
-- A control symbol has been received.
 
-- Check the received control symbol.
case txControlStype0 is
when STYPE0_STATUS =>
if (outputErrorStopped_i = '0') then
-- Save the number of buffers in the link partner.
bufferStatus_o <= txControlParameter1;
end if;
when STYPE0_PACKET_ACCEPTED =>
-- The link partner is accepting a frame.
 
if (outputErrorStopped_i = '0') then
-- Save the number of buffers in the link partner.
bufferStatus_o <= txControlParameter1;
-- Check if expecting this type of reply and that the ackId is
-- expected.
if ((ackId_i /= ackIdWindow_i) and
(ackId_i = txControlParameter0)) then
-- The packet-accepted is expected and the ackId is the expected.
-- The frame has been accepted by the link partner.
-- Update to a new buffer and increment the ackId.
readFrameOut <= '1';
ackId_o <= std_logic_vector(unsigned(ackId_i) + 1);
else
-- Unexpected packet-accepted or packet-accepted for
-- unexpected ackId.
sendLinkRequestOut <= '1';
numberSentLinkRequests_o <= NUMBER_LINK_RESPONSE_RETRIES;
outputErrorStopped_o <= '1';
end if;
end if;
when STYPE0_PACKET_RETRY =>
-- The link partner has asked for a frame retransmission.
 
if (outputErrorStopped_i = '0') then
-- Save the number of buffers in the link partner.
bufferStatus_o <= txControlParameter1;
 
-- Check if the ackId is the one expected.
if (ackId_i = txControlParameter0) then
-- The ackId to retry is expected.
-- Go to the output-retry-stopped state.
-- Note that the output-retry-stopped state is equivalent
-- to sending a restart-from-retry.
sendRestartFromRetryOut <= '1';
else
-- Unexpected ackId to retry.
sendLinkRequestOut <= '1';
numberSentLinkRequests_o <= NUMBER_LINK_RESPONSE_RETRIES;
outputErrorStopped_o <= '1';
end if;
end if;
when STYPE0_PACKET_NOT_ACCEPTED =>
if (outputErrorStopped_i = '0') then
-- Packet was rejected by the link-partner.
sendLinkRequestOut <= '1';
numberSentLinkRequests_o <= NUMBER_LINK_RESPONSE_RETRIES;
outputErrorStopped_o <= '1';
end if;
when STYPE0_LINK_RESPONSE =>
if (outputErrorStopped_i = '1') then
-- Check if the link partner return value is acceptable.
if ((unsigned(txControlParameter0) - unsigned(ackId_i)) <=
(unsigned(ackIdWindow_i) - unsigned(ackId_i))) then
-- Recoverable error.
-- Use the received ackId and recover by removing packets
-- that has been received by the link-partner.
recoverCounter_o <= txControlParameter0;
recoverActive_o <= '1';
else
-- Totally out of sync.
-- Indicate that a fatal error has occurred.
fatalError_o <= '1';
end if;
else
-- Dont expect or need a link-response in this state.
-- Discard it.
end if;
when STYPE0_VC_STATUS =>
-- Not supported.
-- Discard it.
when STYPE0_RESERVED =>
-- Not supported.
-- Discard it.
 
when STYPE0_IMPLEMENTATION_DEFINED =>
-- Not supported.
-- Discard it.
when others =>
null;
end case;
 
-- Indicate the control symbol has been processed.
txControlUpdateOut <= '1';
end if;
end if;
end if;
end if;
end process;
-----------------------------------------------------------------------------
-- Second pipeline stage.
-- Create stype1-part of symbols and data symbols. Save the time when a
-- packet was fully sent.
-- Input: sendRestartFromRetry, sendLinkRequest
-- Output: ackIdWindow, frameState, timeout(0 to 31),
-- symbolControlStart, symbolControlEnd, symbolControlRestart,
-- 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);
 
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,
recoverActive_i, ackId_i, operational_i, outputErrorStopped_i, portEnable_i, readContentData_i, readContentWords_i, readContentEnd_i,
frameState_i, frameWordCounter_i, frameContent_i, maintenanceClass_i,
ackIdWindow_i,
sendRestartFromRetry, sendLinkRequest,
fatalError_i)
begin
readFrameRestartOut <= '0';
readWindowResetOut <= '0';
readWindowNextOut <= '0';
readContentOut <= '0';
 
frameState_o <= frameState_i;
frameWordCounter_o <= frameWordCounter_i;
frameContent_o <= frameContent_i;
ackIdWindow_o <= ackIdWindow_i;
maintenanceClass_o <= maintenanceClass_i;
timeSentSet_o <= '0';
 
symbolControlRestartOut <= '0';
symbolControlLinkRequestOut <= '0';
symbolControlStartOut <= '0';
symbolControlEndOut <= '0';
symbolDataOut <= '0';
symbolDataContentOut <= (others => '0');
 
if (fatalError_i = '1') then
readWindowResetOut <= '1';
elsif (recoverActive_i = '1') then
ackIdWindow_o <= ackId_i;
frameState_o <= FRAME_IDLE;
readWindowResetOut <= '1';
else
if (operational_i = '0') then
-----------------------------------------------------------------------
-- This state is entered at startup. A port that is not initialized
-- should only transmit idle sequences.
-----------------------------------------------------------------------
-- Initialize framing before entering the operational state.
frameState_o <= FRAME_IDLE;
ackIdWindow_o <= ackId_i;
readWindowResetOut <= '1';
else
-------------------------------------------------------------------
-- This state is the operational state. It relays frames and handle
-- flow control.
-------------------------------------------------------------------
if (sendRestartFromRetry = '1') then
-- Send a restart-from-retry control symbol to acknowledge the restart
-- of the frame.
symbolControlRestartOut <= '1';
 
-- Make sure there wont be any timeout before the frame is
-- starting to be retransmitted.
timeSentSet_o <= '1';
 
-- Restart the frame transmission.
ackIdWindow_o <= ackId_i;
frameState_o <= FRAME_IDLE;
readWindowResetOut <= '1';
end if;
 
if (sendLinkRequest = '1') then
-- Dont restart the packet transmission since we do not yet know which
-- packets that was successfully received by our link partner.
 
-- Send a link-request symbol.
symbolControlLinkRequestOut <= '1';
 
-- Write the current timer value.
timeSentSet_o <= '1';
end if;
if ((sendRestartFromRetry = '0') and (sendLinkRequest = '0') and
(outputErrorStopped_i = '0')) then
-- Check if a frame transfer is in progress.
-- REMARK: Hold any data symbol if there is a pending symbol from the
-- receiver side...
case frameState_i is
when FRAME_IDLE =>
---------------------------------------------------------------
-- No frame has been started.
---------------------------------------------------------------
 
-- Wait for a new frame to arrive from the frame buffer.
if (readWindowEmpty_i = '0') then
-- Update the output from the frame buffer to contain the
-- data when it is read later.
readContentOut <= '1';
frameContent_o <=
frameContent_i(31 downto 0) & readContentData_i;
 
-- Proceed to start the transmission of the packet.
frameState_o <= FRAME_BUFFER;
end if;
 
when FRAME_BUFFER =>
-----------------------------------------------------------------
-- Packet buffer output has been updated. Store the packet
-- content temporarily.
-----------------------------------------------------------------
 
readContentOut <= '1';
frameContent_o <=
frameContent_i(31 downto 0) & readContentData_i;
 
if (readContentData_i(19 downto 16) = FTYPE_MAINTENANCE_CLASS) then
maintenanceClass_o <= '1';
else
maintenanceClass_o <= '0';
end if;
 
frameState_o <= FRAME_START;
when FRAME_START | FRAME_END =>
-------------------------------------------------------
-- Check if we are allowed to transmit this packet.
-------------------------------------------------------
-- The packet may be not allowed, i.e. a non-maintenance
-- sent when only maintenance is allowed. The link-partner can be
-- busy, i.e. not having enough buffers to receive the new packet
-- in or the number of outstanding packets may be too large.
-- REMARK: Only update readContent_o in the last instance
-- if cascaded...
 
-- Check if the packet is allowed.
if ((portEnable_i = '1') or (maintenanceClass_i = '1')) then
-- Packet is allowed.
 
-- Check if the link is able to accept the new frame.
if ((readWindowEmpty_i = '0') and
(bufferStatus_i /= "00000") and
((unsigned(ackIdWindow_i)+1) /= unsigned(ackId_i))) then
-- New data is available for transmission and there
-- is room to receive it at the other side.
-- The packet may be transmitted.
 
-- Send a control symbol to start the packet and a status to
-- complete the symbol.
symbolControlStartOut <= '1';
-- Indicate that a control symbol has been sent to start the
-- transmission of the frame.
frameContent_o <=
frameContent_i(31 downto 0) & readContentData_i;
readContentOut <= '1';
-- Proceed to send the first packet data symbol containing
-- the ackId.
frameState_o <= FRAME_FIRST;
else
-- The link cannot accept the packet.
-- Wait in this state and dont do anything.
if (frameState_i = FRAME_END) then
symbolControlEndOut <= '1';
end if;
readFrameRestartOut <= '1';
frameState_o <= FRAME_IDLE;
end if;
else
-- The packet is not allowed.
-- Discard it.
if (frameState_i = FRAME_END) then
symbolControlEndOut <= '1';
end if;
--readFrameRestartOut <= '1';
frameState_o <= FRAME_DISCARD;
end if;
 
when FRAME_FIRST =>
---------------------------------------------------------------
-- Send the first packet content containing our current
-- ackId.
---------------------------------------------------------------
 
-- Write a new data symbol and fill in our ackId on the
-- packet.
symbolDataOut <= '1';
symbolDataContentOut <= std_logic_vector(ackIdWindow_i) & "0" &
frameContent_i(57 downto 32);
frameContent_o <= frameContent_i(31 downto 0) & readContentData_i;
-- Check if the frame is ending.
if (readContentEnd_i = '1') then
-- The frame is ending.
readWindowNextOut <= '1';
frameState_o <= FRAME_LAST_0;
else
readContentOut <= '1';
frameState_o <= FRAME_MIDDLE;
end if;
when FRAME_MIDDLE =>
---------------------------------------------------------------
-- The frame has not been fully sent.
-- Send a data symbol until the last part of the packet is
-- detected.
---------------------------------------------------------------
-- Write a new data symbol.
symbolDataOut <= '1';
symbolDataContentOut <= frameContent_i(63 downto 32);
frameContent_o <= frameContent_i(31 downto 0) & readContentData_i;
 
-- Check if the frame is ending.
if (readContentEnd_i = '1') then
-- The frame is ending.
readWindowNextOut <= '1';
frameState_o <= FRAME_LAST_0;
else
readContentOut <= '1';
end if;
when FRAME_LAST_0 =>
-----------------------------------------------------------------
--
-----------------------------------------------------------------
 
symbolDataOut <= '1';
symbolDataContentOut <= frameContent_i(63 downto 32);
frameContent_o <= frameContent_i(31 downto 0) & readContentData_i;
if (readWindowEmpty_i = '0') then
readContentOut <= '1';
end if;
frameState_o <= FRAME_LAST_1;
 
when FRAME_LAST_1 =>
-----------------------------------------------------------------
--
-----------------------------------------------------------------
 
symbolDataOut <= '1';
symbolDataContentOut <= frameContent_i(63 downto 32);
frameContent_o <= frameContent_i(31 downto 0) & readContentData_i;
if (readWindowEmpty_i = '0') then
if (readContentData_i(19 downto 16) = FTYPE_MAINTENANCE_CLASS) then
maintenanceClass_o <= '1';
else
maintenanceClass_o <= '0';
end if;
readContentOut <= '1';
end if;
 
-- Update the window ackId.
ackIdWindow_o <= std_logic_vector(unsigned(ackIdWindow_i) + 1);
 
-- Start timeout supervision for transmitted frame.
timeSentSet_o <= '1';
 
-- Proceed to end the frame or start a new one.
frameState_o <= FRAME_END;
 
when FRAME_DISCARD =>
---------------------------------------------------------------
--
---------------------------------------------------------------
-- The packet should be discarded.
-- Send idle-sequence.
 
-- Check that there are no outstanding packets that
-- has not been acknowledged.
if(unsigned(ackIdWindow_i) = unsigned(ackId_i)) then
-- No unacknowledged packets.
-- It is now safe to remove the unallowed frame.
-- REMARK: Discard packet; readFrameOut <= '1';
 
-- Go back and send a new frame.
frameState_o <= FRAME_IDLE;
end if;
when others =>
---------------------------------------------------------------
--
---------------------------------------------------------------
null;
end case;
end if;
end if;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Third pipeline stage.
-- Create the stype0 and stype1 part of a control symbol.
-- This process makes sure that the buffer status are transmitted at least
-- every 255 symbol.
-- At startup it makes sure that at least 16 status symbols are transmitted
-- before the operational-state is entered.
-- Input: symbolControlStart, symbolControlEnd, symbolControlRestart,
-- symbolControlLinkRequest, symbolData, symbolDataContent
-- Output: symbolsTransmitted_o, operational_o,
-- symbolControl, stype0, parameter0, parameter1, stype1, cmd,
-- symbolData1, symbolData1Content
-----------------------------------------------------------------------------
 
rxControlUpdate_o <= rxControlUpdateOut and (not txFull_i);
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,
rxControlEmpty_i,
symbolControlStype1, symbolData,
rxControlStype0, rxControlParameter0, rxControlParameter1,
fatalError_i)
begin
operational_o <= operational_i;
counter_o <= counter_i;
symbolsTransmitted_o <= symbolsTransmitted_i;
rxControlUpdateOut <= '0';
controlValidOut <= '0';
stype0Out <= STYPE0_STATUS;
parameter0Out <= ackIdStatus_i;
parameter1Out <= "11111";
if (fatalError_i = '1') then
operational_o <= '0';
counter_o <= NUMBER_STATUS_TRANSMIT;
symbolsTransmitted_o <= (others=>'0');
else
-- Check the operational state.
if (operational_i = '0') then
-----------------------------------------------------------------------
-- This state is entered at startup. A port that is not initialized
-- should only transmit idle sequences.
-----------------------------------------------------------------------
-- Check if the port is initialized.
if (portInitialized_i = '1') then
---------------------------------------------------------------------
-- The specification requires a status control symbol being sent at
-- least every 1024 code word until an error-free status has been
-- received. This implies that at most 256 idle sequences should be
-- sent in between status control symbols. Once an error-free status
-- has been received, status symbols may be sent more rapidly. At
-- least 15 statuses has to be transmitted once an error-free status
-- has been received.
---------------------------------------------------------------------
 
-- Check if we are ready to change state to operational.
if ((linkInitialized_i = '1') and
(unsigned(counter_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
-- 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);
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');
end if;
else
---------------------------------------------------------------------
-- This is the operational state.
-- It is entered once the link has been considdered up and running.
---------------------------------------------------------------------
 
-- 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');
else
-- A symbol not containing the bufferStatus has been sent.
symbolsTransmitted_o <= std_logic_vector(unsigned(symbolsTransmitted_i) + 1);
end if;
else
-- A symbol not containing the bufferStatus has been sent.
controlValidOut <= '0';
symbolsTransmitted_o <= std_logic_vector(unsigned(symbolsTransmitted_i) + 1);
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');
end if;
end if;
end if;
end process;
-----------------------------------------------------------------------------
-- Fourth pipeline stage.
-- Make all symbols ready for transmission, i.e. calculate the CRC5 on
-- control symbols and choose which symbol to send.
-- Inputs: controlValid, stype0, parameter0, parameter1, stype1, cmd,
-- symbolData1, symbolData1Content
-----------------------------------------------------------------------------
 
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";
 
Crc5Calculator: Crc5ITU
port map(
d_i=>controlContent(31 downto 13), 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');
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;
end if;
end if;
end process;
end architecture;
 
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
 
entity RioReceiver is
generic(
NUMBER_WORDS : natural range 1 to 4 := 1);
port(
clk : in std_logic;
areset_n : in std_logic;
portEnable_i : in std_logic;
localAckIdWrite_i : in std_logic;
inboundAckId_i : in std_logic_vector(4 downto 0);
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);
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);
ackIdStatus_o : out std_logic_vector(4 downto 0);
linkInitialized_o : out std_logic;
writeFrameFull_i : in std_logic;
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));
end entity;
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture RioReceiverImpl of RioReceiver is
 
component RioReceiverCore is
generic(
NUMBER_WORDS : natural range 1 to 4 := 1);
port(
clk : in std_logic;
areset_n : in std_logic;
 
-- Status signals used for maintenance.
portEnable_i : in std_logic;
 
-- Support for localAckIdCSR.
-- REMARK: Add support for this???
localAckIdWrite_i : in std_logic;
inboundAckId_i : in std_logic_vector(4 downto 0);
inboundAckId_o : out std_logic_vector(4 downto 0);
-- 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);
 
-- Receiver has received a control symbol containing:
-- packet-accepted, packet-retry, packet-not-accepted,
-- status, VC_status, link-response
txControlWrite_o : out std_logic;
txControlSymbol_o : out std_logic_vector(12 downto 0);
 
-- Reciever 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)
-- a frame is rejected due to errors => packet-not-accepted
-- a link-request should be answered => link-response
rxControlWrite_o : out std_logic;
rxControlSymbol_o : out std_logic_vector(12 downto 0);
 
-- Status signals used internally.
ackIdStatus_o : out std_logic_vector(4 downto 0);
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;
inputRetryStopped_o : out std_logic;
inputErrorStopped_i : in std_logic;
inputErrorStopped_o : out std_logic;
ackId_i : in unsigned(4 downto 0);
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);
-- Frame buffering interface.
writeFrameFull_i : in std_logic;
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));
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 txControlWrite : std_logic_vector(NUMBER_WORDS-1 downto 0);
signal rxControlWrite : std_logic_vector(NUMBER_WORDS-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);
 
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)
begin
if (areset_n = '0') then
operationalCurrent <= (others=>'0');
inputRetryStoppedCurrent <= (others=>'0');
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
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);
rxControlWrite_o(i) <= rxControlWrite(i);
ReceiverCore: RioReceiverCore
generic map(NUMBER_WORDS=>NUMBER_WORDS)
port map(
clk=>clk,
areset_n=>areset_n,
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,
txControlWrite_o=>txControlWrite(i),
txControlSymbol_o=>txControlSymbol_o(13*(i+1)-1 downto 13*i),
rxControlWrite_o=>rxControlWrite(i),
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),
inputRetryStopped_o=>inputRetryStoppedNext(i),
inputErrorStopped_i=>inputErrorStoppedCurrent(i),
inputErrorStopped_o=>inputErrorStoppedNext(i),
ackId_i=>ackIdCurrent(5*(i+1)-1 downto 5*i),
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));
end generate;
end architecture;
-------------------------------------------------------------------------------
-- RioReceiverCore
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
entity RioReceiverCore is
generic(
NUMBER_WORDS : natural range 1 to 4 := 1);
port(
clk : in std_logic;
areset_n : in std_logic;
 
-- Status signals used for maintenance.
portEnable_i : in std_logic;
 
-- Support for localAckIdCSR.
-- REMARK: Add support for this???
localAckIdWrite_i : in std_logic;
inboundAckId_i : in std_logic_vector(4 downto 0);
inboundAckId_o : out std_logic_vector(4 downto 0);
-- 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);
 
-- Receiver has received a control symbol containing:
-- packet-accepted, packet-retry, packet-not-accepted,
-- status, VC_status, link-response
txControlWrite_o : out std_logic;
txControlSymbol_o : out std_logic_vector(12 downto 0);
 
-- Reciever 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)
-- a frame is rejected due to errors => packet-not-accepted
-- a link-request should be answered => link-response
rxControlWrite_o : out std_logic;
rxControlSymbol_o : out std_logic_vector(12 downto 0);
 
-- Status signals used internally.
ackIdStatus_o : out std_logic_vector(4 downto 0);
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;
inputRetryStopped_o : out std_logic;
inputErrorStopped_i : in std_logic;
inputErrorStopped_o : out std_logic;
ackId_i : in unsigned(4 downto 0);
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);
-- Frame buffering interface.
writeFrameFull_i : in std_logic;
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));
end entity;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture RioReceiverCoreImpl of RioReceiverCore is
 
component Crc5ITU is
port(
d_i : in std_logic_vector(18 downto 0);
crc_o : out std_logic_vector(4 downto 0));
end component;
 
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 symbolEnable0, symbolEnable1 : std_logic;
signal symbolType0 : std_logic_vector(1 downto 0);
signal symbolContent0, symbolContent1 : std_logic_vector(31 downto 0);
signal crc5Valid : std_logic;
signal crc5 : std_logic_vector(4 downto 0);
 
signal symbolValid : std_logic;
signal stype0Status : std_logic;
signal stype1Start : std_logic;
signal stype1End : std_logic;
signal stype1Stomp : std_logic;
signal stype1Restart : std_logic;
signal stype1LinkRequest : std_logic;
signal symbolData : 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);
begin
 
linkInitialized_o <= operational_i;
ackIdStatus_o <= std_logic_vector(ackId_i);
inboundAckId_o <= std_logic_vector(ackId_i);
 
-----------------------------------------------------------------------------
-- First pipeline stage.
-- Check the validity of the symbol, CRC5 on control symbols, and save the
-- 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);
 
process(clk, areset_n)
begin
if (areset_n = '0') then
crc5Valid <= '0';
symbolType0 <= (others => '0');
symbolContent0 <= (others => '0');
elsif (clk'event and clk = '1') then
if (rxEmpty_i = '0') then
if (crc5 = rxData_i(12 downto 8)) then
crc5Valid <= '1';
else
crc5Valid <= '0';
end if;
symbolEnable0 <= '1';
symbolType0 <= rxType_i;
symbolContent0 <= rxData_i;
else
symbolEnable0 <= '0';
end if;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Second pipeline stage.
-- Separate the part of the control symbol that are going to the transmitter
-- side and check the type of symbol for this side.
-----------------------------------------------------------------------------
 
process(clk, areset_n)
begin
if (areset_n = '0') then
txControlWrite_o <= '0';
txControlSymbol_o <= (others => '0');
 
symbolValid <= '0';
stype0Status <= '0';
stype1Start <= '0';
stype1End <= '0';
stype1Stomp <= '0';
stype1Restart <= '0';
stype1LinkRequest <= '0';
symbolData <= '0';
symbolContent1 <= (others => '0');
elsif (clk'event and clk = '1') then
if (symbolEnable0 = '1') then
symbolEnable1 <= '1';
symbolContent1 <= symbolContent0;
if (symbolType0 = SYMBOL_CONTROL) then
if (crc5Valid = '1') then
-- REMARK: Check if stype0 is nop and dont forward it???
symbolValid <= '1';
txControlWrite_o <= '1';
txControlSymbol_o <= symbolContent0(31 downto 19);
else
symbolValid <= '0';
txControlWrite_o <= '0';
txControlSymbol_o <= (others => '0');
end if;
else
symbolValid <= '1';
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;
 
-----------------------------------------------------------------------------
-- Third pipeline stage.
-- Update the CRC16 for the packet.
-- Update the buffered data and write it to the packet buffer if needed.
-- Update the main receiver state machine.
-- Generate reply symbols to the link-partner.
-- Note that this stage cannot contain any registers as it could be cascaded
-- to other cores.
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- 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.
-----------------------------------------------------------------------------
 
crc16Data(31 downto 26) <= "000000" when (unsigned(frameIndex_i) = 1) else
symbolContent1(31 downto 26);
crc16Data(25 downto 0) <= symbolContent1(25 downto 0);
 
crc16Current <= crc_i when (unsigned(frameIndex_i) /= 1) else
(others => '1');
 
Crc16Msb: Crc16CITT
port map(
d_i=>crc16Data(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp);
Crc16Lsb: Crc16CITT
port map(
d_i=>crc16Data(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next);
 
crc_o <= crc_i when (symbolData = '0') else
crc16Next;
 
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.
-----------------------------------------------------------------------------
process(portInitialized_i, portEnable_i, writeFrameFull_i,
operational_i, ackId_i, frameIndex_i, frameWordCounter_i,
inputRetryStopped_i, inputErrorStopped_i,
symbolValid,
stype0Status,
stype1Start, stype1End, stype1Stomp, stype1Restart, stype1LinkRequest,
symbolData,
symbolContent1,
frameContent,
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;
rxControlWrite <= '0';
rxControlSymbol <= (others => '0');
writeFrame_o <= '0';
writeFrameAbort_o <= '0';
writeContent_o <= '0';
writeContentWords_o <= (others => '0');
 
-- Act on the current state.
if (operational_i = '0') then
---------------------------------------------------------------------
-- The port is not operational and is waiting for status control
-- symbols to be received on the link. Count the number
-- of error-free status symbols and considder the link operational
-- 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
-- The control symbol has a valid checksum.
-- Check the stype0 part if we should count the number of
-- error-free status symbols.
if (stype0Status = '1') then
-- The symbol is a status.
-- Check if enough status symbols have been received.
if (unsigned(frameIndex_i) = 7) then
-- Enough status symbols have been received.
 
-- 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.
frameIndex_o <= std_logic_vector(unsigned(frameIndex_i) + 1);
end if;
else
-- The symbol is not a status.
-- Dont do anything.
end if;
else
-- A control symbol with CRC5 error was recevied.
frameIndex_o <= (others => '0');
end if;
else
-- The port has become uninitialized.
frameIndex_o <= (others => '0');
end if;
else
---------------------------------------------------------------------
-- The port has been initialized and enough error free status symbols
-- have been received. Forward data frames to the frame buffer
-- interface. This is the normal operational state.
---------------------------------------------------------------------
-- Check that the port is initialized.
if (portInitialized_i = '1') then
-- The port and link is initialized.
-- Check if the control symbol has a valid CRC-5.
if (symbolValid = '1') then
-- The symbol is correct.
 
if ((stype1Start = '1') and
(inputRetryStopped_i = '0') and (inputErrorStopped_i = '0')) then
-------------------------------------------------------------
-- Start the reception of a new frame or end a currently
-- ongoing frame and start a new one.
-------------------------------------------------------------
-- Check if a frame has already been started.
if (unsigned(frameIndex_i) /= 0) then
-- A frame is already started.
-- Complete the last frame and start to ackumulate a new one
-- and update the ackId.
if (unsigned(frameIndex_i) > 3) then
 
-- 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';
 
-- 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 indicated
-- 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;
else
-- No frame has been started.
-- 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.
-- 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";
-- Enter the input retry-stopped state.
inputRetryStopped_o <= '1';
end if;
 
if (stype1Restart = '1') then
if (inputRetryStopped_i = '1') then
-------------------------------------------------------------
-- The receiver indicates a restart from a retry sent
-- from us.
-------------------------------------------------------------
 
-- Abort the frame and reset frame reception.
frameIndex_o <= (others => '0');
writeFrameAbort_o <= '1';
-- Go back to the normal operational state.
inputRetryStopped_o <= '0';
else
-------------------------------------------------------------
-- The receiver indicates a restart from a retry sent
-- from us.
-------------------------------------------------------------
-- See 5.10 in the standard.
-- Protocol error, this symbol should not be received here since
-- we should have been in input-retry-stopped.
-- 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;
inputErrorStopped_o <= '1';
end if;
end if;
 
if (stype1LinkRequest = '1') then
-------------------------------------------------------------
-- Reply to a LINK-REQUEST.
-------------------------------------------------------------
-- Check the command part.
if (symbolContent1(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";
elsif (inputRetryStopped_i = '1') then
rxControlWrite <= '1';
rxControlSymbol <= 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";
end if;
else
-- Reset device command or other unsupported command.
-- Discard this.
end if;
-- Abort the frame and reset frame reception.
inputRetryStopped_o <= '0';
inputErrorStopped_o <= '0';
frameIndex_o <= (others=>'0');
writeFrameAbort_o <= '1';
end if;
 
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...
 
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
 
-- 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;
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';
end if;
else
-- The ackId is unexpected.
-- Send packet-not-accepted.
rxControlWrite <= '1';
rxControlSymbol <= 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.
-- 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);
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';
end if;
else
-- The port has become uninitialized.
-- Go back to the uninitialized state.
operational_o <= '0';
end if;
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...
 
process(clk, areset_n)
begin
if (areset_n = '0') then
rxControlWrite_o <= '0';
rxControlSymbol_o <= (others=>'0');
elsif (clk'event and clk = '1') then
rxControlWrite_o <= rxControlWrite and symbolEnable1;
rxControlSymbol_o <= rxControlSymbol;
end if;
end process;
end architecture;
 
 
 
-------------------------------------------------------------------------------
--
---------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
entity RioFifo is
generic(
DEPTH_WIDTH : natural;
DATA_WIDTH : natural);
port(
clk : in std_logic;
areset_n : in std_logic;
 
empty_o : out std_logic;
read_i : in std_logic;
data_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
 
write_i : in std_logic;
data_i : in std_logic_vector(DATA_WIDTH-1 downto 0));
end entity;
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture RioFifoImpl of RioFifo is
 
component MemorySimpleDualPortAsync is
generic(
ADDRESS_WIDTH : natural := 1;
DATA_WIDTH : natural := 1;
INIT_VALUE : std_logic := 'U');
port(
clkA_i : in std_logic;
enableA_i : in std_logic;
addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
 
addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
end component;
 
signal empty : std_logic;
signal full : std_logic;
 
signal readAddress : std_logic_vector(DEPTH_WIDTH-1 downto 0);
signal readAddressInc : std_logic_vector(DEPTH_WIDTH-1 downto 0);
signal writeAddress : std_logic_vector(DEPTH_WIDTH-1 downto 0);
signal writeAddressInc : std_logic_vector(DEPTH_WIDTH-1 downto 0);
begin
 
empty_o <= empty;
 
readAddressInc <= std_logic_vector(unsigned(readAddress) + 1);
writeAddressInc <= std_logic_vector(unsigned(writeAddress) + 1);
 
process(areset_n, clk)
begin
if (areset_n = '0') then
empty <= '1';
full <= '0';
readAddress <= (others=>'0');
writeAddress <= (others=>'0');
elsif (clk'event and clk = '1') then
if (empty = '1') then
if (write_i = '1') then
empty <= '0';
writeAddress <= writeAddressInc;
end if;
end if;
if (full = '1') then
if (read_i = '1') then
full <= '0';
readAddress <= readAddressInc;
end if;
end if;
if (empty = '0') and (full = '0') then
if (write_i = '1') and (read_i = '0') then
writeAddress <= writeAddressInc;
if (writeAddressInc = readAddress) then
full <= '1';
end if;
end if;
if (write_i = '0') and (read_i = '1') then
readAddress <= readAddressInc;
if (readAddressInc = writeAddress) then
empty <= '1';
end if;
end if;
if (write_i = '1') and (read_i = '1') then
writeAddress <= writeAddressInc;
readAddress <= readAddressInc;
end if;
end if;
end if;
end process;
Memory: MemorySimpleDualPortAsync
generic map(ADDRESS_WIDTH=>DEPTH_WIDTH,
DATA_WIDTH=>DATA_WIDTH,
INIT_VALUE=>'0')
port map(
clkA_i=>clk, enableA_i=>write_i,
addressA_i=>writeAddress, dataA_i=>data_i,
addressB_i=>readAddress, dataB_o=>data_o);
end architecture;
 
 
 
-------------------------------------------------------------------------------
-- A CRC-5 calculator following the implementation proposed in the 2.2
-- standard.
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
entity Crc5ITU is
port(
d_i : in std_logic_vector(18 downto 0);
crc_o : out std_logic_vector(4 downto 0));
end entity;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture Crc5Impl of Crc5ITU is
signal d : std_logic_vector(0 to 18);
signal c : std_logic_vector(0 to 4);
 
begin
-- Reverse the bit vector indexes to make them the same as in the standard.
d(18) <= d_i(0); d(17) <= d_i(1); d(16) <= d_i(2); d(15) <= d_i(3);
d(14) <= d_i(4); d(13) <= d_i(5); d(12) <= d_i(6); d(11) <= d_i(7);
d(10) <= d_i(8); d(9) <= d_i(9); d(8) <= d_i(10); d(7) <= d_i(11);
d(6) <= d_i(12); d(5) <= d_i(13); d(4) <= d_i(14); d(3) <= d_i(15);
d(2) <= d_i(16); d(1) <= d_i(17); d(0) <= d_i(18);
 
-- Calculate the resulting crc.
c(0) <= d(18) xor d(16) xor d(15) xor d(12) xor
d(10) xor d(5) xor d(4) xor d(3) xor
d(1) xor d(0);
c(1) <= (not d(18)) xor d(17) xor d(15) xor d(13) xor
d(12) xor d(11) xor d(10) xor d(6) xor
d(3) xor d(2) xor d(0);
c(2) <= (not d(18)) xor d(16) xor d(14) xor d(13) xor
d(12) xor d(11) xor d(7) xor d(4) xor
d(3) xor d(1);
c(3) <= (not d(18)) xor d(17) xor d(16) xor d(14) xor
d(13) xor d(10) xor d(8) xor d(3) xor
d(2) xor d(1);
c(4) <= d(18) xor d(17) xor d(15) xor d(14) xor
d(11) xor d(9) xor d(4) xor d(3) xor
d(2) xor d(0);
 
-- Reverse the bit vector indexes to make them the same as in the standard.
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;
2.0.0-alpha/rtl/vhdl/RioSerial.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: 2.0.0-alpha/rtl/vhdl/RioPacketBuffer.vhd =================================================================== --- 2.0.0-alpha/rtl/vhdl/RioPacketBuffer.vhd (nonexistent) +++ 2.0.0-alpha/rtl/vhdl/RioPacketBuffer.vhd (revision 23) @@ -0,0 +1,831 @@ +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- Description +-- Containing RapidIO packet buffering functionallity. Two different entities +-- are implemented, one with transmission window support and one without. +-- +-- To Do: +-- - +-- +-- Author(s): +-- - Magnus Rosenius, magro732@opencores.org +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------- + + +------------------------------------------------------------------------------- +-- RioPacketBuffer +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- Entity for RioPacketBuffer. +------------------------------------------------------------------------------- +entity RioPacketBuffer is + generic( + SIZE_ADDRESS_WIDTH : natural := 6; + CONTENT_ADDRESS_WIDTH : natural := 8); + port( + clk : in std_logic; + areset_n : in std_logic; + + inboundWriteFrameFull_o : out std_logic; + inboundWriteFrame_i : in std_logic; + inboundWriteFrameAbort_i : in std_logic; + inboundWriteContent_i : in std_logic; + inboundWriteContentData_i : in std_logic_vector(31 downto 0); + inboundReadFrameEmpty_o : out std_logic; + inboundReadFrame_i : in std_logic; + inboundReadFrameRestart_i : in std_logic; + inboundReadFrameAborted_o : out std_logic; + inboundReadContentEmpty_o : out std_logic; + inboundReadContent_i : in std_logic; + inboundReadContentEnd_o : out std_logic; + inboundReadContentData_o : out std_logic_vector(31 downto 0); + + outboundWriteFrameFull_o : out std_logic; + outboundWriteFrame_i : in std_logic; + outboundWriteFrameAbort_i : in std_logic; + outboundWriteContent_i : in std_logic; + outboundWriteContentData_i : in std_logic_vector(31 downto 0); + outboundReadFrameEmpty_o : out std_logic; + outboundReadFrame_i : in std_logic; + outboundReadFrameRestart_i : in std_logic; + outboundReadFrameAborted_o : out std_logic; + outboundReadContentEmpty_o : out std_logic; + outboundReadContent_i : in std_logic; + outboundReadContentEnd_o : out std_logic; + outboundReadContentData_o : out std_logic_vector(31 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for RioPacketBuffer. +------------------------------------------------------------------------------- +architecture RioPacketBufferImpl of RioPacketBuffer is + + component PacketBufferContinous is + generic( + SIZE_ADDRESS_WIDTH : natural; + CONTENT_ADDRESS_WIDTH : natural); + port( + clk : in std_logic; + areset_n : in std_logic; + + writeFrameFull_o : out std_logic; + writeFrame_i : in std_logic; + writeFrameAbort_i : in std_logic; + writeContent_i : in std_logic; + writeContentData_i : in std_logic_vector(31 downto 0); + + readFrameEmpty_o : out std_logic; + readFrame_i : in std_logic; + readFrameRestart_i : in std_logic; + readFrameAborted_o : out std_logic; + readContentEmpty_o : out std_logic; + readContent_i : in std_logic; + readContentEnd_o : out std_logic; + readContentData_o : out std_logic_vector(31 downto 0)); + end component; + +begin + + ----------------------------------------------------------------------------- + -- Outbound frame buffers. + ----------------------------------------------------------------------------- + OutboundPacketBuffer: PacketBufferContinous + generic map( + SIZE_ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH, + CONTENT_ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH) + port map( + clk=>clk, + areset_n=>areset_n, + writeFrameFull_o=>outboundWriteFrameFull_o, + writeFrame_i=>outboundWriteFrame_i, writeFrameAbort_i=>outboundWriteFrameAbort_i, + writeContent_i=>outboundWriteContent_i, writeContentData_i=>outboundWriteContentData_i, + + readFrameEmpty_o=>outboundReadFrameEmpty_o, + readFrame_i=>outboundReadFrame_i, readFrameRestart_i=>outboundReadFrameRestart_i, + readFrameAborted_o=>outboundReadFrameAborted_o, + readContentEmpty_o=>outboundReadContentEmpty_o, + readContent_i=>outboundReadContent_i, readContentEnd_o=>outboundReadContentEnd_o, + readContentData_o=>outboundReadContentData_o); + + ----------------------------------------------------------------------------- + -- Inbound frame buffers. + ----------------------------------------------------------------------------- + InboundPacketBuffer: PacketBufferContinous + generic map( + SIZE_ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH, + CONTENT_ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH) + port map( + clk=>clk, + areset_n=>areset_n, + writeFrameFull_o=>inboundWriteFrameFull_o, + writeFrame_i=>inboundWriteFrame_i, writeFrameAbort_i=>inboundWriteFrameAbort_i, + writeContent_i=>inboundWriteContent_i, writeContentData_i=>inboundWriteContentData_i, + + readFrameEmpty_o=>inboundReadFrameEmpty_o, + readFrame_i=>inboundReadFrame_i, readFrameRestart_i=>inboundReadFrameRestart_i, + readFrameAborted_o=>inboundReadFrameAborted_o, + readContentEmpty_o=>inboundReadContentEmpty_o, + readContent_i=>inboundReadContent_i, readContentEnd_o=>inboundReadContentEnd_o, + readContentData_o=>inboundReadContentData_o); + +end architecture; + + + + +------------------------------------------------------------------------------- +-- RioPacketBufferWindow +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- Entity for RioPacketBufferWindow. +------------------------------------------------------------------------------- +entity RioPacketBufferWindow is + generic( + SIZE_ADDRESS_WIDTH : natural := 6; + CONTENT_ADDRESS_WIDTH : natural := 8); + port( + clk : in std_logic; + areset_n : in std_logic; + + inboundWriteFrameFull_o : out std_logic; + inboundWriteFrame_i : in std_logic; + inboundWriteFrameAbort_i : in std_logic; + inboundWriteContent_i : in std_logic; + inboundWriteContentData_i : in std_logic_vector(31 downto 0); + inboundReadFrameEmpty_o : out std_logic; + inboundReadFrame_i : in std_logic; + inboundReadFrameRestart_i : in std_logic; + inboundReadFrameAborted_o : out std_logic; + inboundReadContentEmpty_o : out std_logic; + inboundReadContent_i : in std_logic; + inboundReadContentEnd_o : out std_logic; + inboundReadContentData_o : out std_logic_vector(31 downto 0); + + outboundWriteFrameFull_o : out std_logic; + outboundWriteFrame_i : in std_logic; + outboundWriteFrameAbort_i : in std_logic; + outboundWriteContent_i : in std_logic; + outboundWriteContentData_i : in std_logic_vector(31 downto 0); + outboundReadFrameEmpty_o : out std_logic; + outboundReadFrame_i : in std_logic; + outboundReadFrameRestart_i : in std_logic; + outboundReadFrameAborted_o : out std_logic; + outboundReadWindowEmpty_o : out std_logic; + outboundReadWindowReset_i : in std_logic; + outboundReadWindowNext_i : in std_logic; + outboundReadContentEmpty_o : out std_logic; + outboundReadContent_i : in std_logic; + outboundReadContentEnd_o : out std_logic; + outboundReadContentData_o : out std_logic_vector(31 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for RioPacketBufferWindow. +------------------------------------------------------------------------------- +architecture RioPacketBufferWindowImpl of RioPacketBufferWindow is + + component PacketBufferContinous is + generic( + SIZE_ADDRESS_WIDTH : natural; + CONTENT_ADDRESS_WIDTH : natural); + port( + clk : in std_logic; + areset_n : in std_logic; + + writeFrameFull_o : out std_logic; + writeFrame_i : in std_logic; + writeFrameAbort_i : in std_logic; + writeContent_i : in std_logic; + writeContentData_i : in std_logic_vector(31 downto 0); + + readFrameEmpty_o : out std_logic; + readFrame_i : in std_logic; + readFrameRestart_i : in std_logic; + readFrameAborted_o : out std_logic; + + readContentEmpty_o : out std_logic; + readContent_i : in std_logic; + readContentEnd_o : out std_logic; + readContentData_o : out std_logic_vector(31 downto 0)); + end component; + + component PacketBufferContinousWindow is + generic( + SIZE_ADDRESS_WIDTH : natural; + CONTENT_ADDRESS_WIDTH : natural); + port( + clk : in std_logic; + areset_n : in std_logic; + + writeFrameFull_o : out std_logic; + writeFrame_i : in std_logic; + writeFrameAbort_i : in std_logic; + writeContent_i : in std_logic; + writeContentData_i : in std_logic_vector(31 downto 0); + + readFrameEmpty_o : out std_logic; + readFrame_i : in std_logic; + readFrameRestart_i : in std_logic; + readFrameAborted_o : out std_logic; + + readWindowEmpty_o : out std_logic; + readWindowReset_i : in std_logic; + readWindowNext_i : in std_logic; + + readContentEmpty_o : out std_logic; + readContent_i : in std_logic; + readContentEnd_o : out std_logic; + readContentData_o : out std_logic_vector(31 downto 0)); + end component; + +begin + + ----------------------------------------------------------------------------- + -- Outbound frame buffers. + ----------------------------------------------------------------------------- + OutboundPacketBuffer: PacketBufferContinousWindow + generic map( + SIZE_ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH, + CONTENT_ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH) + port map( + clk=>clk, + areset_n=>areset_n, + writeFrameFull_o=>outboundWriteFrameFull_o, + writeFrame_i=>outboundWriteFrame_i, writeFrameAbort_i=>outboundWriteFrameAbort_i, + writeContent_i=>outboundWriteContent_i, writeContentData_i=>outboundWriteContentData_i, + + readFrameEmpty_o=>outboundReadFrameEmpty_o, + readFrame_i=>outboundReadFrame_i, readFrameRestart_i=>outboundReadFrameRestart_i, + readFrameAborted_o=>outboundReadFrameAborted_o, + readWindowEmpty_o=>outboundReadWindowEmpty_o, + readWindowReset_i=>outboundReadWindowReset_i, + readWindowNext_i=>outboundReadWindowNext_i, + readContentEmpty_o=>outboundReadContentEmpty_o, + readContent_i=>outboundReadContent_i, readContentEnd_o=>outboundReadContentEnd_o, + readContentData_o=>outboundReadContentData_o); + + ----------------------------------------------------------------------------- + -- Inbound frame buffers. + ----------------------------------------------------------------------------- + InboundPacketBuffer: PacketBufferContinous + generic map( + SIZE_ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH, + CONTENT_ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH) + port map( + clk=>clk, + areset_n=>areset_n, + writeFrameFull_o=>inboundWriteFrameFull_o, + writeFrame_i=>inboundWriteFrame_i, writeFrameAbort_i=>inboundWriteFrameAbort_i, + writeContent_i=>inboundWriteContent_i, writeContentData_i=>inboundWriteContentData_i, + + readFrameEmpty_o=>inboundReadFrameEmpty_o, + readFrame_i=>inboundReadFrame_i, readFrameRestart_i=>inboundReadFrameRestart_i, + readFrameAborted_o=>inboundReadFrameAborted_o, + readContentEmpty_o=>inboundReadContentEmpty_o, + readContent_i=>inboundReadContent_i, readContentEnd_o=>inboundReadContentEnd_o, + readContentData_o=>inboundReadContentData_o); + +end architecture; + + + + +------------------------------------------------------------------------------- +-- PacketBufferContinous +-- This component stores data in chuncks and stores the size of them. The full +-- memory can be used, except for one word, or a specified (using generic) +-- maximum number of frames. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + +------------------------------------------------------------------------------- +-- Entity for PacketBufferContinous. +------------------------------------------------------------------------------- +entity PacketBufferContinous is + generic( + SIZE_ADDRESS_WIDTH : natural; + CONTENT_ADDRESS_WIDTH : natural); + port( + clk : in std_logic; + areset_n : in std_logic; + + writeFrameFull_o : out std_logic; + writeFrame_i : in std_logic; + writeFrameAbort_i : in std_logic; + writeContent_i : in std_logic; + writeContentData_i : in std_logic_vector(31 downto 0); + + readFrameEmpty_o : out std_logic; + readFrame_i : in std_logic; + readFrameRestart_i : in std_logic; + readFrameAborted_o : out std_logic; + + readContentEmpty_o : out std_logic; + readContent_i : in std_logic; + readContentEnd_o : out std_logic; + readContentData_o : out std_logic_vector(31 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for PacketBufferContinous. +------------------------------------------------------------------------------- +architecture PacketBufferContinousImpl of PacketBufferContinous is + + component MemorySimpleDualPortAsync is + generic( + ADDRESS_WIDTH : natural := 1; + DATA_WIDTH : natural := 1); + port( + clkA_i : in std_logic; + enableA_i : in std_logic; + addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0); + + addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0)); + end component; + + component MemorySimpleDualPort is + generic( + ADDRESS_WIDTH : natural := 1; + DATA_WIDTH : natural := 1); + port( + clkA_i : in std_logic; + enableA_i : in std_logic; + addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0); + + clkB_i : in std_logic; + enableB_i : in std_logic; + addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0)); + end component; + + -- The number of available word positions left in the memory. + signal available : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + -- The position to place new frames. + signal backIndex, backIndexNext : unsigned(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + -- The position to remove old frames. + signal frontIndex, frontIndexNext : unsigned(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + -- The size of the current frame. + signal readFrameEnd_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + -- The start of unread content. + signal memoryStart_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + -- The current reading position. + signal memoryRead_p, memoryReadNext_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + -- The end of unread content. + signal memoryEnd_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + -- The current writing position. + signal memoryWrite_p, memoryWriteNext_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + -- Memory output signal containing the position of a frame. + signal framePositionReadData : std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); +begin + + ----------------------------------------------------------------------------- + -- Internal signal assignments. + ----------------------------------------------------------------------------- + + available <= not (memoryEnd_p - memoryStart_p); + + backIndexNext <= backIndex + 1; + frontIndexNext <= frontIndex + 1; + + memoryWriteNext_p <= memoryWrite_p + 1; + memoryReadNext_p <= memoryRead_p + 1; + + ----------------------------------------------------------------------------- + -- Writer logic. + ----------------------------------------------------------------------------- + + writeFrameFull_o <= '1' when ((backIndexNext = frontIndex) or + (available <= 68)) else '0'; + + Writer: process(clk, areset_n) + begin + if (areset_n = '0') then + backIndex <= (others=>'0'); + + memoryEnd_p <= (others=>'0'); + memoryWrite_p <= (others=>'0'); + elsif (clk'event and clk = '1') then + + if (writeFrameAbort_i = '1') then + memoryWrite_p <= memoryEnd_p; + elsif (writeContent_i = '1') then + memoryWrite_p <= memoryWriteNext_p; + end if; + + if(writeFrame_i = '1') then + memoryEnd_p <= memoryWrite_p; + backIndex <= backIndexNext; + end if; + + end if; + end process; + + ----------------------------------------------------------------------------- + -- Frame cancellation logic. + ----------------------------------------------------------------------------- + + process(clk, areset_n) + begin + if (areset_n = '0') then + readFrameAborted_o <= '0'; + elsif (clk'event and clk = '1') then + + if ((frontIndex = backIndex) and + ((writeFrameAbort_i = '1') and (readFrameRestart_i = '0'))) then + readFrameAborted_o <= '1'; + elsif ((writeFrameAbort_i = '0') and (readFrameRestart_i = '1')) then + readFrameAborted_o <= '0'; + end if; + + end if; + end process; + + ----------------------------------------------------------------------------- + -- Reader logic. + ----------------------------------------------------------------------------- + + readFrameEmpty_o <= '1' when (frontIndex = backIndex) else '0'; + readContentEmpty_o <= '1' when ((frontIndex = backIndex) and + (memoryWrite_p = memoryRead_p)) else '0'; + + Reader: process(clk, areset_n) + begin + if (areset_n = '0') then + frontIndex <= (others=>'0'); + + memoryStart_p <= (others=>'0'); + memoryRead_p <= (others=>'0'); + + readContentEnd_o <= '0'; + elsif (clk'event and clk = '1') then + + -- REMARK: Break apart into registers to avoid priority ladder??? + if(readFrameRestart_i = '1') then + memoryRead_p <= memoryStart_p; + elsif(readContent_i = '1') then + if(memoryRead_p = readFrameEnd_p) then + readContentEnd_o <= '1'; + else + readContentEnd_o <= '0'; + memoryRead_p <= memoryReadNext_p; + end if; + elsif(readFrame_i = '1') then + memoryStart_p <= readFrameEnd_p; + frontIndex <= frontIndexNext; + memoryRead_p <= readFrameEnd_p; + end if; + + end if; + end process; + + ----------------------------------------------------------------------------- + -- Frame positioning memory signals. + ----------------------------------------------------------------------------- + + readFrameEnd_p <= unsigned(framePositionReadData); + + -- Memory to keep frame starting/ending positions in. + FramePosition: MemorySimpleDualPortAsync + generic map(ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH, DATA_WIDTH=>CONTENT_ADDRESS_WIDTH) + port map( + clkA_i=>clk, enableA_i=>writeFrame_i, + addressA_i=>std_logic_vector(backIndex), dataA_i=>std_logic_vector(memoryWrite_p), + addressB_i=>std_logic_vector(frontIndex), dataB_o=>framePositionReadData); + + ----------------------------------------------------------------------------- + -- Frame content memory signals. + ----------------------------------------------------------------------------- + + -- Memory to keep frame content in. + -- REMARK: Use paritybits here as well to make sure the frame data does not + -- become corrupt??? + FrameContent: MemorySimpleDualPort + generic map(ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH, DATA_WIDTH=>32) + port map( + clkA_i=>clk, enableA_i=>writeContent_i, + addressA_i=>std_logic_vector(memoryWrite_p), dataA_i=>writeContentData_i, + clkB_i=>clk, enableB_i=>readContent_i, + addressB_i=>std_logic_vector(memoryRead_p), dataB_o=>readContentData_o); + +end architecture; + + + +------------------------------------------------------------------------------- +-- PacketBufferContinousWindow +-- This component stores data in chuncks and stores the size of them. The full +-- memory can be used, except for one word, or a specified (using generic) +-- maximum number of frames. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + +------------------------------------------------------------------------------- +-- Entity for PacketBufferContinousWindow. +------------------------------------------------------------------------------- +entity PacketBufferContinousWindow is + generic( + SIZE_ADDRESS_WIDTH : natural; + CONTENT_ADDRESS_WIDTH : natural); + port( + clk : in std_logic; + areset_n : in std_logic; + + writeFrameFull_o : out std_logic; + writeFrame_i : in std_logic; + writeFrameAbort_i : in std_logic; + writeContent_i : in std_logic; + writeContentData_i : in std_logic_vector(31 downto 0); + + readFrameEmpty_o : out std_logic; + readFrame_i : in std_logic; + readFrameRestart_i : in std_logic; + readFrameAborted_o : out std_logic; + + readWindowEmpty_o : out std_logic; + readWindowReset_i : in std_logic; + readWindowNext_i : in std_logic; + + readContentEmpty_o : out std_logic; + readContent_i : in std_logic; + readContentEnd_o : out std_logic; + readContentData_o : out std_logic_vector(31 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for PacketBufferContinousWindow. +------------------------------------------------------------------------------- +architecture PacketBufferContinousWindowImpl of PacketBufferContinousWindow is + + component MemorySimpleDualPortAsync is + generic( + ADDRESS_WIDTH : natural := 1; + DATA_WIDTH : natural := 1); + port( + clkA_i : in std_logic; + enableA_i : in std_logic; + addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0); + + addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0)); + end component; + + component MemorySimpleDualPort is + generic( + ADDRESS_WIDTH : natural := 1; + DATA_WIDTH : natural := 1); + port( + clkA_i : in std_logic; + enableA_i : in std_logic; + addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0); + + clkB_i : in std_logic; + enableB_i : in std_logic; + addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0)); + end component; + + -- The number of available word positions left in the memory. + signal available : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + signal backIndex, backIndexNext : unsigned(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + signal frontIndex, frontIndexNext : unsigned(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + signal windowIndex, windowIndexNext : unsigned(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + -- The size of the current frame. + signal readFrameEnd_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + -- The start of unread content. + signal memoryStart_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + -- The start of unread window content. + signal memoryStartWindow_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + -- The current reading position. + signal memoryRead_p, memoryReadNext_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + -- The end of unread content. + signal memoryEnd_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + -- The current writing position. + signal memoryWrite_p, memoryWriteNext_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + + signal framePositionReadAddress : std_logic_vector(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); + signal framePositionReadData : std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0'); +begin + + ----------------------------------------------------------------------------- + -- Internal signal assignments. + ----------------------------------------------------------------------------- + + available <= not (memoryEnd_p - memoryStart_p); + + backIndexNext <= backIndex + 1; + frontIndexNext <= frontIndex + 1; + windowIndexNext <= windowIndex + 1; + + memoryWriteNext_p <= memoryWrite_p + 1; + memoryReadNext_p <= memoryRead_p + 1; + + ----------------------------------------------------------------------------- + -- Writer logic. + ----------------------------------------------------------------------------- + + writeFrameFull_o <= '1' when ((backIndexNext = frontIndex) or + (available <= 68)) else '0'; + + Writer: process(clk, areset_n) + begin + if (areset_n = '0') then + backIndex <= (others=>'0'); + + memoryEnd_p <= (others=>'0'); + memoryWrite_p <= (others=>'0'); + elsif (clk'event and clk = '1') then + + if (writeFrameAbort_i = '1') then + memoryWrite_p <= memoryEnd_p; + elsif (writeContent_i = '1') then + memoryWrite_p <= memoryWriteNext_p; + end if; + + if(writeFrame_i = '1') then + memoryEnd_p <= memoryWrite_p; + backIndex <= backIndexNext; + end if; + + end if; + end process; + + ----------------------------------------------------------------------------- + -- Frame cancellation logic. + ----------------------------------------------------------------------------- + + process(clk, areset_n) + begin + if (areset_n = '0') then + readFrameAborted_o <= '0'; + elsif (clk'event and clk = '1') then + + if ((windowIndex = backIndex) and + ((writeFrameAbort_i = '1') and (readFrameRestart_i = '0'))) then + readFrameAborted_o <= '1'; + elsif ((writeFrameAbort_i = '0') and (readFrameRestart_i = '1')) then + readFrameAborted_o <= '0'; + end if; + + end if; + end process; + + ----------------------------------------------------------------------------- + -- Reader logic. + ----------------------------------------------------------------------------- + + readFrameEmpty_o <= '1' when (frontIndex = backIndex) else '0'; + readWindowEmpty_o <= '1' when (windowIndex = backIndex) else '0'; + readContentEmpty_o <= '1' when ((windowIndex = backIndex) and + (memoryWrite_p = memoryRead_p)) else '0'; + + Reader: process(clk, areset_n) + begin + if (areset_n = '0') then + frontIndex <= (others=>'0'); + windowIndex <= (others=>'0'); + + memoryStart_p <= (others=>'0'); + memoryStartWindow_p <= (others=>'0'); + memoryRead_p <= (others=>'0'); + + readContentEnd_o <= '0'; + elsif (clk'event and clk = '1') then + + -- REMARK: Break apart into registers to avoid priority ladder??? + if(readFrameRestart_i = '1') then + memoryRead_p <= memoryStartWindow_p; + elsif(readContent_i = '1') then + if(memoryReadNext_p = readFrameEnd_p) then + readContentEnd_o <= '1'; + else + readContentEnd_o <= '0'; + memoryRead_p <= memoryReadNext_p; + end if; + elsif(readFrame_i = '1') then + memoryStart_p <= readFrameEnd_p; + frontIndex <= frontIndexNext; + elsif(readWindowReset_i = '1') then + memoryStartWindow_p <= memoryStart_p; + windowIndex <= frontIndex; + memoryRead_p <= memoryStart_p; + elsif(readWindowNext_i = '1') then + memoryStartWindow_p <= readFrameEnd_p; + windowIndex <= windowIndexNext; + memoryRead_p <= readFrameEnd_p; + end if; + + end if; + end process; + + ----------------------------------------------------------------------------- + -- Frame positioning memory signals. + ----------------------------------------------------------------------------- + + -- Assign the address from both frontIndex and windowIndex to be able to + -- share the memory between the two different types of accesses. This assumes + -- that the window is not accessed at the same time as the other signal. + framePositionReadAddress <= std_logic_vector(frontIndex) when (readFrame_i = '1') else + std_logic_vector(windowIndex); + readFrameEnd_p <= unsigned(framePositionReadData); + + -- Memory to keep frame starting/ending positions in. + FramePosition: MemorySimpleDualPortAsync + generic map(ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH, DATA_WIDTH=>CONTENT_ADDRESS_WIDTH) + port map( + clkA_i=>clk, enableA_i=>writeFrame_i, + addressA_i=>std_logic_vector(backIndex), dataA_i=>std_logic_vector(memoryWrite_p), + addressB_i=>framePositionReadAddress, dataB_o=>framePositionReadData); + + ----------------------------------------------------------------------------- + -- Frame content memory signals. + ----------------------------------------------------------------------------- + + -- Memory to keep frame content in. + -- REMARK: Use paritybits here as well to make sure the frame data does not + -- become corrupt??? + FrameContent: MemorySimpleDualPort + generic map(ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH, DATA_WIDTH=>32) + port map( + clkA_i=>clk, enableA_i=>writeContent_i, + addressA_i=>std_logic_vector(memoryWrite_p), dataA_i=>writeContentData_i, + clkB_i=>clk, enableB_i=>readContent_i, + addressB_i=>std_logic_vector(memoryRead_p), dataB_o=>readContentData_o); + +end architecture;
2.0.0-alpha/rtl/vhdl/RioPacketBuffer.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: 2.0.0-alpha/rtl/vhdl/srio_pcs_struct.vhd =================================================================== --- 2.0.0-alpha/rtl/vhdl/srio_pcs_struct.vhd (nonexistent) +++ 2.0.0-alpha/rtl/vhdl/srio_pcs_struct.vhd (revision 23) @@ -0,0 +1,2912 @@ +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- To Do: +-- - +-- +-- Author(s): +-- - A. Demirezen, azdem@opencores.org +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- +-- File name: ccs_timer.vhd +-- Rev: 0.0 +-- Description: This entity watches the CCS (clock compensation sequence) +-- insertion according to RIO Sepec. Part-6, subchapter 4.7.1 +-- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_unsigned.all; +use work.rio_common.all; + +entity ccs_timer is + generic ( + TCQ : time := 100 ps + ); + port ( + rst_n : in std_logic; + UCLK : in std_logic; + + send_ccs : out std_logic; + ccs_timer_rst : in std_logic + ); +end ccs_timer; + +architecture RTL of ccs_timer is +-------------------------------------------------------------------------------------- +signal ccs_counter : std_logic_vector(11 downto 0) := (others => '0'); +constant CCS_INTERVAL : std_logic_vector(11 downto 0) := x"7FF"; -- = 4096 chars + +-------------------------------------------------------------------------------------- +begin + +-- CCS counter process +process(rst_n, UCLK) + begin + if rst_n = '0' then + ccs_counter <= CCS_INTERVAL; + send_ccs <= '0'; + elsif rising_edge(UCLK) then + if ccs_timer_rst = '0' then + if ccs_counter = CCS_INTERVAL then + send_ccs <= '1'; + else + send_ccs <= '0'; + ccs_counter <= ccs_counter + '1'; + end if; + else + send_ccs <= '0'; + ccs_counter <= (others => '0'); + end if; + end if; +end process; + +end RTL; +--------------------------------------------------------------------------------------- +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- To Do: +-- - +-- +-- Author(s): +-- - A. Demirezen, azdem@opencores.org +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- +-- File name: idle_generator.vhd +-- Rev: 0.0 +-- Description: This entity generates IDLE1 sequence for SRIO PHY +-- RIO Sepec. Part-6, subchapter 4.7.2 +-- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_unsigned.all; +use work.rio_common.all; + +entity idle_generator is + generic ( + lfsr_init : std_logic_vector(7 downto 0) := x"01"; + TCQ : time := 100 ps + ); + port ( + UCLK : in std_logic; + rst_n : in std_logic; + + send_idle : in std_logic; + + send_K : out std_logic; + send_A : out std_logic; + send_R : out std_logic + ); +end idle_generator; + +architecture RTL of idle_generator is +------------------------------------------------------------------------------------------------------------------------------------------- +signal q_pseudo_random_number : std_logic_vector(7 downto 0) := (others => '0'); +signal pseudo_random_bit : std_logic := '0'; + +signal down_counter_load_value : std_logic_vector(4 downto 0) := (others => '0'); +signal down_counter : std_logic_vector(4 downto 0) := (others => '0'); +signal Acntr_eq_zero : std_logic := '0'; +signal send_idle_q : std_logic := '0'; +-- + +COMPONENT pseudo_random_number_generator +GENERIC ( + lfsr_init : std_logic_vector(7 downto 0) + ); +PORT( + clk : IN std_logic; + rst_n : IN std_logic; + q : OUT std_logic_vector(7 downto 0) + ); +END COMPONENT; + +------------------------------------------------------------------------------------------------------------------------------------------- +begin + +inst_prng: pseudo_random_number_generator GENERIC MAP( + lfsr_init => lfsr_init --x"01" + ) + PORT MAP( + clk => UCLK, + rst_n => rst_n, + q => q_pseudo_random_number + ); + +pseudo_random_bit <= q_pseudo_random_number(0); + +down_counter_load_value <= '1' & q_pseudo_random_number(6) & q_pseudo_random_number(4) & q_pseudo_random_number(3) & q_pseudo_random_number(1); + +-- down counter process +process(rst_n, UCLK) + begin + if rst_n = '0' then + down_counter <= (others => '0'); + elsif rising_edge(UCLK) then + if Acntr_eq_zero = '1' then + down_counter <= down_counter_load_value; + else + down_counter <= down_counter - '1'; + end if; + end if; +end process; + +Acntr_eq_zero <= '1' when down_counter = "00000" else '0'; + +-- send_idle delay process +process(rst_n, UCLK) + begin + if rst_n = '0' then + send_idle_q <= '0'; + elsif rising_edge(UCLK) then + send_idle_q <= send_idle; + end if; +end process; + +send_K <= send_idle and (not(send_idle_q) or (send_idle_q and not(Acntr_eq_zero) and pseudo_random_bit)); +send_A <= send_idle and send_idle_q and Acntr_eq_zero; +send_R <= send_idle and send_idle_q and not(Acntr_eq_zero) and not(pseudo_random_bit); + +end RTL; +------------------------------------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- To Do: +-- - +-- +-- Author(s): +-- - A. Demirezen, azdem@opencores.org +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- +-- File name: idle_generator_dual.vhd +-- Rev: 0.0 +-- Description: This entity generates IDLE1 sequence for SRIO PHY +-- RIO Sepec. Part-6, subchapter 4.7.2 +-- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_unsigned.all; +use work.rio_common.all; + +entity idle_generator_dual is + generic ( + TCQ : time := 100 ps + ); + port ( + UCLK : in std_logic; + rst_n : in std_logic; + + send_idle : in std_logic_vector(1 downto 0); + + send_K : out std_logic_vector(1 downto 0); + send_A : out std_logic_vector(1 downto 0); + send_R : out std_logic_vector(1 downto 0) + ); +end idle_generator_dual; + +architecture RTL of idle_generator_dual is +------------------------------------------------------------------------------------------------------------------------------------------- + +COMPONENT idle_generator + generic ( + lfsr_init : std_logic_vector(7 downto 0); + TCQ : time + ); +PORT( + UCLK : IN std_logic; + rst_n : IN std_logic; + send_idle : IN std_logic; + send_K : OUT std_logic; + send_A : OUT std_logic; + send_R : OUT std_logic + ); +END COMPONENT; + +------------------------------------------------------------------------------------------------------------------------------------------- +begin + + Inst_idle_generator_0: idle_generator GENERIC MAP( + TCQ => 100 ps, + lfsr_init => x"0F" + ) + PORT MAP( + UCLK => UCLK, + rst_n => rst_n, + send_idle => send_idle(0), + send_K => send_K(0), + send_A => send_A(0), + send_R => send_R(0) + ); + + Inst_idle_generator_1: idle_generator GENERIC MAP( + TCQ => 100 ps, + lfsr_init => x"F0" + ) + PORT MAP( + UCLK => UCLK, + rst_n => rst_n, + send_idle => send_idle(1), + send_K => send_K(1), + send_A => send_A(1), + send_R => send_R(1) + ); + +end RTL; +------------------------------------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- To Do: +-- - +-- +-- Author(s): +-- - A. Demirezen, azdem@opencores.org +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- +-- File name: pcs_rx_controller.vhd +-- Rev: 0.0 +-- Description: This entity controls the RX stream +-- +-- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_unsigned.all; +use work.rio_common.all; + +entity pcs_rx_controller is + generic ( + TCQ : time := 100 ps + ); + port ( + rst_n : in std_logic; + rio_clk : in std_logic; -- ~150 MHz + UCLK_x2 : in std_logic; -- 312,5 MHz + UCLK : in std_logic; -- 156,25 MHz + UCLK_x2_DV2 : in std_logic; -- 312,5 MHz @ x4 mode / 78,125 @ x1 (fallback mode) + UCLK_or_DV4 : in std_logic; -- 156,25 MHz @ x4 mode / 39,0625 @ x1 (fallback mode) + -- UCLK_DV4 : in std_logic; -- 39,0625 + -- + -- Interface to the RioSerial + inboundRead_i : in std_logic; + inboundEmpty_o : out std_logic; + inboundSymbol_o : out std_logic_vector(33 downto 0); + -- + -- Interface to the GTX transceivers + RXDATA_i : in std_logic_vector(63 downto 0); -- N = 4 + RXCHARISK_i : in std_logic_vector(7 downto 0); + RXCHARISvalid_i : in std_logic_vector(7 downto 0); + -- + -- Interface to the port init + port_initalized_i : in std_logic; + mode_sel_i : in std_logic; + mode_0_lane_sel_i : in std_logic + + ); +end pcs_rx_controller; + +architecture RTL of pcs_rx_controller is + +------------------------------------------------------------------------------- +COMPONENT pcs_rx_boudary_32b_out_64b_in + PORT ( + rst : IN STD_LOGIC; + wr_clk : IN STD_LOGIC; + rd_clk : IN STD_LOGIC; + din : IN STD_LOGIC_VECTOR(67 DOWNTO 0); + wr_en : IN STD_LOGIC; + rd_en : IN STD_LOGIC; + dout : OUT STD_LOGIC_VECTOR(33 DOWNTO 0); + full : OUT STD_LOGIC; + almost_full : OUT STD_LOGIC; + empty : OUT STD_LOGIC; + almost_empty : OUT STD_LOGIC; + valid : OUT STD_LOGIC + ); +END COMPONENT; +------------------------------------------------------------------------------- +signal rst : std_logic:= '0'; + +signal RXDATA_swap : std_logic_vector(63 downto 0) := (others => '0'); +signal RXCHARISK_swap : std_logic_vector(7 downto 0) := (others => '0'); +signal RXCHARISvalid_swap : std_logic_vector(7 downto 0) := (others => '0'); + +signal RXDATA_u : std_logic_vector(31 downto 0) := (others => '0'); +signal RXCHARISK_u : std_logic_vector(3 downto 0) := (others => '0'); +signal RXDATA_l : std_logic_vector(31 downto 0) := (others => '0'); +signal RXCHARISK_l : std_logic_vector(3 downto 0) := (others => '0'); +signal RXCHARISvalid_u : std_logic_vector(3 downto 0) := (others => '0'); +signal RXCHARISvalid_l : std_logic_vector(3 downto 0) := (others => '0'); + +signal inboundValid : std_logic:= '0'; +signal rx_fifo_wr_en : std_logic:= '0'; +signal rx_fifo_wr_en_q : std_logic:= '0'; +signal rx_fifo_full : std_logic:= '0'; +signal rx_fifo_almost_full : std_logic:= '0'; +signal rx_fifo_almost_empty : std_logic:= '0'; + +signal rx_fifo_data_in : std_logic_vector(67 downto 0) := (others => '0'); +signal rx_fifo_data_in_q : std_logic_vector(67 downto 0) := (others => '0'); +signal rx_fifo_data_swapped : std_logic_vector(67 downto 0) := (others => '0'); +signal rx_fifo_full_p : std_logic:= '0'; + +signal port_initalized : std_logic:= '0'; +signal mode_sel : std_logic:= '0'; +signal mode_0_lane_sel : std_logic:= '0'; + +signal port_state : std_logic_vector(2 downto 0) := (others => '0'); + +signal upper_symbol_type : std_logic_vector(1 downto 0) := (others => '0'); +signal lower_symbol_type : std_logic_vector(1 downto 0) := (others => '0'); + +signal upper_symbol_not_idle : std_logic:= '0'; +signal lower_symbol_not_idle : std_logic:= '0'; +signal upper_symbol_valid : std_logic:= '0'; +signal lower_symbol_valid : std_logic:= '0'; +signal upper_symbol_not_error : std_logic:= '0'; +signal lower_symbol_not_error : std_logic:= '0'; + +-- signal RXDATA_sr : std_logic_vector(63 downto 0) := (others => '0'); +-- signal RXCHARISK_sr : std_logic_vector(7 downto 0) := (others => '0'); +-- signal RXCHARISvalid_sr : std_logic_vector(7 downto 0) := (others => '0'); + +signal RXDATA_sr_done : std_logic_vector(63 downto 0) := (others => '0'); +signal RXCHARISK_sr_done : std_logic_vector(7 downto 0) := (others => '0'); +signal RXCHARISvalid_sr_done : std_logic_vector(7 downto 0) := (others => '0'); + +signal RXDATA_sr : std_logic_vector(71 downto 0) := (others => '0'); +signal RXCHARISK_sr : std_logic_vector(8 downto 0) := (others => '0'); +signal RXCHARISvalid_sr : std_logic_vector(8 downto 0) := (others => '0'); + +signal RXDATA_R_lane : std_logic_vector(15 downto 0) := (others => '0'); +signal RXCHARISK_R_lane : std_logic_vector(1 downto 0) := (others => '0'); +signal RXCHARISvalid_R_lane : std_logic_vector(1 downto 0) := (others => '0'); + +signal valid_byte_cntr : std_logic_vector(2 downto 0) := (others => '0'); +signal irregular_stream : std_logic:= '0'; +signal done_cntr : std_logic_vector(1 downto 0) := (others => '0'); +signal rx_done : std_logic:= '0'; + +signal u_l_switch : std_logic:= '0'; + +-- signal sr_symbol_not_idle : std_logic:= '0'; +-- signal sr_symbol_not_idle_q : std_logic:= '0'; +-- signal sr_symbol_not_error : std_logic:= '0'; +-- signal sr_symbol_not_error_q : std_logic:= '0'; +-- signal RXDATA_sr : std_logic_vector(31 downto 0) := (others => '0'); +-- signal RXCHARISK_sr : std_logic_vector(3 downto 0) := (others => '0'); +-- signal RXCHARISvalid_sr : std_logic_vector(3 downto 0) := (others => '0'); +-- signal sr_symbol_type : std_logic_vector(1 downto 0) := (others => '0'); + +signal sr_u_symbol_not_idle : std_logic:= '0'; +signal sr_u_symbol_not_idle_q : std_logic:= '0'; +signal sr_u_symbol_not_error : std_logic:= '0'; +signal sr_u_symbol_not_error_q : std_logic:= '0'; +signal RXDATA_u_sr : std_logic_vector(31 downto 0) := (others => '0'); +signal RXCHARISK_u_sr : std_logic_vector(3 downto 0) := (others => '0'); +signal RXCHARISvalid_u_sr : std_logic_vector(3 downto 0) := (others => '0'); +signal sr_u_symbol_type : std_logic_vector(1 downto 0) := (others => '0'); + +signal sr_l_symbol_not_idle : std_logic:= '0'; +signal sr_l_symbol_not_idle_q : std_logic:= '0'; +signal sr_l_symbol_not_error : std_logic:= '0'; +signal sr_l_symbol_not_error_q : std_logic:= '0'; +signal RXDATA_sr_l : std_logic_vector(31 downto 0) := (others => '0'); +signal RXCHARISK_sr_l : std_logic_vector(3 downto 0) := (others => '0'); +signal RXCHARISvalid_sr_l : std_logic_vector(3 downto 0) := (others => '0'); +signal sr_l_symbol_type : std_logic_vector(1 downto 0) := (others => '0'); + + +signal started_once : std_logic:= '0'; +signal word_switch : std_logic:= '0'; +signal shift_cntr : std_logic_vector(1 downto 0) := (others => '0'); + + +---------------------------------------------------------------------------------- +begin +rst <= not(rst_n); + +rx_boundary_fifo : pcs_rx_boudary_32b_out_64b_in -- FWFT FIFO + PORT MAP ( + rst => rst, + rd_clk => rio_clk, + rd_en => inboundRead_i, + dout => inboundSymbol_o, + valid => inboundValid, + empty => inboundEmpty_o, + almost_empty => rx_fifo_almost_empty, + + wr_clk => UCLK_or_DV4, + wr_en => rx_fifo_wr_en_q, -- rx_fifo_wr_en, -- rx_fifo_wr_en_q, -- + din => rx_fifo_data_in_q, -- rx_fifo_data_in, -- rx_fifo_data_in_q, -- + full => rx_fifo_full, -- rx_fifo_full + almost_full => rx_fifo_almost_full -- rx_fifo_full + ); + +-- Pipelining RX write +process(UCLK_or_DV4) + begin + if rising_edge(UCLK_or_DV4) then + rx_fifo_wr_en_q <= rx_fifo_wr_en; + rx_fifo_data_in_q <= rx_fifo_data_in; + end if; +end process; + + +-- rx_fifo_data_swapped <= rx_fifo_data_in(33 downto 32) +-- & rx_fifo_data_in(7 downto 0) & rx_fifo_data_in(15 downto 8) & rx_fifo_data_in(23 downto 16) & rx_fifo_data_in(31 downto 24); + +port_initalized <= port_initalized_i; +mode_sel <= mode_sel_i; +mode_0_lane_sel <= mode_0_lane_sel_i; + +port_state <= port_initalized & mode_sel & mode_0_lane_sel; + +-- RX management / FIFO write process +process(rst_n, UCLK) -- _x2 + begin + if rst_n = '0' then + + rx_fifo_wr_en <= '0'; + word_switch <= '0'; + started_once <= '0'; + rx_fifo_data_in <= (others => '0'); + -- RXDATA_sr <= (others => '0'); + -- RXCHARISK_sr <= (others => '1'); + -- RXCHARISvalid_sr <= (others => '0'); + shift_cntr <= (others => '0'); + + elsif rising_edge(UCLK) then + -- Alternative If-Else Statement + if port_initalized = '0' then -- Port has not been initialized yet + rx_fifo_wr_en <= '0'; + rx_fifo_data_in <= (others => '0'); + else -- Port has been initialized + -- if mode_sel = '1' then -- x4 mode is active + if upper_symbol_valid = '1' and lower_symbol_valid = '1' then + rx_fifo_data_in <= upper_symbol_type & RXDATA_u & lower_symbol_type & RXDATA_l; + rx_fifo_wr_en <= not(rx_fifo_almost_full); + elsif upper_symbol_valid = '1' then + rx_fifo_data_in <= upper_symbol_type & RXDATA_u & SYMBOL_IDLE & x"00000000"; + rx_fifo_wr_en <= not(rx_fifo_almost_full); + elsif lower_symbol_valid = '1' then + rx_fifo_data_in <= SYMBOL_IDLE & x"00000000" & lower_symbol_type & RXDATA_l; + rx_fifo_wr_en <= not(rx_fifo_almost_full); + else + rx_fifo_wr_en <= '0'; + end if; + -- else -- x1 fallback mode is active + -- if upper_symbol_valid = '1' and lower_symbol_valid = '1' then + -- rx_fifo_data_in <= upper_symbol_type & RXDATA_u & lower_symbol_type & RXDATA_l; + -- rx_fifo_wr_en <= not(rx_fifo_full); + -- elsif upper_symbol_valid = '1' then + -- rx_fifo_data_in <= upper_symbol_type & RXDATA_u & SYMBOL_IDLE & RXDATA_l; + -- rx_fifo_wr_en <= not(rx_fifo_full); + -- elsif lower_symbol_valid = '1' then + -- rx_fifo_data_in <= SYMBOL_IDLE & RXDATA_u & lower_symbol_type & RXDATA_l; + -- rx_fifo_wr_en <= not(rx_fifo_full); + -- else + -- rx_fifo_wr_en <= '0'; + -- end if; + -- end if; + end if; + end if; +end process; +------------------------------------------------------------------------------------------------------------------------------------------------------- + +-- -- Pipelining RX stream +-- process(UCLK) +-- begin +-- if rising_edge(UCLK) then +-- RXDATA_swap <= RXDATA_i(15 downto 0) & RXDATA_i(31 downto 16) & RXDATA_i(47 downto 32) & RXDATA_i(63 downto 48); +-- RXCHARISK_swap <= RXCHARISK_i(1 downto 0) & RXCHARISK_i(3 downto 2) & RXCHARISK_i(5 downto 4) & RXCHARISK_i(7 downto 6); +-- RXCHARISvalid_swap <= RXCHARISvalid_i(1 downto 0) & RXCHARISvalid_i(3 downto 2) & RXCHARISvalid_i(5 downto 4) & RXCHARISvalid_i(7 downto 6); +-- end if; +-- end process; + +-- Pipelining RX stream +process(UCLK) + begin + if rising_edge(UCLK) then + + RXDATA_swap <= RXDATA_i(15 downto 0) & RXDATA_i(31 downto 16) & RXDATA_i(47 downto 32) & RXDATA_i(63 downto 48); + RXCHARISK_swap <= RXCHARISK_i(1 downto 0) & RXCHARISK_i(3 downto 2) & RXCHARISK_i(5 downto 4) & RXCHARISK_i(7 downto 6); + RXCHARISvalid_swap <= RXCHARISvalid_i(1 downto 0) & RXCHARISvalid_i(3 downto 2) & RXCHARISvalid_i(5 downto 4) & RXCHARISvalid_i(7 downto 6); + + -- if mode_sel = '1' then -- x4 mode is active + + -- else -- x1 fallback mode is active + -- + -- RXDATA_swap <= RXDATA_sr_done ; + -- RXCHARISK_swap <= RXCHARISK_sr_done ; + -- RXCHARISvalid_swap <= RXCHARISvalid_sr_done ; + -- + -- end if; + end if; +end process; +--- Lane 0 active Lane 2 active +RXDATA_R_lane <= RXDATA_i(15 downto 0) when mode_0_lane_sel = '0' else RXDATA_i(47 downto 32) ; +RXCHARISK_R_lane <= RXCHARISK_i(1 downto 0) when mode_0_lane_sel = '0' else RXCHARISK_i(5 downto 4) ; +RXCHARISvalid_R_lane <= RXCHARISvalid_i(1 downto 0) when mode_0_lane_sel = '0' else RXCHARISvalid_i(5 downto 4) ; + +-- RXDATA shifting process for x1 mode +process(UCLK) -- _x2 rst_n, + begin + -- if rst_n = '0' then + -- + -- RXDATA_sr <= (others => '0'); + -- RXCHARISK_sr <= (others => '1'); + -- RXCHARISvalid_sr <= (others => '0'); + -- valid_byte_cntr <= (others => '0'); + -- + -- RXDATA_sr_done <= (others => '0'); + -- RXCHARISK_sr_done <= (others => '1'); + -- RXCHARISvalid_sr_done <= (others => '0'); + -- + -- done_cntr <= (others => '0'); + -- rx_done <= '0'; + -- + -- els + if rising_edge(UCLK) then + + if port_initalized = '0' then -- Port has not been initialized yet + + RXDATA_sr <= (others => '0'); + RXCHARISK_sr <= (others => '1'); + RXCHARISvalid_sr <= (others => '0'); + valid_byte_cntr <= (others => '0'); + + RXDATA_sr_done <= (others => '0'); + RXCHARISK_sr_done <= (others => '1'); + RXCHARISvalid_sr_done <= (others => '0'); + + done_cntr <= (others => '0'); + rx_done <= '0'; + + else + done_cntr <= done_cntr + rx_done; + if RXCHARISvalid_R_lane(0) = '1' and (RXCHARISK_R_lane(0) = '0' or (RXCHARISK_R_lane(0) = '1' and (RXDATA_R_lane(7 downto 0) = SC or RXDATA_R_lane(7 downto 0) = PD))) then + if RXCHARISvalid_R_lane(1) = '1' and (RXCHARISK_R_lane(1) = '0' or (RXCHARISK_R_lane(1) = '1' and (RXDATA_R_lane(15 downto 8) = SC or RXDATA_R_lane(15 downto 8) = PD))) then + --- [VVVV] It may appear anytime + valid_byte_cntr <= valid_byte_cntr + "10"; + RXDATA_sr <= RXDATA_sr(55 downto 0) & RXDATA_R_lane(15 downto 0); + RXCHARISK_sr <= RXCHARISK_sr(6 downto 0) & RXCHARISK_R_lane(1 downto 0); + RXCHARISvalid_sr <= RXCHARISvalid_sr(6 downto 0) & RXCHARISvalid_R_lane(1 downto 0); + if valid_byte_cntr = "110" then + irregular_stream <= '0'; + rx_done <= '1'; + done_cntr <= (others => '0'); + RXDATA_sr_done <= RXDATA_sr(47 downto 0) & RXDATA_R_lane(15 downto 0); + RXCHARISK_sr_done <= RXCHARISK_sr(5 downto 0) & RXCHARISK_R_lane(1 downto 0); + RXCHARISvalid_sr_done <= RXCHARISvalid_sr(5 downto 0) & RXCHARISvalid_R_lane(1 downto 0); + elsif valid_byte_cntr = "111" then + irregular_stream <= '1'; + rx_done <= '1'; + done_cntr <= (others => '0'); + RXDATA_sr_done <= RXDATA_sr(55 downto 0) & RXDATA_R_lane(15 downto 8); + RXCHARISK_sr_done <= RXCHARISK_sr(6 downto 0) & RXCHARISK_R_lane(1); + RXCHARISvalid_sr_done <= RXCHARISvalid_sr(6 downto 0) & RXCHARISvalid_R_lane(1); + elsif done_cntr = "11" then + rx_done <= '0'; + RXCHARISK_sr_done <= (others => '1'); + RXCHARISvalid_sr_done <= (others => '0'); + end if; + else + --- [__VV] : It can appear only in the beginning + if valid_byte_cntr = "100" then + valid_byte_cntr <= valid_byte_cntr + '1'; + else -- either it is an irregular start or something went wrong + valid_byte_cntr <= "001"; + irregular_stream <= '1'; + end if; + RXDATA_sr <= RXDATA_sr(63 downto 0) & RXDATA_R_lane(7 downto 0); + RXCHARISK_sr <= RXCHARISK_sr(7 downto 0) & RXCHARISK_R_lane(0); + RXCHARISvalid_sr <= RXCHARISvalid_sr(7 downto 0) & RXCHARISvalid_R_lane(0); + if done_cntr = "11" then + rx_done <= '0'; + RXCHARISK_sr_done <= (others => '1'); + RXCHARISvalid_sr_done <= (others => '0'); + end if; + end if; + else + if RXCHARISvalid_R_lane(1) = '1' and (RXCHARISK_R_lane(1) = '0' or (RXCHARISK_R_lane(1) = '1' and (RXDATA_R_lane(15 downto 8) = SC or RXDATA_R_lane(15 downto 8) = PD))) then + --- [VV__] : It can appear only in the end + RXDATA_sr <= RXDATA_sr(63 downto 0) & RXDATA_R_lane(15 downto 8); + RXCHARISK_sr <= RXCHARISK_sr(7 downto 0) & RXCHARISK_R_lane(1); + RXCHARISvalid_sr <= RXCHARISvalid_sr(7 downto 0) & RXCHARISvalid_R_lane(1); + if valid_byte_cntr = "011" then + valid_byte_cntr <= valid_byte_cntr + '1'; + irregular_stream <= '0'; -- irregularity has been compensated for the first symbol + if done_cntr = "11" then + rx_done <= '0'; + RXCHARISK_sr_done <= (others => '1'); + RXCHARISvalid_sr_done <= (others => '0'); + end if; + elsif valid_byte_cntr = "111" then -- 2 symbols (2x32b) are done + valid_byte_cntr <= (others => '0'); + irregular_stream <= '0'; -- irregularity has been compensated for the second symbol + rx_done <= '1'; + done_cntr <= (others => '0'); + RXDATA_sr_done <= RXDATA_sr(55 downto 0) & RXDATA_R_lane(15 downto 8); + RXCHARISK_sr_done <= RXCHARISK_sr(6 downto 0) & RXCHARISK_R_lane(1); + RXCHARISvalid_sr_done <= RXCHARISvalid_sr(6 downto 0) & RXCHARISvalid_R_lane(1); + else -- something went wrong + valid_byte_cntr <= (others => '0'); + irregular_stream <= '0'; + if done_cntr = "11" then + rx_done <= '0'; + RXCHARISK_sr_done <= (others => '1'); + RXCHARISvalid_sr_done <= (others => '0'); + end if; + end if; + else + --- [____] + if valid_byte_cntr /= "100" then -- No IDLE allowed, unless between two symbols: Something went wrong probably + valid_byte_cntr <= "000"; + irregular_stream <= '0'; + end if; + if done_cntr = "11" then + rx_done <= '0'; + RXCHARISK_sr_done <= (others => '1'); + RXCHARISvalid_sr_done <= (others => '0'); + end if; + end if; + end if; + end if; + end if; +end process; + +RXDATA_u <= RXDATA_swap(63 downto 56) & RXDATA_swap(47 downto 40) & RXDATA_swap(31 downto 24) & RXDATA_swap(15 downto 8) when mode_sel = '1' else -- x4 mode + RXDATA_sr_done(63 downto 32); -- x1 mode +RXCHARISK_u <= RXCHARISK_swap(7) & RXCHARISK_swap(5) & RXCHARISK_swap(3) & RXCHARISK_swap(1) when mode_sel = '1' else -- x4 mode + RXCHARISK_sr_done(7 downto 4); -- x1 mode +RXCHARISvalid_u <= RXCHARISvalid_swap(7) & RXCHARISvalid_swap(5) & RXCHARISvalid_swap(3) & RXCHARISvalid_swap(1) when mode_sel = '1' else -- x4 mode + RXCHARISvalid_sr_done(7 downto 4); -- x1 mode +RXDATA_l <= RXDATA_swap(55 downto 48) & RXDATA_swap(39 downto 32) & RXDATA_swap(23 downto 16) & RXDATA_swap(7 downto 0) when mode_sel = '1' else -- x4 mode + RXDATA_sr_done(31 downto 0); -- x1 mode +RXCHARISK_l <= RXCHARISK_swap(6) & RXCHARISK_swap(4) & RXCHARISK_swap(2) & RXCHARISK_swap(0) when mode_sel = '1' else -- x4 mode + RXCHARISK_sr_done(3 downto 0); -- x1 mode +RXCHARISvalid_l <= RXCHARISvalid_swap(6) & RXCHARISvalid_swap(4) & RXCHARISvalid_swap(2) & RXCHARISvalid_swap(0) when mode_sel = '1' else -- x4 mode + RXCHARISvalid_sr_done(3 downto 0); -- x1 mode + +-- RXDATA_u <= RXDATA_swap(63 downto 56) & RXDATA_swap(47 downto 40) & RXDATA_swap(31 downto 24) & RXDATA_swap(15 downto 8); +-- RXCHARISK_u <= RXCHARISK_swap(7) & RXCHARISK_swap(5) & RXCHARISK_swap(3) & RXCHARISK_swap(1); +-- RXDATA_l <= RXDATA_swap(55 downto 48) & RXDATA_swap(39 downto 32) & RXDATA_swap(23 downto 16) & RXDATA_swap(7 downto 0); +-- RXCHARISK_l <= RXCHARISK_swap(6) & RXCHARISK_swap(4) & RXCHARISK_swap(2) & RXCHARISK_swap(0); +-- RXCHARISvalid_u <= RXCHARISvalid_swap(7) & RXCHARISvalid_swap(5) & RXCHARISvalid_swap(3) & RXCHARISvalid_swap(1); +-- RXCHARISvalid_l <= RXCHARISvalid_swap(6) & RXCHARISvalid_swap(4) & RXCHARISvalid_swap(2) & RXCHARISvalid_swap(0); + +upper_symbol_type <= SYMBOL_IDLE when RXCHARISK_u = "1111" and RXCHARISvalid_u = "1111" else + SYMBOL_CONTROL when RXCHARISK_u = "1000" and RXCHARISvalid_u = "1111" and (RXDATA_u(31 downto 24) = SC or RXDATA_u(31 downto 24) = PD) else + SYMBOL_DATA when RXCHARISK_u = "0000" and RXCHARISvalid_u = "1111" else + SYMBOL_ERROR; + +lower_symbol_type <= SYMBOL_IDLE when RXCHARISK_l = "1111" and RXCHARISvalid_l = "1111" else + SYMBOL_CONTROL when RXCHARISK_l = "1000" and RXCHARISvalid_l = "1111" and (RXDATA_l(31 downto 24) = SC or RXDATA_l(31 downto 24) = PD) else + SYMBOL_DATA when RXCHARISK_l = "0000" and RXCHARISvalid_l = "1111" else + SYMBOL_ERROR; + +-- +upper_symbol_not_idle <= '0' when upper_symbol_type = SYMBOL_IDLE else '1'; +lower_symbol_not_idle <= '0' when lower_symbol_type = SYMBOL_IDLE else '1'; +upper_symbol_not_error <= '0' when upper_symbol_type = SYMBOL_ERROR else '1'; +lower_symbol_not_error <= '0' when lower_symbol_type = SYMBOL_ERROR else '1'; + +upper_symbol_valid <= upper_symbol_not_idle and upper_symbol_not_error; +lower_symbol_valid <= lower_symbol_not_idle and lower_symbol_not_error; + + +end RTL; +--------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- To Do: +-- - +-- +-- Author(s): +-- - A. Demirezen, azdem@opencores.org +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- +-- File name: pcs_tx_controller.vhd +-- Rev: 0.0 +-- Description: This entity controls the TX stream +-- +-- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_unsigned.all; +use work.rio_common.all; + +entity pcs_tx_controller is + generic ( + TCQ : time := 100 ps + ); + port ( + rst_n : in std_logic; + rio_clk : in std_logic; -- ~150 MHz + UCLK_x2 : in std_logic; -- 312,5 MHz + UCLK : in std_logic; -- 156,25 MHz + UCLK_x2_DV2 : in std_logic; -- 312,5 MHz @ x4 mode / 78,125 @ x1 (fallback mode) + UCLK_or_DV4 : in std_logic; -- 156,25 MHz @ x4 mode / 39,0625 @ x1 (fallback mode) + -- + -- Interface to the RioSerial + outboundWrite_i : in std_logic; + outboundFull_o : out std_logic; + outboundSymbol_i : in std_logic_vector(33 downto 0); + -- outboundSymbolEmpty_i : in std_logic; + -- outboundSymbolRead_o : out std_logic; + -- outboundSymbol_i : in std_logic_vector(33 downto 0); + -- + -- Interface to the GTX transceivers + TXDATA_o : out std_logic_vector(63 downto 0); -- N = 4 + TXCHARISK_o : out std_logic_vector(7 downto 0); + -- + -- Interface to the other blocks + send_ccs_i : in std_logic; + ccs_timer_rst_o : out std_logic; + send_idle_o : out std_logic_vector(1 downto 0); + send_K_i : in std_logic_vector(1 downto 0); + send_A_i : in std_logic_vector(1 downto 0); + send_R_i : in std_logic_vector(1 downto 0); + -- + -- Interface to the port init + TXINHIBIT_02 : in std_logic; + TXINHIBIT_others : in std_logic; + port_initalized_i : in std_logic; + mode_sel_i : in std_logic; + mode_0_lane_sel_i : in std_logic + + ); +end pcs_tx_controller; + +architecture RTL of pcs_tx_controller is + +------------------------------------------------------------------------------- +COMPONENT pcs_tx_boudary_32b_in_64b_out + PORT ( + rst : IN STD_LOGIC; + wr_clk : IN STD_LOGIC; + rd_clk : IN STD_LOGIC; + din : IN STD_LOGIC_VECTOR(33 DOWNTO 0); + wr_en : IN STD_LOGIC; + rd_en : IN STD_LOGIC; + dout : OUT STD_LOGIC_VECTOR(67 DOWNTO 0); + full : OUT STD_LOGIC; + empty : OUT STD_LOGIC; + almost_empty : out STD_LOGIC; + almost_full : out STD_LOGIC; + valid : OUT STD_LOGIC + ); +END COMPONENT; +------------------------------------------------------------------------------- +-- COMPONENT pcs_tx_boudary_32b_v2 +-- PORT ( +-- rst : IN STD_LOGIC; +-- wr_clk : IN STD_LOGIC; +-- rd_clk : IN STD_LOGIC; +-- din : IN STD_LOGIC_VECTOR(33 DOWNTO 0); +-- wr_en : IN STD_LOGIC; +-- rd_en : IN STD_LOGIC; +-- dout : OUT STD_LOGIC_VECTOR(33 DOWNTO 0); +-- full : OUT STD_LOGIC; +-- empty : OUT STD_LOGIC; +-- almost_empty : OUT STD_LOGIC; +-- valid : OUT STD_LOGIC +-- ); +-- END COMPONENT; +------------------------------------------------------------------------------- +signal rst : std_logic:= '0'; +signal fragment_counter : std_logic_vector(9 downto 0) := (others => '0'); +signal outboundSymbolType : std_logic_vector(1 downto 0) := (others => '0'); +signal outboundSymbol : std_logic_vector(33 downto 0) := (others => '0'); +signal outboundSymbolRead : std_logic:= '0'; +signal non_idle : std_logic:= '0'; +signal decrement_frag_cntr : std_logic:= '0'; + +signal tx_fifo_full : std_logic:= '0'; +signal symbol_empty : std_logic:= '0'; +signal symbol_almost_empty : std_logic:= '0'; +signal symbol_read : std_logic:= '0'; +signal symbol_valid : std_logic:= '0'; +-- signal symbol : std_logic_vector(33 downto 0) := (others => '0'); +signal symbol : std_logic_vector(67 downto 0) := (others => '0'); +signal symbol_u : std_logic_vector(33 downto 0) := (others => '0'); +signal symbol_l : std_logic_vector(33 downto 0) := (others => '0'); +-- signal symbol_type : std_logic_vector(1 downto 0) := (others => '0'); +signal symbol_type : std_logic_vector(3 downto 0) := (others => '0'); +signal symbol_type_u : std_logic_vector(1 downto 0) := (others => '0'); +signal symbol_type_l : std_logic_vector(1 downto 0) := (others => '0'); + +signal TXDATA : std_logic_vector(63 downto 0); -- N = 4 +signal TXCHARISK : std_logic_vector(7 downto 0); +signal TXDATA_u : std_logic_vector(31 downto 0); +signal TXCHARISK_u : std_logic_vector(3 downto 0); +signal TXDATA_l : std_logic_vector(31 downto 0); +signal TXCHARISK_l : std_logic_vector(3 downto 0); + +signal TXDATA_u_idle : std_logic_vector(31 downto 0); +signal TXDATA_l_idle : std_logic_vector(31 downto 0); + +signal word_switch : std_logic:= '0'; +signal lane_switch : std_logic_vector(1 downto 0) := (others => '0'); +signal cycle_switch : std_logic_vector(1 downto 0) := (others => '0'); +signal read_switch : std_logic_vector(1 downto 0) := (others => '0'); + +signal send_idle_q : std_logic:= '0'; +signal send_idle_reg : std_logic_vector(1 downto 0) := (others => '0'); +signal send_idle : std_logic_vector(1 downto 0) := (others => '0'); +signal idle_char_type_0 : std_logic_vector(2 downto 0) := (others => '0'); +signal idle_char_type_1 : std_logic_vector(2 downto 0) := (others => '0'); + +signal send_ccs_cntr : std_logic_vector(1 downto 0) := (others => '0'); +signal send_K : std_logic_vector(1 downto 0) := (others => '0'); +signal send_A : std_logic_vector(1 downto 0) := (others => '0'); +signal send_R : std_logic_vector(1 downto 0) := (others => '0'); +signal send_ccs : std_logic:= '0'; +signal send_ccs_q : std_logic:= '0'; +signal do_not_interrupt : std_logic:= '0'; + +signal be_silent : std_logic:= '0'; +signal fifo_wr_selective : std_logic:= '0'; +signal fifo_wr_selective_q : std_logic:= '0'; +signal fifo_wr_always_even : std_logic:= '0'; +signal fifo_wr_odd_or_even : std_logic:= '0'; +signal fifo_wr_evenly : std_logic:= '0'; +signal outboundSymbolisData : std_logic:= '0'; +signal outboundSymbolisData_q : std_logic:= '0'; + +signal outboundSymbol_q : std_logic_vector(33 downto 0) := (others => '0'); +signal fifo_wr_evenly_q : std_logic:= '0'; +-- signal send_K_ccs : std_logic:= '0'; +-- signal send_R_ccs : std_logic:= '0'; +-- signal send_K_q : std_logic:= '0'; +-- signal send_A_q : std_logic:= '0'; +-- signal send_R_q : std_logic:= '0'; +---------------------------------------------------------------------------------- +begin +-- +rst <= not(rst_n); + +outboundSymbolType <= outboundSymbol_i(33 downto 32); +-- Filtering the ERROR symbol out +outboundSymbol <= outboundSymbol_i when (outboundSymbolType = SYMBOL_DATA or outboundSymbolType = SYMBOL_CONTROL) else + SYMBOL_IDLE & outboundSymbol_i(31 downto 0); + +fifo_wr_selective <= outboundWrite_i when (outboundSymbolType = SYMBOL_DATA or outboundSymbolType = SYMBOL_CONTROL) else '0'; + +fifo_wr_always_even <= fifo_wr_selective or (fifo_wr_selective_q and fifo_wr_odd_or_even); + +outboundSymbolisData <= '1' when outboundSymbolType = SYMBOL_DATA else '0'; + +fifo_wr_evenly <= fifo_wr_selective or (fifo_wr_selective_q and fifo_wr_odd_or_even and not(outboundSymbolisData_q)); + +-- Writing to the FIFO +process(rio_clk) + begin + if rising_edge(rio_clk) then + fifo_wr_selective_q <= fifo_wr_selective; + outboundSymbolisData_q <= outboundSymbolisData; + if fifo_wr_selective = '1' then + fifo_wr_odd_or_even <= not(fifo_wr_odd_or_even); + elsif fifo_wr_selective_q = '1' then + fifo_wr_odd_or_even <= fifo_wr_odd_or_even and outboundSymbolisData_q; -- '0'; + end if; + + outboundSymbol_q <= outboundSymbol; + fifo_wr_evenly_q <= fifo_wr_evenly; + end if; +end process; + +send_K <= send_K_i; +send_A <= send_A_i; +send_R <= send_R_i; + +-- idle_char_type <= send_K & send_A & send_R; +idle_char_type_0 <= send_K(0) & send_A(0) & send_R(0); +idle_char_type_1 <= send_K(1) & send_A(1) & send_R(1); + +be_silent <= '1' when TXINHIBIT_02 = '1' and TXINHIBIT_others = '1' else '0'; + +-- symbol_type <= symbol(33 downto 32); +symbol_type_u <= symbol_u(33 downto 32); +symbol_type_l <= symbol_l(33 downto 32); + +symbol_u <= symbol(67 downto 34); +symbol_l <= symbol(33 downto 0); + +send_idle(1) <= '1' when (send_ccs = '0') and + ((symbol_read = '1' and symbol_type_u = SYMBOL_IDLE) or + (symbol_read = '0') or + (port_initalized_i = '0')) + else + '0'; + +send_idle(0) <= '1' when (send_ccs = '0') and + ((symbol_read = '1' and symbol_type_l = SYMBOL_IDLE) or + (symbol_read = '0') or + (port_initalized_i = '0')) + else + '0'; + +send_idle_o <= send_idle; -- _reg; + +-- symbol_read <= not(symbol_empty) and not(send_ccs) and not(send_ccs_q); + +-- Pipelining +process(UCLK) -- _x2 + begin + if rising_edge(UCLK) then + send_ccs <= not(do_not_interrupt) and send_ccs_i; -- will be high only during real CCS transmission + -- send_idle_reg <= send_idle; + end if; +end process; + +-- Reading from the FIFO +process(UCLK_or_DV4) -- UCLK_x2_DV2 + begin + if rising_edge(UCLK_or_DV4) then + -- case symbol_read is + -- when '0' => + -- symbol_read <= not(symbol_empty) and not(send_ccs) and not(send_ccs_q); -- after TCQ; + -- when '1' => + -- symbol_read <= not(symbol_almost_empty); -- after TCQ; -- and not(send_ccs) and not(send_ccs_q); + -- when others => + -- symbol_read <= '0'; -- after TCQ; + -- end case; + + end if; +end process; + +tx_boundary_fifo : pcs_tx_boudary_32b_in_64b_out -- FWFT FIFO + PORT MAP ( + rst => rst, + + wr_clk => rio_clk, + wr_en => fifo_wr_evenly_q, --fifo_wr_always_even, --outboundWrite_i, + din => outboundSymbol_q, + full => open, -- outboundFull_o, + almost_full => outboundFull_o, + + rd_clk => UCLK_or_DV4, + rd_en => symbol_read, + dout => symbol, + empty => symbol_empty, + almost_empty => symbol_almost_empty, + valid => symbol_valid + ); + +-- FIFO read / TX output process +process(rst_n, UCLK) -- UCLK_x2 + begin + if rst_n = '0' then + + ccs_timer_rst_o <= '0'; + do_not_interrupt <= '0'; + TXDATA_u <= (others => '0'); + TXCHARISK_u <= (others => '0'); + TXDATA_l <= (others => '0'); + TXCHARISK_l <= (others => '0'); + cycle_switch <= (others => '0'); + read_switch <= (others => '0'); + symbol_read <= '0'; + + elsif rising_edge(UCLK) then + + if be_silent = '0' then -- Transmitters are NOT inhibitied + if send_ccs = '1' or send_ccs_q = '1' then -- Transmitting the clock compensation sequence (ccs) = |K|,|R|,|R|,|R| + symbol_read <= '0'; + if send_ccs_q = '0' then + TXDATA_u <= K_column; + TXCHARISK_u <= (others => '1'); + TXDATA_l <= R_column; + TXCHARISK_l <= (others => '1'); + ccs_timer_rst_o <= '1'; + else + TXDATA_u <= R_column; + TXCHARISK_u <= (others => '1'); + TXDATA_l <= R_column; + TXCHARISK_l <= (others => '1'); + end if; + else -- Transmitting the IDLE sequence or the CONTROL/DATA symbols + + read_switch <= read_switch + '1'; + if read_switch = "00" then + case symbol_read is + when '0' => + symbol_read <= not(symbol_empty); -- and not(send_ccs) and not(send_ccs_q); -- after TCQ; + do_not_interrupt <= not(symbol_empty); + when '1' => + symbol_read <= not(symbol_almost_empty); -- after TCQ; -- and not(send_ccs) and not(send_ccs_q); + do_not_interrupt <= not(symbol_almost_empty); + when others => + symbol_read <= '0'; -- after TCQ; + do_not_interrupt <= '0'; + end case; + end if; + + ccs_timer_rst_o <= '0'; + if symbol_read = '1' then -- two symbols have been read, at least one of them is non-idle, they should be forwarded in 1 or 4 cycles + case mode_sel_i is + when '1' => -- Lane stripping (x4 mode: rd_clk = UCLK) + case symbol_type_u is + when SYMBOL_DATA => + TXDATA_u <= symbol_u(31 downto 24) & symbol_u(23 downto 16) & symbol_u(15 downto 8) & symbol_u(7 downto 0); + TXCHARISK_u <= (others => '0'); + when SYMBOL_CONTROL => + TXDATA_u <= symbol_u(31 downto 24) & symbol_u(23 downto 16) & symbol_u(15 downto 8) & symbol_u(7 downto 0); + TXCHARISK_u <= "1000"; + when SYMBOL_IDLE => + TXDATA_u <= TXDATA_u_idle; + TXCHARISK_u <= (others => '1'); + when others => + -- dummy + TXDATA_u <= TXDATA_u_idle; + TXCHARISK_u <= (others => '1'); + end case; + case symbol_type_l is + when SYMBOL_DATA => + TXDATA_l <= symbol_l(31 downto 24) & symbol_l(23 downto 16) & symbol_l(15 downto 8) & symbol_l(7 downto 0); + TXCHARISK_l <= (others => '0'); + when SYMBOL_CONTROL => + TXDATA_l <= symbol_l(31 downto 24) & symbol_l(23 downto 16) & symbol_l(15 downto 8) & symbol_l(7 downto 0); + TXCHARISK_l <= "1000"; + when SYMBOL_IDLE => + TXDATA_l <= TXDATA_l_idle; + TXCHARISK_l <= (others => '1'); + when others => + -- dummy + TXDATA_l <= TXDATA_l_idle; + TXCHARISK_l <= (others => '1'); + end case; + when '0' => -- Slow motion read (x1 mode: rd_clk = UCLK_DV4) + cycle_switch <= cycle_switch + '1'; + -- Cycle | Symbol part to be sent + ---------|---------------------- + -- 00 | symbol_u(31 downto 16) + -- 01 | symbol_u(15 downto 0) + -- 10 | symbol_l(31 downto 16) + -- 11 | symbol_l(15 downto 0) + case cycle_switch(1) is + when '0' => + case cycle_switch(0) is + when '0' => -- 00 + if symbol_type_u /= SYMBOL_IDLE then + TXDATA_u <= symbol_u(31 downto 24) & symbol_u(31 downto 24) & symbol_u(31 downto 24) & symbol_u(31 downto 24); + if symbol_type_u = SYMBOL_DATA then + TXCHARISK_u <= (others => '0'); + else -- if symbol_type_u = SYMBOL_CONTROL then + TXCHARISK_u <= (others => '1'); + end if; + TXDATA_l <= symbol_u(23 downto 16) & symbol_u(23 downto 16) & symbol_u(23 downto 16) & symbol_u(23 downto 16); + TXCHARISK_l <= (others => '0'); + else -- if symbol_type_u = SYMBOL_IDLE then + TXDATA_u <= TXDATA_u_idle; + TXCHARISK_u <= (others => '1'); + TXDATA_l <= TXDATA_l_idle; + TXCHARISK_l <= (others => '1'); + end if; + when '1' => -- 01 + if symbol_type_u /= SYMBOL_IDLE then + TXDATA_u <= symbol_u(15 downto 8) & symbol_u(15 downto 8) & symbol_u(15 downto 8) & symbol_u(15 downto 8); + TXCHARISK_u <= (others => '0'); -- This is the second part: does not matter control or data + TXDATA_l <= symbol_u(7 downto 0) & symbol_u(7 downto 0) & symbol_u(7 downto 0) & symbol_u(7 downto 0); + TXCHARISK_l <= (others => '0'); + else -- if symbol_type_u = SYMBOL_IDLE then + TXDATA_u <= TXDATA_u_idle; + TXCHARISK_u <= (others => '1'); + TXDATA_l <= TXDATA_l_idle; + TXCHARISK_l <= (others => '1'); + end if; + when others => + -- dummy + end case; + when '1' => + case cycle_switch(0) is + when '0' => + if symbol_type_l /= SYMBOL_IDLE then + TXDATA_u <= symbol_l(31 downto 24) & symbol_l(31 downto 24) & symbol_l(31 downto 24) & symbol_l(31 downto 24); + if symbol_type_l = SYMBOL_DATA then + TXCHARISK_u <= (others => '0'); + else -- if symbol_type_l = SYMBOL_CONTROL then + TXCHARISK_u <= (others => '1'); + end if; + TXDATA_l <= symbol_l(23 downto 16) & symbol_l(23 downto 16) & symbol_l(23 downto 16) & symbol_l(23 downto 16); + TXCHARISK_l <= (others => '0'); + else -- if symbol_type_l = SYMBOL_IDLE then + TXDATA_u <= TXDATA_u_idle; + TXCHARISK_u <= (others => '1'); + TXDATA_l <= TXDATA_l_idle; + TXCHARISK_l <= (others => '1'); + end if; + when '1' => + if symbol_type_l /= SYMBOL_IDLE then + TXDATA_u <= symbol_l(15 downto 8) & symbol_l(15 downto 8) & symbol_l(15 downto 8) & symbol_l(15 downto 8); + TXCHARISK_u <= (others => '0'); -- This is the second part: does not matter control or data + TXDATA_l <= symbol_l(7 downto 0) & symbol_l(7 downto 0) & symbol_l(7 downto 0) & symbol_l(7 downto 0); + TXCHARISK_l <= (others => '0'); + else -- if symbol_type_l = SYMBOL_IDLE then + TXDATA_u <= TXDATA_u_idle; + TXCHARISK_u <= (others => '1'); + TXDATA_l <= TXDATA_l_idle; + TXCHARISK_l <= (others => '1'); + end if; + when others => + -- dummy + end case; + when others => + -- dummy + end case; + + when others => + -- dummy + end case; + ----------------------------------------------------------------------------- + else -- No Symbols are present at the FIFO output: Transmitting an idle sequence: |K| or |A| or |R| + TXDATA_u <= TXDATA_u_idle; + TXCHARISK_u <= (others => '1'); + TXDATA_l <= TXDATA_l_idle; + TXCHARISK_l <= (others => '1'); + end if; + end if; + else -- Transmitters are inhibitied + TXDATA_u <= x"BCBCBCBC" ; + TXCHARISK_u <= (others => '1'); + TXDATA_l <= x"FDFDFDFD" ; + TXCHARISK_l <= (others => '1'); + end if; + end if; +end process; + +-- Combinational idle drive process +process(idle_char_type_0, idle_char_type_1) + begin + case idle_char_type_1 is + when "100" => -- |K| (~%50) + TXDATA_u_idle <= K_column; + + when "010" => -- |A| (1/16 .. 1/32) + TXDATA_u_idle <= A_column; + + when "001" => -- |R| (~%50) + TXDATA_u_idle <= R_column; + + when others => + -- dummy + TXDATA_u_idle <= K_column; + end case; + case idle_char_type_0 is + when "100" => -- |K| (~%50) + TXDATA_l_idle <= K_column; + + when "010" => -- |A| (1/16 .. 1/32) + TXDATA_l_idle <= A_column; + + when "001" => -- |R| (~%50) + TXDATA_l_idle <= R_column; + + when others => + -- dummy + TXDATA_l_idle <= R_column; + end case; +end process; + +-- TXDATA buffering by UCLK +process(UCLK) + begin + if rising_edge(UCLK) then + ------------------ + -- MUST BE SWAPPED + TXDATA_o <= TXDATA_u( 7 downto 0) & TXDATA_l( 7 downto 0) & TXDATA_u(15 downto 8) & TXDATA_l(15 downto 8) + & TXDATA_u(23 downto 16) & TXDATA_l(23 downto 16) & TXDATA_u(31 downto 24) & TXDATA_l(31 downto 24); + TXCHARISK_o <= TXCHARISK_u(0) & TXCHARISK_l(0) & TXCHARISK_u(1) & TXCHARISK_l(1) & TXCHARISK_u(2) & TXCHARISK_l(2) & TXCHARISK_u(3) & TXCHARISK_l(3); + ------------------ + end if; +end process; + +-- Delaying send_ccs +process(UCLK) + begin + if rising_edge(UCLK) then + if be_silent = '0' then + send_ccs_q <= send_ccs; --- + else + send_ccs_q <= '0'; + end if; + end if; +end process; + +end RTL; +---------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- To Do: +-- - +-- +-- Author(s): +-- - A. Demirezen, azdem@opencores.org +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- +-- File name: port_init_fsms.vhd +-- Rev: 0.0 +-- Description: This entity does the 1x/Nx port init according to the +-- RIO Sepec. Part-6, subchapter 4.2 +-- +------------------------------------------------------------------------------ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_unsigned.all; +use work.rio_common.all; +--use work.rio_common_sim.all; + +entity port_init_fsms is + generic ( + TCQ : time := 100 ps + ); + port ( + rst_n : in std_logic; + UCLK_x2 : in std_logic; + UCLK : in std_logic; + UCLK_DV4 : in std_logic; + UCLK_DV_1024 : in std_logic; + + force_reinit : in std_logic:='0'; -- force retraining + mode_sel : out std_logic; -- 0: x1 fallback mode / 1: xN Mode + mode_0_lane_sel : out std_logic; -- If mode_sel = 0 then 0: Lane 0 is active(R), 1: Lane 2 is active else don't care + port_initalized : out std_logic; -- 1: Port initialization is successfully complete + lane_sync : out std_logic_vector(N-1 downto 0); -- Lane is synchoronised + RXCHARISvalid : out std_logic_vector(N*2-1 downto 0); + + -- GTXRESET : out std_logic; + TXINHIBIT_02 : out std_logic; + TXINHIBIT_others : out std_logic; + ENCHANSYNC : out std_logic; + -- TXDATA : out std_logic_vector(N*16-1 downto 0); + -- TXCHARISK : out std_logic_vector(N*2-1 downto 0); + PLLLKDET : in std_logic; + RXDATA : in std_logic_vector(N*16-1 downto 0); + RXCHARISK : in std_logic_vector(N*2-1 downto 0); + RXCHARISCOMMA : in std_logic_vector(N*2-1 downto 0); + RXBYTEISALIGNED : in std_logic_vector(N-1 downto 0); + RXBYTEREALIGN : in std_logic_vector(N-1 downto 0); + RXELECIDLE : in std_logic_vector(N-1 downto 0); + RXDISPERR : in std_logic_vector(N*2-1 downto 0); + RXNOTINTABLE : in std_logic_vector(N*2-1 downto 0); + RXBUFERR : in std_logic; + RXBUFRST : out std_logic; + CHBONDDONE : in std_logic_vector(N-1 downto 0) + ); +end port_init_fsms; + +architecture rtl of port_init_fsms is +------------------------------------------------------------------------------------------------------------------------------------------- +-- Lane_Synchronization State Machine +type lane_sync_states is (NO_SYNC, NO_SYNC_1, NO_SYNC_2, NO_SYNC_2a, NO_SYNC_2b, NO_SYNC_3, SYNC, SYNCa, SYNCb, SYNC_1, SYNC_2, SYNC_2a, SYNC_2b, SYNC_3, SYNC_4); +type lane_sync_states_array is array (N-1 downto 0) of lane_sync_states; + +signal lane_sync_state_n : lane_sync_states_array := (others => NO_SYNC); +signal lane_sync_n : std_logic_vector(N-1 downto 0) := (others => '0'); +signal Kcounter_n : Kcounter_array_type := (others => (others => '0')); +signal Vcounter_n : Vcounter_array_type := (others => (others => '0')); +signal Icounter_n : Icounter_array_type := (others => (others => '0')); +signal code_group_valid : std_logic_vector(N*2-1 downto 0) := (others => '0'); +------------------------------------------------------------------------------------------------------------------------------------------- +-- Lane_Alignment State Machine +type lane_alignment_states is (NOT_ALIGNED, NOT_ALIGNED_1, NOT_ALIGNED_2, ALIGNED, ALIGNED_1, ALIGNED_2, ALIGNED_3); + +signal lane_alignment_state : lane_alignment_states := NOT_ALIGNED; +signal N_lanes_aligned : std_logic := '0'; +signal Acounter : std_logic_vector(2 downto 0) := (others => '0'); +signal Mcounter : Mcounter_type := (others => '0'); +signal lane_alignment_reset : std_logic := '0'; +signal N_lane_sync : std_logic := '0'; +constant N_lanes_all_high : std_logic_vector(N-1 downto 0) := (others => '1'); +constant N_lanes_all_low : std_logic_vector(N-1 downto 0) := (others => '0'); + +signal A_column_valid : std_logic := '0'; +signal align_error : std_logic := '0'; +signal A_column_valid_upper : std_logic := '0'; +signal align_error_upper : std_logic := '0'; +signal A_column_valid_lower : std_logic := '0'; +signal align_error_lower : std_logic := '0'; + +signal RXCHARIS_A_upper : std_logic_vector(N-1 downto 0) := (others => '0'); +signal RXCHARIS_A_lower : std_logic_vector(N-1 downto 0) := (others => '0'); +------------------------------------------------------------------------------------------------------------------------------------------- +-- begin --dummy +-- 1x/Nx Mode Init State Machine +type mode_init_states is (SILENT, SEEK, DISCOVERY, x1_RECOVERY, Nx_MODE, x1_MODE_LANE0, x1_MODE_LANE2); + +signal mode_init_state : mode_init_states := SILENT; +signal lanes02_drvr_oe : std_logic := '0'; +signal N_lanes_drvr_oe : std_logic := '0'; +signal Nx_mode_active : std_logic := '0'; +signal receive_lane2 : std_logic := '0'; +signal force_reinit_reg : std_logic := '0'; +signal force_reinit_clear : std_logic := '0'; + +signal silence_timer_en : std_logic := '0'; +signal silence_timer_done : std_logic := '0'; +signal silence_timer : std_logic_vector(4 downto 0) := (others => '0'); + +signal disc_tmr_en : std_logic := '0'; +signal disc_tmr_done : std_logic := '0'; +signal disc_tmr : std_logic_vector(15 downto 0) := (others => '0'); + +signal port_initalized_reg : std_logic := '0'; + +signal idle_selected : std_logic := '1'; -- Only IDLE1 is to be used +signal Nx_mode_enabled : std_logic := '1'; -- Nx mode is to be always enabled +signal force_1x_mode : std_logic := '0'; -- don't force 1x mode +signal force_laneR : std_logic := '0'; -- don't care, when force_1x_mode = 0 + +signal lane_ready_n : std_logic_vector(N-1 downto 0) := (others => '0'); +signal rcvr_trained_n : std_logic_vector(N-1 downto 0) := (others => '0'); +signal N_lanes_ready : std_logic := '0'; + +signal rxbufrst_cntr : std_logic_vector(2 downto 0) := (others => '0'); +signal rxbuferr_reg : std_logic := '0'; +------------------------------------------------------------------------------------------------------------------------------------------- +begin + +lane_sync <= lane_sync_n; +---------------------------------------------------------------- +-- Figure 4-14. Lane_Synchronization State Machine for N Lanes +GEN_LANE_SYNC_FSM: for i in 0 to N-1 generate + +code_group_valid(i*2) <= not(RXNOTINTABLE(i*2) ) and not(RXDISPERR(i*2) ); +code_group_valid(i*2+1) <= not(RXNOTINTABLE(i*2+1)) and not(RXDISPERR(i*2+1)); + +RXCHARISvalid(i*2) <= code_group_valid(i*2) ; +RXCHARISvalid(i*2+1) <= code_group_valid(i*2+1); + +process(rst_n, UCLK) -- (UCLK_x2) -- + begin + + if rst_n = '0' then + + lane_sync_state_n(i) <= NO_SYNC; + lane_sync_n(i) <= '0'; + Kcounter_n(i) <= (others => '0'); + Vcounter_n(i) <= (others => '0'); + + elsif rising_edge(UCLK) then + + case lane_sync_state_n(i) is + when NO_SYNC => + -- change(signal_detect[n]) + if RXELECIDLE(i) = '1' then + lane_sync_n(i) <= '0'; + Kcounter_n(i) <= (others => '0'); + Vcounter_n(i) <= (others => '0'); + -- signal_detect[n] & /COMMA/ [ KK-- ] : /K/ is being detected at the upper half + elsif (code_group_valid(i*2+1) = '1' and RXCHARISCOMMA(i*2+1) = '1') then + -- signal_detect[n] & /COMMA/ [ --KK ] : /K/ is being detected also at the lower half + if (code_group_valid(i*2) = '1' and RXCHARISCOMMA(i*2) = '1') then + lane_sync_state_n(i) <= NO_SYNC_2; + Kcounter_n(i) <= Kcounter_n(i) + "10"; + Vcounter_n(i) <= Vcounter_n(i) + "10"; + -- signal_detect[n] [ --VV ] : At the lower half: no comma, but valid + elsif (code_group_valid(i*2) = '1') then + lane_sync_state_n(i) <= NO_SYNC_2; + Kcounter_n(i) <= Kcounter_n(i) + '1'; + Vcounter_n(i) <= Vcounter_n(i) + "10"; + -- do nothing + else + lane_sync_n(i) <= '0'; + Kcounter_n(i) <= (others => '0'); + Vcounter_n(i) <= (others => '0'); + end if; + ---------------------------------------------------------------------------------------------- + -- signal_detect[n] & /COMMA/ [ --KK ] : /K/ is being detected only at the lower half + elsif (code_group_valid(i*2) = '1' and RXCHARISCOMMA(i*2) = '1') then + lane_sync_state_n(i) <= NO_SYNC_2; + Kcounter_n(i) <= Kcounter_n(i) + '1'; + Vcounter_n(i) <= Vcounter_n(i) + '1'; + ---------------------------------------------------------------------------------------------- + -- !signal_detect[n] | !/COMMA/ + else + lane_sync_n(i) <= '0'; + Kcounter_n(i) <= (others => '0'); + Vcounter_n(i) <= (others => '0'); + end if; + -- -- change(signal_detect[n]) + -- if RXELECIDLE(i) = '1' then + -- lane_sync_n(i) <= '0'; + -- Kcounter_n(i) <= (others => '0'); + -- Vcounter_n(i) <= (others => '0'); + -- -- signal_detect[n] & /COMMA/ [ KK-- ] : /K/ is being detected at the upper half + -- elsif (code_group_valid(i*2+1) = '1' and RXCHARISCOMMA(i*2+1) = '1') then + -- lane_sync_state_n(i) <= NO_SYNC_2a; + -- Kcounter_n(i) <= Kcounter_n(i) + '1'; + -- Vcounter_n(i) <= Vcounter_n(i) + '1'; + -- -- signal_detect[n] & /COMMA/ [ --KK ] : /K/ is being detected at the lower half + -- elsif (code_group_valid(i*2) = '1' and RXCHARISCOMMA(i*2) = '1') then + -- lane_sync_state_n(i) <= NO_SYNC_2b; + -- Kcounter_n(i) <= Kcounter_n(i) + '1'; + -- Vcounter_n(i) <= Vcounter_n(i) + '1'; + -- -- !signal_detect[n] | !/COMMA/ + -- else + -- lane_sync_n(i) <= '0'; + -- Kcounter_n(i) <= (others => '0'); + -- Vcounter_n(i) <= (others => '0'); + -- end if; + + -- when NO_SYNC_1 => + + when NO_SYNC_2 => + -- [ IIXX or XXII ] -- One of both /INVALID/ + if (code_group_valid(i*2) = '0' or code_group_valid(i*2+1) = '0') then + lane_sync_state_n(i) <= NO_SYNC; + lane_sync_n(i) <= '0'; + Kcounter_n(i) <= (others => '0'); + Vcounter_n(i) <= (others => '0'); + -- [ KKKK ] -- Both /COMMA/ + elsif (RXCHARISCOMMA(i*2) = '1' and RXCHARISCOMMA(i*2+1) = '1') then + -- (Kcounter[n] > 126) & (Vcounter[n] > Vmin-1) + if Kcounter_n(i) >= Kmin and Vcounter_n(i) >= Vmin then + lane_sync_state_n(i) <= SYNC; + -- (Kcounter[n] < 127) | (Vcounter[n] < Vmin) + else + Kcounter_n(i) <= Kcounter_n(i) + "10"; + Vcounter_n(i) <= Vcounter_n(i) + "10"; + end if; + -- [ KKVV or VVKK ] -- One of both /COMMA/ + elsif (RXCHARISCOMMA(i*2) = '1' or RXCHARISCOMMA(i*2+1) = '1') then + -- (Kcounter[n] > 126) & (Vcounter[n] > Vmin-1) + if Kcounter_n(i) >= Kmin and Vcounter_n(i) >= Vmin then + lane_sync_state_n(i) <= SYNC; + -- (Kcounter[n] < 127) | (Vcounter[n] < Vmin) + else + Kcounter_n(i) <= Kcounter_n(i) + '1' ; + Vcounter_n(i) <= Vcounter_n(i) + "10"; + end if; + + -- [ VVVV ] -- None of both /COMMA/, but both /VALID/ + else -- if RXCHARISCOMMA(i*2) = '0') and RXCHARISCOMMA(i*2+1) = '0') then + -- (Kcounter[n] > 126) & (Vcounter[n] > Vmin-1) + if Kcounter_n(i) >= Kmin and Vcounter_n(i) >= Vmin then + lane_sync_state_n(i) <= SYNC; + -- (Kcounter[n] < 127) | (Vcounter[n] < Vmin) + else + Vcounter_n(i) <= Vcounter_n(i) + "10"; + end if; + end if; + + -- when NO_SYNC_2a => + -- -- !(/COMMA/|/INVALID/) + -- if (code_group_valid(i*2) = '1' and not(RXCHARISCOMMA(i*2) = '1')) then --RXCHARISK(i*2) = '1' and RXDATA(i*16+7 downto i*16) = x"BC")) then + -- lane_sync_state_n(i) <= NO_SYNC_2b; + -- Vcounter_n(i) <= Vcounter_n(i) + '1'; + -- -- /COMMA/ + -- elsif (code_group_valid(i*2) = '1' and RXCHARISCOMMA(i*2) = '1') then --RXCHARISK(i*2) = '1' and RXDATA(i*16+7 downto i*16) = x"BC") then + -- -- (Kcounter[n] > 126) & (Vcounter[n] > Vmin-1) + -- if Kcounter_n(i) >= Kmin and Vcounter_n(i) >= Vmin then + -- lane_sync_state_n(i) <= SYNCb; + -- -- (Kcounter[n] < 127) | (Vcounter[n] < Vmin) + -- else + -- lane_sync_state_n(i) <= NO_SYNC_2b; + -- Kcounter_n(i) <= Kcounter_n(i) + '1'; + -- Vcounter_n(i) <= Vcounter_n(i) + '1'; + -- end if; + -- -- /INVALID/ + -- elsif (code_group_valid(i*2) = '0') then + -- lane_sync_state_n(i) <= NO_SYNC; + -- lane_sync_n(i) <= '0'; + -- Kcounter_n(i) <= (others => '0'); + -- Vcounter_n(i) <= (others => '0'); + -- end if; + -- + -- when NO_SYNC_2b => + -- -- !(/COMMA/|/INVALID/) + -- if (code_group_valid(i*2+1) = '1' and not(RXCHARISCOMMA(i*2+1) = '1')) then --RXCHARISK(i*2+1) = '1' and RXDATA(i*16+15 downto i*16+8) = x"BC")) then + -- lane_sync_state_n(i) <= NO_SYNC_2a; + -- Vcounter_n(i) <= Vcounter_n(i) + '1'; + -- -- /COMMA/ + -- elsif (code_group_valid(i*2+1) = '1' and RXCHARISCOMMA(i*2+1) = '1') then --RXCHARISK(i*2+1) = '1' and RXDATA(i*16+15 downto i*16+8) = x"BC") then + -- -- (Kcounter[n] > 126) & (Vcounter[n] > Vmin-1) + -- if Kcounter_n(i) >= Kmin and Vcounter_n(i) >= Vmin then + -- lane_sync_state_n(i) <= SYNCa; + -- -- (Kcounter[n] < 127) | (Vcounter[n] < Vmin) + -- else + -- lane_sync_state_n(i) <= NO_SYNC_2a; + -- Kcounter_n(i) <= Kcounter_n(i) + '1'; + -- Vcounter_n(i) <= Vcounter_n(i) + '1'; + -- end if; + -- -- /INVALID/ + -- elsif (code_group_valid(i*2+1) = '0') then + -- lane_sync_state_n(i) <= NO_SYNC; + -- lane_sync_n(i) <= '0'; + -- Kcounter_n(i) <= (others => '0'); + -- Vcounter_n(i) <= (others => '0'); + -- end if; + + -- when NO_SYNC_3 => + + when SYNC => + -- Both /VALID/ + if (code_group_valid(i*2) = '1' and code_group_valid(i*2+1) = '1') then + lane_sync_n(i) <= '1'; + Icounter_n(i) <= (others => '0'); + -- One of both /INVALID/ + elsif (code_group_valid(i*2) = '1' or code_group_valid(i*2+1) = '1') then + Icounter_n(i) <= Icounter_n(i) + '1'; + lane_sync_state_n(i) <= SYNC_2; + -- Both /INVALID/ + else + Icounter_n(i) <= Icounter_n(i) + "10"; + lane_sync_state_n(i) <= SYNC_2; + end if; + -- + -- when SYNCa => + -- -- /INVALID/ + -- if (code_group_valid(i*2) = '0') then + -- Icounter_n(i) <= Icounter_n(i) + '1'; + -- lane_sync_state_n(i) <= SYNC_2b; + -- -- /VALID/ + -- else + -- lane_sync_state_n(i) <= SYNCb; + -- lane_sync_n(i) <= '1'; + -- Icounter_n(i) <= (others => '0'); + -- end if; + -- + -- when SYNCb => + -- -- /INVALID/ + -- if (code_group_valid(i*2+1) = '0') then + -- Icounter_n(i) <= Icounter_n(i) + '1'; + -- lane_sync_state_n(i) <= SYNC_2a; + -- -- /VALID/ + -- else + -- lane_sync_state_n(i) <= SYNCa; + -- lane_sync_n(i) <= '1'; + -- Icounter_n(i) <= (others => '0'); + -- end if; + + -- when SYNC_1 => + + when SYNC_2 => + -- Both /VALID/ + if (code_group_valid(i*2) = '1' and code_group_valid(i*2+1) = '1') then + Vcounter_n(i) <= Vcounter_n(i) + "10"; + -- (Vcounter[n] < 255) + if Vcounter_n(i) < x"FF" then + -- do nothing + lane_sync_state_n(i) <= SYNC_2; + -- (Vcounter[n] = 255) + else + Icounter_n(i) <= Icounter_n(i) - '1'; + Vcounter_n(i) <= (others => '0'); + -- (Icounter[n] > 0) + if Icounter_n(i) > Ione then + -- do nothing + lane_sync_state_n(i) <= SYNC_2; + -- (Icounter[n] = 0) + else + lane_sync_state_n(i) <= SYNC; + end if; + end if; + -- One of both /INVALID/ + elsif (code_group_valid(i*2) = '1' or code_group_valid(i*2+1) = '1') then + Icounter_n(i) <= Icounter_n(i) + '1'; + Vcounter_n(i) <= (others => '0'); + -- (Icounter[n] = Imax) + if Icounter_n(i) = Imax then + lane_sync_state_n(i) <= NO_SYNC; + lane_sync_n(i) <= '0'; + Kcounter_n(i) <= (others => '0'); + -- (Icounter[n] < Imax) + else + -- do nothing + lane_sync_state_n(i) <= SYNC_2; + end if; + -- Both /INVALID/ + else + Icounter_n(i) <= Icounter_n(i) + "10"; + Vcounter_n(i) <= (others => '0'); + -- (Icounter[n] = Imax) + if Icounter_n(i) = Imax then + lane_sync_state_n(i) <= NO_SYNC; + lane_sync_n(i) <= '0'; + Kcounter_n(i) <= (others => '0'); + -- (Icounter[n] < Imax) + else + -- do nothing + lane_sync_state_n(i) <= SYNC_2; + end if; + end if; + ---------------------------------------------- + + -- when SYNC_2a => + -- -- /INVALID/ + -- if (code_group_valid(i*2+1) = '0') then + -- Icounter_n(i) <= Icounter_n(i) + '1'; + -- Vcounter_n(i) <= (others => '0'); + -- -- (Icounter[n] = Imax) + -- if Icounter_n(i) = Imax then + -- lane_sync_state_n(i) <= NO_SYNC; + -- lane_sync_n(i) <= '0'; + -- Kcounter_n(i) <= (others => '0'); + -- -- (Icounter[n] < Imax) + -- else + -- lane_sync_state_n(i) <= SYNC_2b; + -- end if; + -- -- /VALID/ + -- else + -- Vcounter_n(i) <= Vcounter_n(i) + '1'; + -- -- (Vcounter[n] < 255) + -- if Vcounter_n(i) < x"FF" then + -- lane_sync_state_n(i) <= SYNC_2b; + -- -- (Vcounter[n] = 255) + -- else + -- Icounter_n(i) <= Icounter_n(i) - '1'; + -- Vcounter_n(i) <= (others => '0'); + -- -- (Icounter[n] > 0) + -- if Icounter_n(i) > Izero then + -- lane_sync_state_n(i) <= SYNC_2b; + -- -- (Icounter[n] = 0) + -- else + -- lane_sync_state_n(i) <= SYNCb; + -- end if; + -- end if; + -- end if; + -- + -- when SYNC_2b => + -- -- /INVALID/ + -- if (code_group_valid(i*2+1) = '0') then + -- Icounter_n(i) <= Icounter_n(i) + '1'; + -- Vcounter_n(i) <= (others => '0'); + -- -- (Icounter[n] = Imax) + -- if Icounter_n(i) = Imax then + -- lane_sync_state_n(i) <= NO_SYNC; + -- lane_sync_n(i) <= '0'; + -- Kcounter_n(i) <= (others => '0'); + -- -- (Icounter[n] < Imax) + -- else + -- lane_sync_state_n(i) <= SYNC_2a; + -- end if; + -- -- /VALID/ + -- else + -- Vcounter_n(i) <= Vcounter_n(i) + '1'; + -- -- (Vcounter[n] < 255) + -- if Vcounter_n(i) < x"FF" then + -- lane_sync_state_n(i) <= SYNC_2a; + -- -- (Vcounter[n] = 255) + -- else + -- Icounter_n(i) <= Icounter_n(i) - '1'; + -- Vcounter_n(i) <= (others => '0'); + -- -- (Icounter[n] > 0) + -- if Icounter_n(i) > Izero then + -- lane_sync_state_n(i) <= SYNC_2a; + -- -- (Icounter[n] = 0) + -- else + -- lane_sync_state_n(i) <= SYNCa; + -- end if; + -- end if; + -- end if; + + -- when SYNC_3 => + + -- when SYNC_4 => + + when others => + lane_sync_state_n(i) <= NO_SYNC; + lane_sync_n(i) <= '0'; + Kcounter_n(i) <= (others => '0'); + Vcounter_n(i) <= (others => '0'); + + end case; + end if; +end process; + +end generate GEN_LANE_SYNC_FSM; +---------------------------------------------------------------- +-- Figure 4-15. Lane_Alignment State Machine (for N lanes) + +N_lane_sync <= '1' when lane_sync_n = N_lanes_all_high else '0'; +lane_alignment_reset <= N_lane_sync and rst_n; +A_column_valid_upper <= '1' when (RXCHARIS_A_upper = N_lanes_all_high) else '0'; +A_column_valid_lower <= '1' when (RXCHARIS_A_lower = N_lanes_all_high) else '0'; +A_column_valid <= A_column_valid_upper or A_column_valid_lower; +align_error_upper <= '1' when (RXCHARIS_A_upper /= N_lanes_all_low) and (RXCHARIS_A_upper /= N_lanes_all_high) else '0'; +align_error_lower <= '1' when (RXCHARIS_A_lower /= N_lanes_all_low) and (RXCHARIS_A_lower /= N_lanes_all_high) else '0'; +align_error <= align_error_upper or align_error_lower; +GEN_CHAR_A_CHECKER: for i in 0 to N-1 generate +RXCHARIS_A_upper(i) <= '1' when (code_group_valid(i*2+1) = '1') and (RXCHARISK(i*2+1) = '1') and (RXDATA(i*16+15 downto i*16+8) = A_align) else '0'; +RXCHARIS_A_lower(i) <= '1' when (code_group_valid(i*2) = '1' ) and (RXCHARISK(i*2) = '1' ) and (RXDATA(i*16+7 downto i*16 ) = A_align) else '0'; +end generate GEN_CHAR_A_CHECKER; + +process(lane_alignment_reset, UCLK) + begin + + if lane_alignment_reset = '0' then + + lane_alignment_state <= NOT_ALIGNED; + N_lanes_aligned <= '0'; + Acounter <= (others => '0'); + -- Mcounter <= (others => '0'); + + elsif rising_edge(UCLK) then + + -- if lane_alignment_reset = '1' then + + case lane_alignment_state is + when NOT_ALIGNED => + -- N_lane_sync & ||A|| + if N_lane_sync = '1' and A_column_valid = '1' then + Acounter <= Acounter + '1'; + lane_alignment_state <= NOT_ALIGNED_2; + end if; + + -- when NOT_ALIGNED_1 => + + when NOT_ALIGNED_2 => + -- align_error + if align_error = '1' then + lane_alignment_state <= NOT_ALIGNED; + N_lanes_aligned <= '0'; + Acounter <= (others => '0'); + -- ||A|| + elsif A_column_valid = '1' then + Acounter <= Acounter + '1'; + -- Acounter = 4 + if Acounter = "100" then + lane_alignment_state <= ALIGNED; + -- Acounter < 4 + else + lane_alignment_state <= NOT_ALIGNED_2; + end if; + -- !align_error & !||A|| + else + -- Do nothing: Wait for the next column + end if; + + when ALIGNED => + N_lanes_aligned <= '1'; + Mcounter <= (others => '0'); + -- align_error + if align_error = '1' then + Acounter <= (others => '0'); + Mcounter <= Mcounter + '1'; + lane_alignment_state <= ALIGNED_2; + -- !(align_error) + else + -- Do nothing extra: Wait for the next column + end if; + + -- when ALIGNED_1 => + + when ALIGNED_2 => + -- align_error + if align_error = '1' then + Acounter <= (others => '0'); + Mcounter <= Mcounter + '1'; + -- Mcounter = Mmax + if Mcounter = Mmax then + lane_alignment_state <= NOT_ALIGNED; + N_lanes_aligned <= '0'; + -- Mcounter < Mmax + else + -- Do nothing extra: Wait for the next column + end if; + -- ||A|| + elsif A_column_valid = '1' then + Acounter <= Acounter + '1'; + -- Acounter = 4 + if Acounter = "100" then + lane_alignment_state <= ALIGNED; + -- Acounter < 4 + else + -- Do nothing extra: Wait for the next column + end if; + -- !align_error & !||A|| + else + -- Do nothing: Wait for the next column + end if; + + -- when ALIGNED_3 => + + when others => + lane_alignment_state <= NOT_ALIGNED; + N_lanes_aligned <= '0'; + Acounter <= (others => '0'); + Mcounter <= (others => '0'); + + end case; + -- else + -- lane_alignment_state <= NOT_ALIGNED; + -- N_lanes_aligned <= '0'; + -- Acounter <= (others => '0'); + -- end if; + end if; +end process; + +-- Figure 4-18. 1x/Nx_Initialization State Machine for N = 4 +TXINHIBIT_02 <= not(lanes02_drvr_oe); +TXINHIBIT_others <= not(N_lanes_drvr_oe); +rcvr_trained_n <= CHBONDDONE; -- TBD +lane_ready_n <= lane_sync_n and rcvr_trained_n; +-- lane_ready_n <= lane_sync_n; -- and rcvr_trained_n; +N_lanes_ready <= '1' when N_lanes_aligned = '1' and lane_ready_n = N_lanes_all_high else '0'; + +-- process(UCLK) +-- begin +-- if rising_edge(UCLK) then +-- mode_sel <= Nx_mode_active; +-- mode_0_lane_sel <= receive_lane2; +-- port_initalized <= port_initalized_reg; +-- end if; +-- end process; +mode_sel <= Nx_mode_active; +mode_0_lane_sel <= receive_lane2; +port_initalized <= port_initalized_reg; + +process(rst_n, UCLK) + begin + if rst_n = '0' then + + mode_init_state <= SILENT; + disc_tmr_en <= '0'; + lanes02_drvr_oe <= '0'; + N_lanes_drvr_oe <= '0'; + port_initalized_reg <= '0'; + Nx_mode_active <= '0'; + receive_lane2 <= '0'; + force_reinit_clear <= '0'; + silence_timer_en <= '0'; + idle_selected <= '1'; + + elsif rising_edge(UCLK) then + case mode_init_state is + + when SILENT => + disc_tmr_en <= '0'; + lanes02_drvr_oe <= '0'; + N_lanes_drvr_oe <= '0'; + port_initalized_reg <= '0'; + Nx_mode_active <= '0'; + receive_lane2 <= '0'; + force_reinit_clear <= '1'; -- = force_reinit <= '0'; + silence_timer_en <= '1'; + -- force_reinit + if force_reinit_reg = '1' then + mode_init_state <= SILENT; + -- silence_timer_done + elsif silence_timer_done = '1' then + mode_init_state <= SEEK; + end if; + + when SEEK => + lanes02_drvr_oe <= '1'; + silence_timer_en <= '0'; + -- (lane_sync_0 | lane_sync_2) & idle_selected + if (lane_sync_n(0) = '1' or lane_sync_n(2) = '1') and idle_selected = '1' then + mode_init_state <= DISCOVERY; + end if; + + when DISCOVERY => + port_initalized_reg <= '0'; + Nx_mode_active <= '0'; + N_lanes_drvr_oe <= Nx_mode_enabled; + disc_tmr_en <= '1'; + -- Nx_mode_enabled & N_lanes_ready + if Nx_mode_enabled = '1' and N_lanes_ready = '1' then + + mode_init_state <= Nx_MODE; + + -- lane_ready[0] & (force_1x_mode & (!force_laneR | force_laneR & disc_tmr_done & !lane_ready[2]) + -- | !force_1x_mode & disc_tmr_done & !N_lanes_ready) + elsif lane_ready_n(0) = '1' and ((force_1x_mode = '1' and (force_laneR = '0' or (force_laneR = '1' and disc_tmr_done = '1' and lane_ready_n(2) = '0'))) + or (force_1x_mode = '0' and disc_tmr_done = '1' and N_lanes_ready = '0')) then + + mode_init_state <= x1_MODE_LANE0; + + -- lane_ready[2] & (force_1x_mode & force_laneR | disc_tmr_done & !lane_ready[0] + -- & (force_1x_mode & !force_laneR | !force_1x_mode & !N_lanes_ready)) + elsif lane_ready_n(2) = '1' and ((force_1x_mode = '1' and force_laneR = '1') or + (disc_tmr_done = '1' and lane_ready_n(0) = '0' and + ((force_1x_mode = '1' and force_laneR = '0') or (force_1x_mode = '0' and N_lanes_ready = '0')))) then + + mode_init_state <= x1_MODE_LANE2; + + ---- -- !lane_sync[0] & !lane_sync[2] | disc_tmr_done & !lane_ready[0] & !lane_ready[2] + ---- elsif (lane_sync_n(0) = '0' and lane_sync_n(2) = '0') or (disc_tmr_done = '1' and lane_ready_n(0) = '0' and lane_ready_n(2) = '0') then + -- disc_tmr_done & !lane_ready[0] & !lane_ready[2] + elsif (disc_tmr_done = '1' and lane_ready_n(0) = '0' and lane_ready_n(2) = '0') then + + mode_init_state <= SILENT; + + end if; + + when Nx_MODE => + disc_tmr_en <= '0'; + port_initalized_reg <= '1'; + Nx_mode_active <= '1'; + -- !N_lanes_ready & (lane_sync[0] | lane_sync[2]) + if N_lanes_ready = '0' and (lane_sync_n(0) = '1' or lane_sync_n(2) = '1') then + mode_init_state <= DISCOVERY; + -- !N_lanes_ready & !lane_sync[0] & !lane_sync[2] + elsif N_lanes_ready = '0' and lane_sync_n(0) = '0' and lane_sync_n(2) = '0' then + mode_init_state <= SILENT; + end if; + + when x1_MODE_LANE0 => + disc_tmr_en <= '0'; + N_lanes_drvr_oe <= '0'; + port_initalized_reg <= '1'; + -- !lane_sync[0] + if lane_sync_n(0) = '0' then + mode_init_state <= SILENT; + -- !lane_ready[0] & lane_sync[0] + elsif lane_ready_n(0) = '0' and lane_sync_n(0) = '1' then + mode_init_state <= x1_RECOVERY; + end if; + + when x1_MODE_LANE2 => + disc_tmr_en <= '0'; + receive_lane2 <= '1'; + N_lanes_drvr_oe <= '0'; + port_initalized_reg <= '1'; + -- !lane_sync[2] + if lane_sync_n(2) = '0' then + mode_init_state <= SILENT; + -- !lane_ready[2] & lane_sync[2] + elsif lane_ready_n(2) = '0' and lane_sync_n(2) = '1' then + mode_init_state <= x1_RECOVERY; + end if; + + when x1_RECOVERY => + port_initalized_reg <= '0'; + disc_tmr_en <= '1'; + -- !lane_sync[0] & !lane_sync[2] & disc_tmr_done (!!!) + if lane_sync_n(0) = '0' and lane_sync_n(2) = '0' and disc_tmr_done = '1' then + + mode_init_state <= SILENT; + + -- lane_ready[0] & !receive_lane2 & !disc_tmr_done + elsif lane_sync_n(0) = '1' and receive_lane2 = '0' and disc_tmr_done = '0' then + + mode_init_state <= x1_MODE_LANE0; + + -- lane_ready[2] & receive_lane2 & !disc_tmr_done + elsif lane_sync_n(2) = '1' and receive_lane2 = '1' and disc_tmr_done = '0' then + + mode_init_state <= x1_MODE_LANE2; + + end if; + + when others => + port_initalized_reg <= '0'; + mode_init_state <= SILENT; + + end case; + + end if; + +end process; + +-- Sticky force_reinit set-reset register +process(rst_n, UCLK) + begin + if rst_n = '0' then + force_reinit_reg <= '0'; + elsif rising_edge(UCLK) then + case force_reinit_reg is + when '0' => + force_reinit_reg <= force_reinit or rxbuferr_reg; + when '1' => + -- force_reinit_reg <= not(force_reinit_clear) and not(force_reinit); + force_reinit_reg <= not(force_reinit_clear and not(force_reinit) and not(rxbuferr_reg)); + when others => + force_reinit_reg <= '0'; + end case; + end if; +end process; + +-- RXBUFRST handler +process(rst_n, UCLK) + begin + if rst_n = '0' then + rxbufrst_cntr <= (others => '0'); + rxbuferr_reg <= '0'; + RXBUFRST <= '0'; + + elsif rising_edge(UCLK) then + case rxbuferr_reg is + when '0' => + rxbuferr_reg <= RXBUFERR; + RXBUFRST <= '0'; + when '1' => + if rxbufrst_cntr = "111" then + rxbuferr_reg <= '0'; + rxbufrst_cntr <= (others => '0'); + else + RXBUFRST <= '1'; + rxbufrst_cntr <= rxbufrst_cntr + '1'; + end if; + when others => + rxbuferr_reg <= '0'; + end case; + end if; +end process; + + +-- Silence Timer Process +-- silence_timer_done: Asserted when silence_timer_en has been continuously asserted +-- for 120 +/- 40 µs and the state machine is in the SILENT state. The assertion of +-- silence_timer_done causes silence_timer_en to be de-asserted. When the state +-- machine is not in the SILENT state, silence_timer_done is de-asserted. +process(rst_n, UCLK_DV_1024) + begin + if rst_n = '0' then + silence_timer_done <= '0'; + silence_timer <= (others => '0'); + elsif rising_edge(UCLK_DV_1024) then + + case silence_timer_en is + when '0' => + silence_timer <= (others => '0'); + silence_timer_done <= '0'; + when '1' => + if silence_timer = SILENT_ENOUGH then + if mode_init_state = SILENT then + silence_timer_done <= '1'; + else + silence_timer_done <= '0'; + end if; + else + silence_timer <= silence_timer + '1'; + end if; + when others => + silence_timer <= (others => '0'); + end case; + end if; +end process; + +-- Discovery Timer Process +-- disc_tmr_done: Asserted when disc_tmr_en has been continuously asserted for 28 +/- 4 ms +-- and the state machine is in the DISCOVERY or a RECOVERY state. The assertion of +-- disc_tmr_done causes disc_tmr_en to be de-asserted. When the state machine is in +-- a state other than the DISCOVERY or a RECOVERY state, disc_tmr_done is de-asserted. +process(rst_n, UCLK_DV_1024) + begin + if rst_n = '0' then + disc_tmr_done <= '0'; + disc_tmr <= (others => '0'); + elsif rising_edge(UCLK_DV_1024) then + + case disc_tmr_en is + when '0' => + disc_tmr <= (others => '0'); + disc_tmr_done <= '0'; + when '1' => + if disc_tmr = DISCOVERY_ENDS then + if mode_init_state = DISCOVERY or mode_init_state = x1_RECOVERY then + disc_tmr_done <= '1'; + else + disc_tmr_done <= '0'; + end if; + else + disc_tmr <= disc_tmr + '1'; + end if; + when others => + disc_tmr <= (others => '0'); + end case; + end if; +end process; + +ENCHANSYNC <= '0'; + +end rtl; +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- To Do: +-- - +-- +-- Author(s): +-- - A. Demirezen, azdem@opencores.org +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------ +---------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity pseudo_random_number_generator is + Generic ( + lfsr_init : std_logic_vector(7 downto 0) := x"01" + ); + Port ( + clk : in STD_LOGIC; + rst_n : in STD_LOGIC; + -- Pseudo random number + q : out STD_LOGIC_VECTOR(7 downto 0) + ); +end pseudo_random_number_generator; + +architecture Behavioral of pseudo_random_number_generator is + +signal lfsr : std_logic_vector(7 downto 0) := x"01"; +signal q0 : std_logic; + + begin + +q <= lfsr; + +-- Polynomial: x^7 + x^6 + 1 +q0 <= lfsr(7) xnor lfsr(6) xnor lfsr(0) ; + +process (clk, rst_n) begin + + if rst_n = '0' then + + lfsr <= lfsr_init; -- x"01"; --(others => '0'); + + elsif rising_edge(clk) then + + lfsr <= lfsr(6 downto 0) & q0; + + end if; + +end process; + +end Behavioral; + +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- To Do: +-- - +-- +-- Author(s): +-- - A. Demirezen, azdem@opencores.org +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- +-- File name: serdes_wrapper_v0.vhd +-- Rev: 0.0 +-- Description: This entity instantiates 4-Lane SerDes (GTX-Quad) of Virtex-6 +-- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + +entity serdes_wrapper_v0 is + port ( + REFCLK : in std_logic; + RXUSRCLK : in std_logic; + RXUSRCLK2 : in std_logic; + TXUSRCLK : in std_logic; + TXUSRCLK2 : in std_logic; + GTXRESET : in std_logic; + RXBUFRST : in std_logic; + + -- RXN : in std_logic_vector(N-1 downto 0); + -- RXP : in std_logic_vector(N-1 downto 0); + RXN : in std_logic_vector(0 to N-1); + RXP : in std_logic_vector(0 to N-1); + TXINHIBIT_02 : in std_logic; + TXINHIBIT_others : in std_logic; + ENCHANSYNC : in std_logic; + TXDATA : in std_logic_vector(N*16-1 downto 0); + TXCHARISK : in std_logic_vector(N*2-1 downto 0); + -- TXN : out std_logic_vector(N-1 downto 0); + -- TXP : out std_logic_vector(N-1 downto 0); + TXN : out std_logic_vector(0 to N-1); + TXP : out std_logic_vector(0 to N-1); + PLLLKDET : out std_logic; + RXDATA : out std_logic_vector(N*16-1 downto 0); + RXCHARISK : out std_logic_vector(N*2-1 downto 0); + RXCHARISCOMMA : out std_logic_vector(N*2-1 downto 0); + RXBYTEISALIGNED : out std_logic_vector(N-1 downto 0); + RXBYTEREALIGN : out std_logic_vector(N-1 downto 0); + RXELECIDLE : out std_logic_vector(N-1 downto 0); + RXDISPERR : out std_logic_vector(N*2-1 downto 0); + RXNOTINTABLE : out std_logic_vector(N*2-1 downto 0); + RXBUFERR : out std_logic; + CHBONDDONE : out std_logic_vector(N-1 downto 0) + ); +end serdes_wrapper_v0; + +architecture struct of serdes_wrapper_v0 is + + COMPONENT srio_gt_wrapper_v6_4x + PORT( + REFCLK : IN std_logic; + RXUSRCLK : IN std_logic; + RXUSRCLK2 : IN std_logic; + TXUSRCLK : IN std_logic; + TXUSRCLK2 : IN std_logic; + GTXRESET : IN std_logic; + RXBUFRST : IN std_logic; + RXN0 : IN std_logic; + RXN1 : IN std_logic; + RXN2 : IN std_logic; + RXN3 : IN std_logic; + RXP0 : IN std_logic; + RXP1 : IN std_logic; + RXP2 : IN std_logic; + RXP3 : IN std_logic; + TXINHIBIT_02 : IN std_logic; + TXINHIBIT_13 : IN std_logic; + ENCHANSYNC : IN std_logic; + TXDATA0 : IN std_logic_vector(15 downto 0); + TXDATA1 : IN std_logic_vector(15 downto 0); + TXDATA2 : IN std_logic_vector(15 downto 0); + TXDATA3 : IN std_logic_vector(15 downto 0); + TXCHARISK0 : IN std_logic_vector(1 downto 0); + TXCHARISK1 : IN std_logic_vector(1 downto 0); + TXCHARISK2 : IN std_logic_vector(1 downto 0); + TXCHARISK3 : IN std_logic_vector(1 downto 0); + TXN0 : OUT std_logic; + TXN1 : OUT std_logic; + TXN2 : OUT std_logic; + TXN3 : OUT std_logic; + TXP0 : OUT std_logic; + TXP1 : OUT std_logic; + TXP2 : OUT std_logic; + TXP3 : OUT std_logic; + PLLLKDET : OUT std_logic; + RXDATA0 : OUT std_logic_vector(15 downto 0); + RXDATA1 : OUT std_logic_vector(15 downto 0); + RXDATA2 : OUT std_logic_vector(15 downto 0); + RXDATA3 : OUT std_logic_vector(15 downto 0); + RXCHARISK0 : OUT std_logic_vector(1 downto 0); + RXCHARISK1 : OUT std_logic_vector(1 downto 0); + RXCHARISK2 : OUT std_logic_vector(1 downto 0); + RXCHARISK3 : OUT std_logic_vector(1 downto 0); + RXCHARISCOMMA0 : OUT std_logic_vector(1 downto 0); + RXCHARISCOMMA1 : OUT std_logic_vector(1 downto 0); + RXCHARISCOMMA2 : OUT std_logic_vector(1 downto 0); + RXCHARISCOMMA3 : OUT std_logic_vector(1 downto 0); + RXBYTEISALIGNED: OUT std_logic_vector(3 downto 0); + RXBYTEREALIGN : OUT std_logic_vector(3 downto 0); + RXELECIDLE : OUT std_logic_vector(3 downto 0); + RXDISPERR0 : OUT std_logic_vector(1 downto 0); + RXDISPERR1 : OUT std_logic_vector(1 downto 0); + RXDISPERR2 : OUT std_logic_vector(1 downto 0); + RXDISPERR3 : OUT std_logic_vector(1 downto 0); + RXNOTINTABLE0 : OUT std_logic_vector(1 downto 0); + RXNOTINTABLE1 : OUT std_logic_vector(1 downto 0); + RXNOTINTABLE2 : OUT std_logic_vector(1 downto 0); + RXNOTINTABLE3 : OUT std_logic_vector(1 downto 0); + RXBUFERR : OUT std_logic; + CHBONDDONE0 : OUT std_logic; + CHBONDDONE1 : OUT std_logic; + CHBONDDONE2 : OUT std_logic; + CHBONDDONE3 : OUT std_logic + ); + END COMPONENT; + +begin + + Inst_srio_gt_wrapper_v6_4x: srio_gt_wrapper_v6_4x PORT MAP( + REFCLK => REFCLK , + RXUSRCLK => RXUSRCLK , + RXUSRCLK2 => RXUSRCLK2 , + TXUSRCLK => TXUSRCLK , + TXUSRCLK2 => TXUSRCLK2 , + GTXRESET => GTXRESET , + RXBUFRST => RXBUFRST , + RXN0 => RXN(0) , + RXN1 => RXN(1) , + RXN2 => RXN(2) , + RXN3 => RXN(3) , + RXP0 => RXP(0) , + RXP1 => RXP(1) , + RXP2 => RXP(2) , + RXP3 => RXP(3) , + TXINHIBIT_02 => TXINHIBIT_02 , + TXINHIBIT_13 => TXINHIBIT_others , + ENCHANSYNC => ENCHANSYNC , + TXDATA0 => TXDATA(15 downto 0) , + TXDATA1 => TXDATA(31 downto 16) , + TXDATA2 => TXDATA(47 downto 32) , + TXDATA3 => TXDATA(63 downto 48) , + TXCHARISK0 => TXCHARISK(1 downto 0) , + TXCHARISK1 => TXCHARISK(3 downto 2) , + TXCHARISK2 => TXCHARISK(5 downto 4) , + TXCHARISK3 => TXCHARISK(7 downto 6) , + TXN0 => TXN(0) , + TXN1 => TXN(1) , + TXN2 => TXN(2) , + TXN3 => TXN(3) , + TXP0 => TXP(0) , + TXP1 => TXP(1) , + TXP2 => TXP(2) , + TXP3 => TXP(3) , + PLLLKDET => PLLLKDET , + RXDATA0 => RXDATA(15 downto 0) , + RXDATA1 => RXDATA(31 downto 16) , + RXDATA2 => RXDATA(47 downto 32) , + RXDATA3 => RXDATA(63 downto 48) , + RXCHARISK0 => RXCHARISK(1 downto 0) , + RXCHARISK1 => RXCHARISK(3 downto 2) , + RXCHARISK2 => RXCHARISK(5 downto 4) , + RXCHARISK3 => RXCHARISK(7 downto 6) , + RXCHARISCOMMA0 => RXCHARISCOMMA(1 downto 0) , + RXCHARISCOMMA1 => RXCHARISCOMMA(3 downto 2) , + RXCHARISCOMMA2 => RXCHARISCOMMA(5 downto 4) , + RXCHARISCOMMA3 => RXCHARISCOMMA(7 downto 6) , + RXBYTEISALIGNED => RXBYTEISALIGNED , + RXBYTEREALIGN => RXBYTEREALIGN , + RXELECIDLE => RXELECIDLE , + RXDISPERR0 => RXDISPERR(1 downto 0) , + RXDISPERR1 => RXDISPERR(3 downto 2) , + RXDISPERR2 => RXDISPERR(5 downto 4) , + RXDISPERR3 => RXDISPERR(7 downto 6) , + RXNOTINTABLE0 => RXNOTINTABLE(1 downto 0) , + RXNOTINTABLE1 => RXNOTINTABLE(3 downto 2) , + RXNOTINTABLE2 => RXNOTINTABLE(5 downto 4) , + RXNOTINTABLE3 => RXNOTINTABLE(7 downto 6) , + RXBUFERR => RXBUFERR , + CHBONDDONE0 => CHBONDDONE(0) , + CHBONDDONE1 => CHBONDDONE(1) , + CHBONDDONE2 => CHBONDDONE(2) , + CHBONDDONE3 => CHBONDDONE(3) + ); + +end struct; +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- To Do: +-- - +-- +-- Author(s): +-- - A. Demirezen, azdem@opencores.org +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.ALL; +use ieee.numeric_std.ALL; +library UNISIM; +use UNISIM.Vcomponents.ALL; + +entity srio_pcs_struct is + port ( CHBONDDONE : in std_logic_vector (3 downto 0); + force_reinit_i : in std_logic; + inboundRead_i : in std_logic; + outboundSymbol_i : in std_logic_vector (33 downto 0); + outboundWrite_i : in std_logic; + PLLLKDET : in std_logic; + rio_clk : in std_logic; + rst_n : in std_logic; + RXBUFERR : in std_logic; + RXBYTEISALIGNED : in std_logic_vector (3 downto 0); + RXBYTEREALIGN : in std_logic_vector (3 downto 0); + RXCAHRISCOMMA : in std_logic_vector (7 downto 0); + RXCAHRISK : in std_logic_vector (7 downto 0); + RXDATA : in std_logic_vector (63 downto 0); + RXDISPERR : in std_logic_vector (7 downto 0); + RXELECIDLE : in std_logic_vector (3 downto 0); + RXNOTINTABLE : in std_logic_vector (7 downto 0); + UCLK : in std_logic; + UCLK_DV4 : in std_logic; + UCLK_DV1024 : in std_logic; + UCLK_or_DV4 : in std_logic; + UCLK_x2 : in std_logic; + UCLK_x2_DV2 : in std_logic; + ENCHANSYNC : out std_logic; + inboundEmpty_o : out std_logic; + inboundSymbol_o : out std_logic_vector (33 downto 0); + lane_sync_o : out std_logic_vector (3 downto 0); + mode_sel_o : out std_logic; + mode_0_lane_sel_o : out std_logic; + outboundFull_o : out std_logic; + port_initialized_o : out std_logic; + RXBUFRST : out std_logic; + TXCAHRISK : out std_logic_vector (7 downto 0); + TXDATA : out std_logic_vector (63 downto 0); + TXINHIBIT_others : out std_logic; + TXINHIBIT_02 : out std_logic); +end srio_pcs_struct; + +architecture BEHAVIORAL of srio_pcs_struct is + signal ccs_timer_rst : std_logic; + signal RXCAHRISvalid : std_logic_vector (7 downto 0); + signal send_A : std_logic_vector (1 downto 0); + signal send_ccs : std_logic; + signal send_idle : std_logic_vector (1 downto 0); + signal send_K : std_logic_vector (1 downto 0); + signal send_R : std_logic_vector (1 downto 0); + signal mode_0_lane_sel_o_DUMMY : std_logic; + signal TXINHIBIT_02_DUMMY : std_logic; + signal mode_sel_o_DUMMY : std_logic; + signal port_initialized_o_DUMMY : std_logic; + signal TXINHIBIT_others_DUMMY : std_logic; + component ccs_timer + port ( rst_n : in std_logic; + ccs_timer_rst : in std_logic; + send_ccs : out std_logic; + UCLK : in std_logic); + end component; + + component idle_generator_dual + port ( UCLK : in std_logic; + rst_n : in std_logic; + send_K : out std_logic_vector (1 downto 0); + send_A : out std_logic_vector (1 downto 0); + send_R : out std_logic_vector (1 downto 0); + send_idle : in std_logic_vector (1 downto 0)); + end component; + + component port_init_fsms + port ( rst_n : in std_logic; + UCLK_x2 : in std_logic; + UCLK : in std_logic; + UCLK_DV4 : in std_logic; + UCLK_DV_1024 : in std_logic; + force_reinit : in std_logic; + PLLLKDET : in std_logic; + RXBUFERR : in std_logic; + RXDATA : in std_logic_vector (63 downto 0); + RXCHARISK : in std_logic_vector (7 downto 0); + RXCHARISCOMMA : in std_logic_vector (7 downto 0); + RXBYTEISALIGNED : in std_logic_vector (3 downto 0); + RXBYTEREALIGN : in std_logic_vector (3 downto 0); + RXELECIDLE : in std_logic_vector (3 downto 0); + RXDISPERR : in std_logic_vector (7 downto 0); + RXNOTINTABLE : in std_logic_vector (7 downto 0); + CHBONDDONE : in std_logic_vector (3 downto 0); + mode_sel : out std_logic; + port_initalized : out std_logic; + TXINHIBIT_02 : out std_logic; + TXINHIBIT_others : out std_logic; + ENCHANSYNC : out std_logic; + RXBUFRST : out std_logic; + lane_sync : out std_logic_vector (3 downto 0); + mode_0_lane_sel : out std_logic; + RXCHARISvalid : out std_logic_vector (7 downto 0)); + end component; + + component pcs_rx_controller + port ( rst_n : in std_logic; + rio_clk : in std_logic; + UCLK_x2 : in std_logic; + UCLK : in std_logic; + UCLK_x2_DV2 : in std_logic; + inboundRead_i : in std_logic; + port_initalized_i : in std_logic; + mode_sel_i : in std_logic; + mode_0_lane_sel_i : in std_logic; + RXDATA_i : in std_logic_vector (63 downto 0); + RXCHARISK_i : in std_logic_vector (7 downto 0); + RXCHARISvalid_i : in std_logic_vector (7 downto 0); + inboundEmpty_o : out std_logic; + inboundSymbol_o : out std_logic_vector (33 downto 0); + UCLK_or_DV4 : in std_logic); + end component; + + component pcs_tx_controller + port ( rst_n : in std_logic; + rio_clk : in std_logic; + UCLK_x2 : in std_logic; + UCLK : in std_logic; + UCLK_x2_DV2 : in std_logic; + UCLK_or_DV4 : in std_logic; + outboundWrite_i : in std_logic; + send_ccs_i : in std_logic; + TXINHIBIT_02 : in std_logic; + TXINHIBIT_others : in std_logic; + port_initalized_i : in std_logic; + mode_sel_i : in std_logic; + mode_0_lane_sel_i : in std_logic; + outboundSymbol_i : in std_logic_vector (33 downto 0); + send_K_i : in std_logic_vector (1 downto 0); + send_A_i : in std_logic_vector (1 downto 0); + send_R_i : in std_logic_vector (1 downto 0); + outboundFull_o : out std_logic; + ccs_timer_rst_o : out std_logic; + TXDATA_o : out std_logic_vector (63 downto 0); + TXCHARISK_o : out std_logic_vector (7 downto 0); + send_idle_o : out std_logic_vector (1 downto 0)); + end component; + +begin + mode_sel_o <= mode_sel_o_DUMMY; + mode_0_lane_sel_o <= mode_0_lane_sel_o_DUMMY; + port_initialized_o <= port_initialized_o_DUMMY; + TXINHIBIT_others <= TXINHIBIT_others_DUMMY; + TXINHIBIT_02 <= TXINHIBIT_02_DUMMY; + ccs_timer_inst : ccs_timer + port map (ccs_timer_rst=>ccs_timer_rst, + rst_n=>rst_n, + UCLK=>UCLK, + send_ccs=>send_ccs); + + dual_idle_generator : idle_generator_dual + port map (rst_n=>rst_n, + send_idle(1 downto 0)=>send_idle(1 downto 0), + UCLK=>UCLK, + send_A(1 downto 0)=>send_A(1 downto 0), + send_K(1 downto 0)=>send_K(1 downto 0), + send_R(1 downto 0)=>send_R(1 downto 0)); + + port_init_fsms_inst : port_init_fsms + port map (CHBONDDONE(3 downto 0)=>CHBONDDONE(3 downto 0), + force_reinit=>force_reinit_i, + PLLLKDET=>PLLLKDET, + rst_n=>rst_n, + RXBUFERR=>RXBUFERR, + RXBYTEISALIGNED(3 downto 0)=>RXBYTEISALIGNED(3 downto 0), + RXBYTEREALIGN(3 downto 0)=>RXBYTEREALIGN(3 downto 0), + RXCHARISCOMMA(7 downto 0)=>RXCAHRISCOMMA(7 downto 0), + RXCHARISK(7 downto 0)=>RXCAHRISK(7 downto 0), + RXDATA(63 downto 0)=>RXDATA(63 downto 0), + RXDISPERR(7 downto 0)=>RXDISPERR(7 downto 0), + RXELECIDLE(3 downto 0)=>RXELECIDLE(3 downto 0), + RXNOTINTABLE(7 downto 0)=>RXNOTINTABLE(7 downto 0), + UCLK=>UCLK, + UCLK_DV_1024=>UCLK_DV1024, + UCLK_DV4=>UCLK_DV4, + UCLK_x2=>UCLK_x2, + ENCHANSYNC=>ENCHANSYNC, + lane_sync(3 downto 0)=>lane_sync_o(3 downto 0), + mode_sel=>mode_sel_o_DUMMY, + mode_0_lane_sel=>mode_0_lane_sel_o_DUMMY, + port_initalized=>port_initialized_o_DUMMY, + RXBUFRST=>RXBUFRST, + RXCHARISvalid(7 downto 0)=>RXCAHRISvalid(7 downto 0), + TXINHIBIT_others=>TXINHIBIT_others_DUMMY, + TXINHIBIT_02=>TXINHIBIT_02_DUMMY); + + rx_controller_inst : pcs_rx_controller + port map (inboundRead_i=>inboundRead_i, + mode_sel_i=>mode_sel_o_DUMMY, + mode_0_lane_sel_i=>mode_0_lane_sel_o_DUMMY, + port_initalized_i=>port_initialized_o_DUMMY, + rio_clk=>rio_clk, + rst_n=>rst_n, + RXCHARISK_i(7 downto 0)=>RXCAHRISK(7 downto 0), + RXCHARISvalid_i(7 downto 0)=>RXCAHRISvalid(7 downto 0), + RXDATA_i(63 downto 0)=>RXDATA(63 downto 0), + UCLK=>UCLK, + UCLK_or_DV4=>UCLK_or_DV4, + UCLK_x2=>UCLK_x2, + UCLK_x2_DV2=>UCLK_x2_DV2, + inboundEmpty_o=>inboundEmpty_o, + inboundSymbol_o(33 downto 0)=>inboundSymbol_o(33 downto 0)); + + tx_controller_inst : pcs_tx_controller + port map (mode_sel_i=>mode_sel_o_DUMMY, + mode_0_lane_sel_i=>mode_0_lane_sel_o_DUMMY, + outboundSymbol_i(33 downto 0)=>outboundSymbol_i(33 downto 0), + outboundWrite_i=>outboundWrite_i, + port_initalized_i=>port_initialized_o_DUMMY, + rio_clk=>rio_clk, + rst_n=>rst_n, + send_A_i(1 downto 0)=>send_A(1 downto 0), + send_ccs_i=>send_ccs, + send_K_i(1 downto 0)=>send_K(1 downto 0), + send_R_i(1 downto 0)=>send_R(1 downto 0), + TXINHIBIT_others=>TXINHIBIT_others_DUMMY, + TXINHIBIT_02=>TXINHIBIT_02_DUMMY, + UCLK=>UCLK, + UCLK_or_DV4=>UCLK_or_DV4, + UCLK_x2=>UCLK_x2, + UCLK_x2_DV2=>UCLK_x2_DV2, + ccs_timer_rst_o=>ccs_timer_rst, + outboundFull_o=>outboundFull_o, + send_idle_o(1 downto 0)=>send_idle(1 downto 0), + TXCHARISK_o(7 downto 0)=>TXCAHRISK(7 downto 0), + TXDATA_o(63 downto 0)=>TXDATA(63 downto 0)); + +end BEHAVIORAL; + + Index: 2.0.0-alpha/rtl/vhdl/RioWbBridge.vhd =================================================================== --- 2.0.0-alpha/rtl/vhdl/RioWbBridge.vhd (nonexistent) +++ 2.0.0-alpha/rtl/vhdl/RioWbBridge.vhd (revision 23) @@ -0,0 +1,935 @@ +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- Description +-- Containing a bridge between a RapidIO network and a Wishbone bus. Packets +-- NWRITE and NREAD are currently supported. +-- +-- To Do: +-- - +-- +-- Author(s): +-- - Nader Kardouni, nader.kardouni@se.transport.bombardier.com +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.numeric_std.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use work.rio_common.all; + +------------------------------------------------------------------------------- +-- entity for RioWbBridge. +------------------------------------------------------------------------------- +Entity RioWbBridge is + generic( + DEVICE_IDENTITY : std_logic_vector(15 downto 0); + DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0); + DEVICE_REV : std_logic_vector(31 downto 0); + ASSY_IDENTITY : std_logic_vector(15 downto 0); + ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0); + ASSY_REV : std_logic_vector(15 downto 0); + DEFAULT_BASE_DEVICE_ID : std_logic_vector(15 downto 0) := x"ffff"); + port( + clk : in std_logic; -- Main clock 25MHz + areset_n : in std_logic; -- Asynchronous reset, active low + + readFrameEmpty_i : in std_logic; + readFrame_o : out std_logic; + readContent_o : out std_logic; + readContentEnd_i : in std_logic; + readContentData_i : in std_logic_vector(31 downto 0); + + writeFrameFull_i : in std_logic; + writeFrame_o : out std_logic; + writeFrameAbort_o : out std_logic; + writeContent_o : out std_logic; + writeContentData_o : out std_logic_vector(31 downto 0); + + -- interface to the peripherals module + wbStb_o : out std_logic; -- strob signal, active high + wbWe_o : out std_logic; -- write signal, active high + wbData_o : out std_logic_vector(7 downto 0); -- master data bus + wbAdr_o : out std_logic_vector(25 downto 0); -- master address bus + wbErr_i : in std_logic; -- error signal, high active + wbAck_i : in std_logic; -- slave acknowledge + wbData_i : in std_logic_vector(7 downto 0) -- slave data bus + ); +end; + +------------------------------------------------------------------------------- +-- Architecture for RioWbBridge. +------------------------------------------------------------------------------- +architecture rtl of RioWbBridge 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; + + constant RST_LVL : std_logic := '0'; + constant BERR_UNKNOWN_DATA : std_logic_vector(7 downto 0) := X"08"; -- not valid data + constant BERR_FRAME_SIZE : std_logic_vector(7 downto 0) := X"81"; -- Frame code size error + constant BERR_FRAME_CODE : std_logic_vector(7 downto 0) := X"80"; -- Frame code type error + constant BERR_NOT_RESPONSE : std_logic_vector(7 downto 0) := X"86"; -- Not response from the device + + type state_type_RioBrige is (IDLE, WAIT_HEADER_0, HEADER_0, HEADER_1, CHECK_OPERATION, + READ_ADDRESS, READ_FROM_FIFO, CHECK_ERROR, WRITE_DATA, + WRITE_TO_WB, WAIT_IDLE, SEND_DONE_0, SEND_DONE_1, + SEND_DONE_2, READ_FROM_WB, APPEND_CRC, + SEND_TO_FIFO, SEND_ERROR, SEND_FRAME, APPEND_CRC_AND_SEND, + SEND_MAINTENANCE_READ_RESPONSE_0, SEND_MAINTENANCE_READ_RESPONSE_1, + SEND_MAINTENANCE_WRITE_RESPONSE_0, SEND_MAINTENANCE_WRITE_RESPONSE_1); + signal stateRB, nextStateRB : state_type_RioBrige; + type byteArray8 is array (0 to 7) of std_logic_vector(7 downto 0); + signal dataLane : byteArray8; +-- type byteArray4 is array (0 to 3) of std_logic_vector(7 downto 0); +-- signal dataLaneS : byteArray4; + signal pos, byteOffset : integer range 0 to 7; + signal numberOfByte, byteCnt, headLen : integer range 0 to 256; + signal endianMsb, reserved, ready : std_logic; + signal start : std_logic; + signal wdptr : std_logic; + signal wbStb : std_logic; + signal xamsbs : std_logic_vector(1 downto 0); + signal ftype : std_logic_vector(3 downto 0); + signal ttype : std_logic_vector(3 downto 0); + signal size : std_logic_vector(3 downto 0); + signal tid : std_logic_vector(7 downto 0); + signal tt : std_logic_vector(1 downto 0); + signal errorCode : std_logic_vector(7 downto 0); + signal sourceId : std_logic_vector(15 downto 0); + signal destinationId : std_logic_vector(15 downto 0); + signal writeContentData : std_logic_vector(31 downto 0); + signal crc16Current, crc16Temp, crc16Next: std_logic_vector(15 downto 0); + signal tempAddr : std_logic_vector(25 downto 0); + signal timeOutCnt : std_logic_vector(14 downto 0); + + -- Configuration memory signal declaration. + signal configEnable : std_logic; + signal configWrite : std_logic; + signal configAddress : std_logic_vector(23 downto 0); + signal configDataWrite : std_logic_vector(31 downto 0); + signal configDataRead : std_logic_vector(31 downto 0); + signal componentTag : std_logic_vector(31 downto 0); + signal baseDeviceId : std_logic_vector(15 downto 0) := DEFAULT_BASE_DEVICE_ID; + signal hostBaseDeviceIdLocked : std_logic; + signal hostBaseDeviceId : std_logic_vector(15 downto 0) := (others => '1'); + +begin + wbStb_o <= wbStb; + writeContentData_o <= writeContentData; + + Crc16High: Crc16CITT + port map( + d_i=>writeContentData(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp); + Crc16Low: Crc16CITT + port map( + d_i=>writeContentData(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next); + + + + ----------------------------------------------------------------------------- + -- wbInterfaceCtrl + -- This process handle the Wishbone interface to the RioWbBridge module. + ----------------------------------------------------------------------------- + wbInterfaceCtrl: process(clk, areset_n) + variable Temp : std_logic_vector(2 downto 0); + begin + if areset_n = RST_LVL then + start <= '0'; + wdptr <= '0'; + wbStb <= '0'; + wbWe_o <= '0'; + byteCnt <= 0; + headLen <= 0; + byteOffset <= 0; + readFrame_o <= '0'; + readContent_o <= '0'; + writeFrame_o <= '0'; + writeContent_o <= '0'; + writeFrameAbort_o <= '0'; + configWrite <= '0'; + configEnable <= '0'; + ready <= '0'; + endianMsb <= '0'; + stateRB <= IDLE; + nextStateRB <= IDLE; + tt <= (others => '0'); + tid <= (others => '0'); + size <= (others => '0'); + ttype <= (others => '0'); + ftype <= (others => '0'); + xamsbs <= (others => '0'); + sourceId <= (others => '0'); + configDataWrite <= (others => '0'); + destinationId <= (others => '0'); + errorCode <= (others => '0'); + tempAddr <= (others => '0'); + wbAdr_o <= (others => '0'); + wbData_o <= (others => '0'); + writeContentData <= (others => '0'); + dataLane <= (others =>(others => '0')); +-- dataLaneS <= (others =>(others => '0')); + crc16Current <= (others => '0'); + timeOutCnt <= (others => '0'); + Temp := (others => '0'); + elsif clk'event and clk ='1' then + + case stateRB is + when IDLE => + if (readFrameEmpty_i = '0') and (writeFrameFull_i = '0') then + readContent_o <= '1'; + byteCnt <= 0; + ready <= '0'; + endianMsb <= '1'; + timeOutCnt <= (others => '0'); + crc16Current <= (others => '1'); + stateRB <= WAIT_HEADER_0; + else + start <= '0'; + readFrame_o <= '0'; + readContent_o <= '0'; + writeFrame_o <= '0'; + writeContent_o <= '0'; + writeFrameAbort_o <= '0'; + errorCode <= (others => '0'); + writeContentData <= (others => '0'); + dataLane <= (others =>(others => '0')); +-- dataLaneS <= (others =>(others => '0')); + Temp := (others => '0'); + end if; + + when WAIT_HEADER_0 => + stateRB <= HEADER_0; + + when HEADER_0 => + readContent_o <= '1'; -- read the header (frame 0) + tt <= readContentData_i(21 downto 20); + ftype <= readContentData_i(19 downto 16); + destinationId <= readContentData_i(15 downto 0); + stateRB <= HEADER_1; + + when HEADER_1 => -- read the header (frame 1) + readContent_o <= '1'; + ttype <= readContentData_i(15 downto 12); + size <= readContentData_i(11 downto 8); + tid <= readContentData_i(7 downto 0); + sourceId <= readContentData_i(31 downto 16); + stateRB <= READ_ADDRESS; + + when READ_ADDRESS => + readContent_o <= '0'; + wdptr <= readContentData_i(2); + xamsbs <= readContentData_i(1 downto 0); + tempAddr <= readContentData_i(25 downto 3) & "000"; -- Wishbone address bus is 26 bits width + configAddress <= readContentData_i(23 downto 0); -- this line is in case of maintenance pakage (config-offset(21-bits)+wdptr(1-bit)+rsv(2-bits)) + stateRB <= CHECK_ERROR; + + when CHECK_ERROR => + byteOffset <= pos; -- first byte position in the first payload + tempAddr <= tempAddr + pos; -- first address + if readContentEnd_i = '1' then -- check if data not valid i the switch buffer + wbStb <= '0'; + wbWe_o <= '0'; + byteOffset <= 0; + writeFrameAbort_o <= '1'; -- over write the frame with an error frame + errorCode <= BERR_UNKNOWN_DATA; -- not valid data + stateRB <= SEND_ERROR; + + -- check if error in the frame size for write pakage + elsif (reserved = '1') and (ftype = FTYPE_WRITE_CLASS) then + wbStb <= '0'; + wbWe_o <= '0'; + byteOffset <= 0; + writeFrameAbort_o <= '1'; -- over write the frame with an error frame + errorCode <= BERR_FRAME_SIZE; -- Frame code size error + stateRB <= SEND_ERROR; + + -- type 5 pakage formate, NWRITE transaction (write to peripherals) read payload from the buffer + elsif (ftype = FTYPE_WRITE_CLASS) and (ttype = "0100") and (tt = "01") then + readContent_o <= '1'; + stateRB <= READ_FROM_FIFO; -- read the payload + nextStateRB <= SEND_ERROR; -- this is in case not valid data in switch buffer + headLen <= 12; + + -- Type 2 pakage formate, NREAD transaction, (read from peripherals) write payload to the buffer + elsif (ftype = FTYPE_REQUEST_CLASS) and (ttype = "0100") and (tt = "01") then + writeContent_o <= '1'; -- write the header-0 of the Read Response pakage + writeContentData(15 downto 0) <= sourceId; -- write to the source address + writeContentData(19 downto 16) <= "1101"; -- Response pakage type 13, ftype Response + writeContentData(21 downto 20) <= "01"; -- tt + writeContentData(31 downto 22) <= "0000000000"; -- acckId, vc, cfr, prio + stateRB <= SEND_DONE_0; -- + headLen <= 8; + + -- Type 8 pakage formate, maintenance Read request + elsif (ftype = FTYPE_MAINTENANCE_CLASS) and (ttype = TTYPE_MAINTENANCE_READ_REQUEST) and (tt = "01") then + configWrite <= '0'; -- read config operation + configEnable <= '1'; -- enable signal to the memoryConfig process + writeContent_o <= '1'; + -- write the header-0 of the Read Response pakage + writeContentData(15 downto 0) <= sourceId; -- write to the source address, this is a response pakage + writeContentData(19 downto 16) <= FTYPE_MAINTENANCE_CLASS; -- ftype, maintenance + writeContentData(21 downto 20) <= "01"; -- tt + writeContentData(31 downto 22) <= "0000000000"; -- acckId, vc, cfr, prio + stateRB <= SEND_MAINTENANCE_READ_RESPONSE_0; + + -- Type 8 pakage formate, maintenance Write request + elsif (ftype = FTYPE_MAINTENANCE_CLASS) and (ttype = TTYPE_MAINTENANCE_WRITE_REQUEST) and (tt = "01") then + configWrite <= '1'; -- write config operation + writeContent_o <= '1'; -- write the header-0 + writeContentData(15 downto 0) <= sourceId; -- write to the source address, this is a response pakage + writeContentData(19 downto 16) <= FTYPE_MAINTENANCE_CLASS; -- ftype, maintenance + writeContentData(21 downto 20) <= "01"; -- tt + writeContentData(31 downto 22) <= "0000000000"; -- acckId, vc, cfr, prio + stateRB <= SEND_MAINTENANCE_WRITE_RESPONSE_0; + + -- Error: unexpected ftype or ttype + else + wbStb <= '0'; + wbWe_o <= '0'; + byteOffset <= 0; + writeFrameAbort_o <= '1'; -- over write the frame with an error frame + errorCode <= BERR_FRAME_CODE; + stateRB <= SEND_ERROR; -- next state after the dataLane is stored in the switch buffer + end if; + + when SEND_MAINTENANCE_READ_RESPONSE_0 => + byteCnt <= 0; + configEnable <= '0'; -- disable signal to the memoryConfig process + -- write the header-1 of the Read Response pakage + writeContentData(7 downto 0) <= tid; + writeContentData(11 downto 8) <= "0000"; -- size/status + writeContentData(15 downto 12) <= TTYPE_MAINTENANCE_READ_RESPONSE; -- transaction type, Maintenance Read Response + writeContentData(31 downto 16) <= baseDeviceId; -- destination address, because this is a response pakage + crc16Current <= crc16Next; -- first frame's CRC + stateRB <= SEND_MAINTENANCE_READ_RESPONSE_1; + + when SEND_MAINTENANCE_READ_RESPONSE_1 => + byteCnt <= byteCnt + 1; -- using byteCnt as a counter + if byteCnt = 0 then + writeContentData <= X"FF" & X"000000"; -- write the filed with HOP + reserved + crc16Current <= crc16Next; -- second frame's CRC + elsif byteCnt = 1 then + if configAddress(2) = '0' then -- check the wdptr bit in the config offset field + writeContentData <= configDataRead; -- write payload-0 with data if wdptr='0' + else + writeContentData <= (others => '0'); -- write zeros + end if; + crc16Current <= crc16Next; -- third frame's CRC + elsif byteCnt = 2 then + if configAddress(2) = '0' then -- check the wdptr bit in the config offset field + writeContentData <= (others => '0'); -- write zeros + else + writeContentData <= configDataRead; -- write payload-1 with data if wdptr='1' + end if; + crc16Current <= crc16Next; -- forth frame's CRC + elsif byteCnt = 3 then + writeContentData <= crc16Next & X"0000"; -- write the CRC field + else + writeContent_o <= '0'; + stateRB <= SEND_FRAME; + end if; + + when SEND_MAINTENANCE_WRITE_RESPONSE_0 => + byteCnt <= 0; + readContent_o <= '1'; -- read the config offset + if configAddress(2) = '0' then -- check the wdptr bit in the config offset field + configDataWrite <= readContentData_i; -- copy payload-0 if wdptr='0' + else + configDataWrite <= configDataWrite; -- do nothing + end if; + writeContentData(7 downto 0) <= tid; + writeContentData(11 downto 8) <= "0000"; -- size/status + writeContentData(15 downto 12) <= TTYPE_MAINTENANCE_WRITE_RESPONSE; -- transaction type, Maintenance Write Response + writeContentData(31 downto 16) <= baseDeviceId; -- destination address, because this is a response pakage + crc16Current <= crc16Next; -- first frame's CRC + stateRB <= SEND_MAINTENANCE_WRITE_RESPONSE_1; + + when SEND_MAINTENANCE_WRITE_RESPONSE_1 => + byteCnt <= byteCnt + 1; -- using byteCnt as a counter + if byteCnt = 0 then + writeContentData <= X"FF" & X"000000"; -- write the filed with HOP + reserved + crc16Current <= crc16Next; -- second frame's CRC + elsif byteCnt = 1 then + configEnable <= '1'; -- enable signal to the memoryConfig process + writeContentData <= crc16Next & X"0000"; -- write the CRC field + if configAddress(2) = '0' then -- check the wdptr bit in the config offset field + configDataWrite <= configDataWrite; -- do nothing + else + configDataWrite <= readContentData_i; -- copy payload-1 if wdptr='1' + end if; + else + configEnable <= '0'; -- disable signal to the memoryConfig process + readContent_o <= '0'; -- at this point even the frame's CRC is read from the buffer + writeContent_o <= '0'; + stateRB <= SEND_FRAME; + end if; + + when SEND_DONE_0 => + writeContent_o <= '1'; + writeContentData(7 downto 0) <= tid; + writeContentData(11 downto 8) <= "0000"; -- size/status + writeContentData(15 downto 12) <= "1000"; -- ttype + writeContentData(31 downto 16) <= baseDeviceId; + crc16Current <= crc16Next; -- first frame's CRC + stateRB <= SEND_DONE_1; + + when SEND_DONE_1 => + byteCnt <= 0; + dataLane <= (others =>(others => '0')); + writeContent_o <= '0'; -- this line is to make sure that the CRC is complete read + crc16Current <= crc16Next; -- second frame's CRC + wbAdr_o <= tempAddr; + tempAddr <= tempAddr + 1; + wbStb <= '1'; + wbWe_o <= '0'; + byteOffset <= pos; + stateRB <= READ_FROM_WB; + + when READ_FROM_WB => + if wbAck_i = '1' then + timeOutCnt <= (others => '0'); -- reset the time out conter + if wbErr_i = '0' then -- check if no error occur + if (byteCnt < numberOfByte - 1) then -- check if reach the last data byte + byteCnt <= byteCnt + 1; + if (byteCnt + headLen = 80) then -- when current position in payload is a CRC position + dataLane(0) <= crc16Current(15 downto 8); + dataLane(1) <= crc16Current(7 downto 0); + dataLane(2) <= wbData_i; + byteOffset <= 3; + elsif byteOffset < 7 then + dataLane(byteOffset) <= wbData_i; + byteOffset <= byteOffset + 1; + else -- dataLane vector is ready to send to fifo + dataLane(7) <= wbData_i; + byteOffset <= 0; -- Here, sets byteOffset for other response + stateRB <= SEND_TO_FIFO; + nextStateRB <= READ_FROM_WB; -- + end if; + else -- get last data from Wishbone + wbStb <= '0'; + byteCnt <= 0; -- Here, using byteCnt and reset it for other response + dataLane(byteOffset) <= wbData_i; + stateRB <= APPEND_CRC_AND_SEND; + if byteOffset < 7 then -- checking for CRC appending position + byteOffset <= byteOffset + 1; + else + byteOffset <= 0; + end if; + end if; + + -- when Wishbone error occur + else + wbStb <= '0'; + wbWe_o <= '0'; + byteOffset <= 0; + writeFrameAbort_o <= '1'; -- over write the frame with an error frame + errorCode <= wbData_i; + stateRB <= SEND_ERROR; + end if; + else -- when no acknowledge received + if timeOutCnt(13) = '1' then -- when waiting more than 1 ms for response from the device + wbStb <= '0'; + wbWe_o <= '0'; + byteOffset <= 0; + writeFrameAbort_o <= '1'; -- over write the frame with an error frame + errorCode <= BERR_NOT_RESPONSE; + stateRB <= SEND_ERROR; + else + timeOutCnt <= timeOutCnt + 1; + end if; + end if; + + -- appending CRC and write to the fifo when frame is shorter then 80 bytes + when APPEND_CRC_AND_SEND => + writeContent_o <= '0'; + byteCnt <= byteCnt + 1; + -- check if frame is shorter than 80 bytes + if (numberOfByte < 65) then + -- Yes, frame is shorter then 80 bytes + if byteCnt = 0 then + -- first write the current double word to the fifo + -- then put the CRC in the next double word + byteOffset <= 0; + stateRB <= SEND_TO_FIFO; + nextStateRB <= APPEND_CRC_AND_SEND; + elsif byteCnt = 1 then + -- append the CRC + writeContent_o <= '1'; + writeContentData <= crc16Current & X"0000"; + else + stateRB <= SEND_FRAME; -- store in the switch buffer + end if; + else + --No, appending CRC and write to the fifo when frame is longer then 80 bytes + if byteCnt = 0 then + -- check if the last byte was placed in the second half of the double word, + -- in that case write the first word to the fifo. + writeContentData <= dataLane(0) & dataLane(1) & dataLane(2) & dataLane(3); + elsif byteCnt = 1 then + crc16Current <= crc16Temp; -- calcylate the crc for the 16 most significant bits + elsif byteCnt = 2 then + writeContent_o <= '1'; + writeContentData <= dataLane(0) & dataLane(1) & crc16Current; + else + stateRB <= SEND_FRAME; -- store in the switch buffer + end if; + end if; + + + when SEND_TO_FIFO => + if byteOffset = 0 then -- using byteOffset as a counter + byteOffset <= 1; + writeContent_o <= '1'; + writeContentData <= dataLane(0) & dataLane(1) & dataLane(2) & dataLane(3); + elsif byteOffset = 1 then -- using byteOffset as a counter + byteOffset <= 2; + writeContent_o <= '0'; + crc16Current <= crc16Next; -- calcylate the crc + elsif byteOffset = 2 then + byteOffset <= 3; + writeContent_o <= '1'; + writeContentData <= dataLane(4) & dataLane(5) & dataLane(6) & dataLane(7); + elsif byteOffset = 3 then + crc16Current <= crc16Next; -- calcylate the crc + writeContent_o <= '0'; + byteOffset <= 0; + stateRB <= nextStateRB; + dataLane <= (others =>(others => '0')); + end if; + + when READ_FROM_FIFO => + if (endianMsb = '1') then + if (readContentEnd_i = '0') then + endianMsb <= '0'; + dataLane(0 to 3) <= (readContentData_i(31 downto 24), readContentData_i(23 downto 16), + readContentData_i(15 downto 8), readContentData_i(7 downto 0)); + else + wbStb <= '0'; + wbWe_o <= '0'; + byteOffset <= 0; + readContent_o <= '0'; + writeFrameAbort_o <= '1'; -- over write the frame with an error frame + errorCode <= BERR_FRAME_SIZE; + stateRB <= SEND_ERROR; +-- stateRB <= IDLE; + end if; + else + endianMsb <= '1'; + readContent_o <= '0'; + dataLane(4 to 7) <= (readContentData_i(31 downto 24), readContentData_i(23 downto 16), + readContentData_i(15 downto 8), readContentData_i(7 downto 0)); + if ready = '1' then + stateRB <= nextStateRB; + else + stateRB <= WRITE_TO_WB; + end if; + end if; + + when WRITE_TO_WB => + if wbStb = '0' then + wbStb <= '1'; + wbWe_o <= '1'; + byteCnt <= 1; + byteOffset <= byteOffset + 1; -- increase number of counted byte + tempAddr <= tempAddr + 1; -- increase the memory sddress address + wbAdr_o <= tempAddr; + wbData_o <= dataLane(byteOffset); + else + if wbAck_i = '1' then + timeOutCnt <= (others => '0'); -- reset the time out conter + if wbErr_i = '0' then -- check the peripherals error signal + if byteCnt < numberOfByte then + tempAddr <= tempAddr + 1; -- increase the memory sddress address + wbAdr_o <= tempAddr; + wbData_o <= dataLane(byteOffset); + byteCnt <= byteCnt + 1; -- increase number of counted byte + if byteOffset < 7 then + if (byteCnt + headLen = 79) then -- check for the CRC-byte position 80 in the frame + byteOffset <= byteOffset + 3; + else + byteOffset <= byteOffset + 1; + end if; + else + if (byteCnt + headLen = 79) then -- check for the CRC-byte position 80 in the frame + byteOffset <= 2; + else + byteOffset <= 0; + end if; + if byteCnt < numberOfByte - 1 then + readContent_o <= '1'; + stateRB <= READ_FROM_FIFO; + end if; + end if; + else -- no more data to send to the peripherals + wbStb <= '0'; + wbWe_o <= '0'; + ready <= '1'; + stateRB <= SEND_FRAME; + end if; + else -- if the peripheral generates an error, send an error Response + wbStb <= '0'; + wbWe_o <= '0'; + byteOffset <= 0; + writeFrameAbort_o <= '1'; -- over write the frame with an error frame + errorCode <= wbData_i; + stateRB <= SEND_ERROR; + end if; + else +-- if readContentEnd_i = '1' then -- when unvalid data in the switch buffer +-- wbStb <= '0'; +-- wbWe_o <= '0'; +-- readFrame_o <= '1'; +-- byteOffset <= 0; +-- writeFrameAbort_o <= '1'; -- over write the frame with an error frame +-- errorCode <= BERR_FRAME_SIZE; -- more data content is expected, Frame size error +-- stateRB <= SEND_ERROR; +-- else + if timeOutCnt(13) = '1' then -- when waiting more than 1 ms for response from the device + wbStb <= '0'; + wbWe_o <= '0'; + readFrame_o <= '1'; + byteOffset <= 0; + writeFrameAbort_o <= '1'; -- over write the frame with an error frame + errorCode <= BERR_NOT_RESPONSE; + stateRB <= SEND_ERROR; + else + timeOutCnt <= timeOutCnt + 1; + end if; +-- end if; + end if; + end if; + + when SEND_ERROR => -- Generate a Response Class, an error pakage ftype=13, ttype=8, status="1111" + readFrame_o <= '0'; + writeFrameAbort_o <= '0'; + byteOffset <= byteOffset + 1; + if byteOffset = 0 then + writeContent_o <= '1'; -- start write to the buffer + crc16Current <= (others => '1'); + writeContentData <= "00000000" & "00" & "01" & "1101" & sourceId; + elsif byteOffset = 1 then + writeContentData <= baseDeviceId & "1000" & "1111" & tid; + crc16Current <= crc16Next; -- first frame's CRC + elsif byteOffset = 2 then + writeContentData <= errorCode & x"000000"; + crc16Current <= crc16Next; -- second frame's CRC + elsif byteOffset = 3 then + writeContentData <= x"00000000"; + crc16Current <= crc16Next; -- third frame's CRC + elsif byteOffset = 4 then + writeContentData <= crc16Next & X"0000"; -- write the CRC field + else + writeContent_o <= '0'; + writeFrame_o <= '1'; + readFrame_o <= '1'; + stateRB <= WAIT_IDLE; + end if; + + when SEND_FRAME => + if (ftype = FTYPE_WRITE_CLASS) and (ttype = TTYPE_NWRITE_TRANSACTION) and (tt = "01") then -- check what type of pakage we got + readFrame_o <= '1'; + elsif (ftype = FTYPE_REQUEST_CLASS) and (ttype = TTYPE_NREAD_TRANSACTION) and (tt = "01") then -- write payload to the buffer is done + readFrame_o <= '1'; + writeFrame_o <= '1'; + else -- the operation was not valid + readFrame_o <= '1'; + writeFrame_o <= '1'; + end if; + stateRB <= WAIT_IDLE; + + when WAIT_IDLE => + readFrame_o <= '0'; + writeFrame_o <= '0'; + readContent_o <= '0'; -- this line is to make sure that the CRC is complete read + stateRB <= IDLE; + + when others => + stateRB <= IDLE; + + end case; + + end if; + + end process; + + ----------------------------------------------------------------------------- + -- Configuration memory. + ----------------------------------------------------------------------------- + memoryConfig : process(clk, areset_n) + begin + if (areset_n = '0') then + configDataRead <= (others => '0'); + baseDeviceId <= DEFAULT_BASE_DEVICE_ID; + componentTag <= (others => '0'); + hostBaseDeviceIdLocked <= '0'; + hostBaseDeviceId <= (others => '1'); + elsif (clk'event and clk = '1') then + + if (configEnable = '1') then + case (configAddress) is + when x"000000" => + -- Device Identity CAR. Read-only. + configDataRead(31 downto 16) <= DEVICE_IDENTITY; + configDataRead(15 downto 0) <= DEVICE_VENDOR_IDENTITY; + when x"000004" => + -- Device Information CAR. Read-only. + configDataRead(31 downto 0) <= DEVICE_REV; + when x"000008" => + -- Assembly Identity CAR. Read-only. + configDataRead(31 downto 16) <= ASSY_IDENTITY; + configDataRead(15 downto 0) <= ASSY_VENDOR_IDENTITY; + when x"00000c" => + -- Assembly Informaiton CAR. Read-only. + -- Extended features pointer to "0000". + configDataRead(31 downto 16) <= ASSY_REV; + configDataRead(15 downto 0) <= x"0000"; + when x"000010" => + -- Processing Element Features CAR. Read-only. + -- Bridge(31), Memory(30), Processor(29), Switch(28). + configDataRead(31) <= '1'; + configDataRead(30 downto 4) <= (others => '0'); + configDataRead(3) <= '1'; -- support 16 bits common transport large system + configDataRead(2 downto 0) <= "001"; -- support 34 bits address + when x"000018" => + -- Source Operations CAR. Read-only. + configDataRead(31 downto 0) <= (others => '0'); + when x"00001C" => + -- Destination Operations CAR. Read-only. + configDataRead(31 downto 16) <= (others => '0'); + configDataRead(15) <= '1'; + configDataRead(14) <= '1'; + configDataRead(13 downto 0) <= (others => '0'); + when x"00004C" => + -- Processing Element Logical Layer Control CSR. + configDataRead(31 downto 3) <= (others => '0'); + configDataRead(2 downto 0) <= "001"; -- support 34 bits address + when x"000060" => + -- Base Device ID CSR. + -- Only valid for end point devices. + if (configWrite = '1') then + baseDeviceId <= configDataWrite(15 downto 0); + else + configDataRead(15 downto 0) <= baseDeviceId; + end if; + when x"000068" => + -- Host Base Device ID Lock CSR. + if (configWrite = '1') then + -- Check if this field has been written before. + if (hostBaseDeviceIdLocked = '0') then + -- The field has not been written. + -- Lock the field and set the host base device id. + hostBaseDeviceIdLocked <= '1'; + hostBaseDeviceId <= configDataWrite(15 downto 0); + else + -- The field has been written. + -- Check if the written data is the same as the stored. + if (hostBaseDeviceId = configDataWrite(15 downto 0)) then + -- Same as stored, reset the value to its initial value. + hostBaseDeviceIdLocked <= '0'; + hostBaseDeviceId <= (others => '1'); + else + -- Not writing the same as the stored value. + -- Ignore the write. + end if; + end if; + else + configDataRead(31 downto 16) <= (others => '0'); + configDataRead(15 downto 0) <= hostBaseDeviceId; + end if; + when x"00006C" => + -- Component TAG CSR. + if (configWrite = '1') then + componentTag <= configDataWrite; + else + configDataRead <= componentTag; + end if; + + when others => + configDataRead <= (others => '0'); + end case; + else + -- Config memory not enabled. + end if; + end if; + end process; + + ----------------------------------------------------------------------------- + -- findInPayload + -- find out number of the bytes and first byte's position in the payload. + ----------------------------------------------------------------------------- + findInPayload: 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; + end case; + end process; + +end architecture;
2.0.0-alpha/rtl/vhdl/RioWbBridge.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: 2.0.0-alpha/rtl/vhdl/RioCommon.vhd =================================================================== --- 2.0.0-alpha/rtl/vhdl/RioCommon.vhd (nonexistent) +++ 2.0.0-alpha/rtl/vhdl/RioCommon.vhd (revision 23) @@ -0,0 +1,1078 @@ +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- Description +-- Contains commonly used types, functions, procedures and entities used in +-- the RapidIO IP library project. +-- +-- To Do: +-- - +-- +-- Author(s): +-- - Magnus Rosenius, magro732@opencores.org +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------- + + +------------------------------------------------------------------------------- +-- RioCommon library. +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.math_real.all; +use std.textio.all; + + +------------------------------------------------------------------------------- +-- RioCommon package description. +------------------------------------------------------------------------------- +package rio_common is + ----------------------------------------------------------------------------- + -- Commonly used types. + ----------------------------------------------------------------------------- + type Array1 is array (natural range <>) of + std_logic; + type Array2 is array (natural range <>) of + std_logic_vector(1 downto 0); + type Array3 is array (natural range <>) of + std_logic_vector(2 downto 0); + type Array4 is array (natural range <>) of + std_logic_vector(3 downto 0); + type Array5 is array (natural range <>) of + std_logic_vector(4 downto 0); + type Array8 is array (natural range <>) of + std_logic_vector(7 downto 0); + type Array9 is array (natural range <>) of + std_logic_vector(8 downto 0); + type Array10 is array (natural range <>) of + std_logic_vector(9 downto 0); + type Array16 is array (natural range <>) of + std_logic_vector(15 downto 0); + type Array32 is array (natural range <>) of + std_logic_vector(31 downto 0); + type Array34 is array (natural range <>) of + std_logic_vector(33 downto 0); + + ----------------------------------------------------------------------------- + -- Commonly used constants. + ----------------------------------------------------------------------------- + + -- Symbol types between the serial and the PCS layer. + constant SYMBOL_IDLE : std_logic_vector(1 downto 0) := "00"; + constant SYMBOL_CONTROL : std_logic_vector(1 downto 0) := "01"; + constant SYMBOL_ERROR : std_logic_vector(1 downto 0) := "10"; + constant SYMBOL_DATA : std_logic_vector(1 downto 0) := "11"; + + -- STYPE0 constants. + constant STYPE0_PACKET_ACCEPTED : std_logic_vector(2 downto 0) := "000"; + constant STYPE0_PACKET_RETRY : std_logic_vector(2 downto 0) := "001"; + constant STYPE0_PACKET_NOT_ACCEPTED : std_logic_vector(2 downto 0) := "010"; + constant STYPE0_RESERVED : std_logic_vector(2 downto 0) := "011"; + constant STYPE0_STATUS : std_logic_vector(2 downto 0) := "100"; + constant STYPE0_VC_STATUS : std_logic_vector(2 downto 0) := "101"; + constant STYPE0_LINK_RESPONSE : std_logic_vector(2 downto 0) := "110"; + constant STYPE0_IMPLEMENTATION_DEFINED : std_logic_vector(2 downto 0) := "111"; + + -- STYPE1 constants. + constant STYPE1_START_OF_PACKET : std_logic_vector(2 downto 0) := "000"; + constant STYPE1_STOMP : std_logic_vector(2 downto 0) := "001"; + constant STYPE1_END_OF_PACKET : std_logic_vector(2 downto 0) := "010"; + constant STYPE1_RESTART_FROM_RETRY : std_logic_vector(2 downto 0) := "011"; + constant STYPE1_LINK_REQUEST : std_logic_vector(2 downto 0) := "100"; + constant STYPE1_MULTICAST_EVENT : std_logic_vector(2 downto 0) := "101"; + constant STYPE1_RESERVED : std_logic_vector(2 downto 0) := "110"; + constant STYPE1_NOP : std_logic_vector(2 downto 0) := "111"; + + -- FTYPE constants. + constant FTYPE_REQUEST_CLASS : std_logic_vector(3 downto 0) := "0010"; + constant FTYPE_WRITE_CLASS : std_logic_vector(3 downto 0) := "0101"; + constant FTYPE_STREAMING_WRITE_CLASS : std_logic_vector(3 downto 0) := "0110"; + constant FTYPE_MAINTENANCE_CLASS : std_logic_vector(3 downto 0) := "1000"; + constant FTYPE_RESPONSE_CLASS : std_logic_vector(3 downto 0) := "1101"; + constant FTYPE_DOORBELL_CLASS : std_logic_vector(3 downto 0) := "1010"; + constant FTYPE_MESSAGE_CLASS : std_logic_vector(3 downto 0) := "0010"; + + -- TTYPE Constants + constant TTYPE_MAINTENANCE_READ_REQUEST : std_logic_vector(3 downto 0) := "0000"; + constant TTYPE_MAINTENANCE_WRITE_REQUEST : std_logic_vector(3 downto 0) := "0001"; + constant TTYPE_MAINTENANCE_READ_RESPONSE : std_logic_vector(3 downto 0) := "0010"; + constant TTYPE_MAINTENANCE_WRITE_RESPONSE : std_logic_vector(3 downto 0) := "0011"; + constant TTYPE_NREAD_TRANSACTION : std_logic_vector(3 downto 0) := "0100"; + constant TTYPE_NWRITE_TRANSACTION : std_logic_vector(3 downto 0) := "0100"; + + constant LINK_REQUEST_CMD_RESET_DEVICE : std_logic_vector(2 downto 0) := "011"; + constant LINK_REQUEST_CMD_INPUT_STATUS : std_logic_vector(2 downto 0) := "100"; + + constant PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID : std_logic_vector(4 downto 0) := "00001"; + constant PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC : std_logic_vector(4 downto 0) := "00010"; + constant PACKET_NOT_ACCEPTED_CAUSE_NON_MAINTENANCE_STOPPED : std_logic_vector(4 downto 0) := "00011"; + constant PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC : std_logic_vector(4 downto 0) := "00100"; + constant PACKET_NOT_ACCEPTED_CAUSE_INVALID_CHARACTER : std_logic_vector(4 downto 0) := "00101"; + constant PACKET_NOT_ACCEPTED_CAUSE_NO_RESOURCES : std_logic_vector(4 downto 0) := "00110"; + constant PACKET_NOT_ACCEPTED_CAUSE_LOSS_DESCRAMBLER : std_logic_vector(4 downto 0) := "00111"; + constant PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR : std_logic_vector(4 downto 0) := "11111"; + + ----------------------------------------------------------------------------- + -- Types used in simulations. + ----------------------------------------------------------------------------- + type ByteArray is array (natural range <>) of + std_logic_vector(7 downto 0); + type HalfwordArray is array (natural range <>) of + std_logic_vector(15 downto 0); + type WordArray is array (natural range <>) of + std_logic_vector(31 downto 0); + type DoublewordArray is array (natural range <>) of + std_logic_vector(63 downto 0); + + -- Type defining a RapidIO frame. + type RioFrame is record + length : natural range 0 to 69; + payload : WordArray(0 to 68); + end record; + type RioFrameArray is array (natural range <>) of RioFrame; + + -- Type defining a RapidIO payload. + type RioPayload is record + length : natural range 0 to 133; + data : HalfwordArray(0 to 132); + end record; + + ----------------------------------------------------------------------------- + -- Crc5 calculation function. + -- ITU, polynom=0x15. + ----------------------------------------------------------------------------- + function Crc5(constant data : in std_logic_vector(18 downto 0); + constant crc : in std_logic_vector(4 downto 0)) + return std_logic_vector; + + --------------------------------------------------------------------------- + -- Create a RapidIO physical layer control symbol. + --------------------------------------------------------------------------- + function RioControlSymbolCreate( + constant stype0 : in std_logic_vector(2 downto 0); + constant parameter0 : in std_logic_vector(4 downto 0); + constant parameter1 : in std_logic_vector(4 downto 0); + constant stype1 : in std_logic_vector(2 downto 0); + constant cmd : in std_logic_vector(2 downto 0)) + return std_logic_vector; + + ----------------------------------------------------------------------------- + -- Crc16 calculation function. + -- CITT, polynom=0x1021. + ----------------------------------------------------------------------------- + function Crc16(constant data : in std_logic_vector(15 downto 0); + constant crc : in std_logic_vector(15 downto 0)) + return std_logic_vector; + + --------------------------------------------------------------------------- + -- Create a randomly initialized data array. + --------------------------------------------------------------------------- + procedure CreateRandomPayload( + variable payload : out HalfwordArray(0 to 132); + variable seed1 : inout positive; + variable seed2 : inout positive); + procedure CreateRandomPayload( + variable payload : out DoublewordArray(0 to 31); + variable seed1 : inout positive; + variable seed2 : inout positive); + + --------------------------------------------------------------------------- + -- Create a generic RapidIO frame. + --------------------------------------------------------------------------- + function RioFrameCreate( + constant ackId : in std_logic_vector(4 downto 0); + constant vc : in std_logic; + constant crf : in std_logic; + constant prio : in std_logic_vector(1 downto 0); + constant tt : in std_logic_vector(1 downto 0); + constant ftype : in std_logic_vector(3 downto 0); + constant sourceId : in std_logic_vector(15 downto 0); + constant destId : in std_logic_vector(15 downto 0); + constant payload : in RioPayload) + return RioFrame; + + --------------------------------------------------------------------------- + -- Create a NWRITE RapidIO frame. + --------------------------------------------------------------------------- + function RioNwrite( + constant wrsize : in std_logic_vector(3 downto 0); + constant tid : in std_logic_vector(7 downto 0); + constant address : in std_logic_vector(28 downto 0); + constant wdptr : in std_logic; + constant xamsbs : in std_logic_vector(1 downto 0); + constant dataLength : in natural range 1 to 32; + constant data : in DoublewordArray(0 to 31)) + return RioPayload; + + --------------------------------------------------------------------------- + -- Create a NREAD RapidIO frame. + --------------------------------------------------------------------------- + function RioNread( + constant rdsize : in std_logic_vector(3 downto 0); + constant tid : in std_logic_vector(7 downto 0); + constant address : in std_logic_vector(28 downto 0); + constant wdptr : in std_logic; + constant xamsbs : in std_logic_vector(1 downto 0)) + return RioPayload; + + --------------------------------------------------------------------------- + -- Create a RESPONSE RapidIO frame. + --------------------------------------------------------------------------- + function RioResponse( + constant status : in std_logic_vector(3 downto 0); + constant tid : in std_logic_vector(7 downto 0); + constant dataLength : in natural range 0 to 32; + constant data : in DoublewordArray(0 to 31)) + return RioPayload; + + --------------------------------------------------------------------------- + -- Create a Maintenance RapidIO frame. + --------------------------------------------------------------------------- + function RioMaintenance( + constant transaction : in std_logic_vector(3 downto 0); + constant size : in std_logic_vector(3 downto 0); + constant tid : in std_logic_vector(7 downto 0); + constant hopCount : in std_logic_vector(7 downto 0); + constant configOffset : in std_logic_vector(20 downto 0); + constant wdptr : in std_logic; + constant dataLength : in natural range 0 to 8; + constant data : in DoublewordArray(0 to 7)) + return RioPayload; + + ----------------------------------------------------------------------------- + -- Function to convert a std_logic_vector to a string. + ----------------------------------------------------------------------------- + function byteToString(constant byte : std_logic_vector(7 downto 0)) + return string; + + --------------------------------------------------------------------------- + -- Procedure to print to report file and output + --------------------------------------------------------------------------- + procedure PrintR( constant str : string ); + + --------------------------------------------------------------------------- + -- Procedure to print to spec file + --------------------------------------------------------------------------- + procedure PrintS( constant str : string ); + + --------------------------------------------------------------------------- + -- Procedure to Assert Expression + --------------------------------------------------------------------------- + procedure AssertE( constant exp: boolean; constant str : string ); + + --------------------------------------------------------------------------- + -- Procedure to Print Error + --------------------------------------------------------------------------- + procedure PrintE( constant str : string ); + + --------------------------------------------------------------------------- + -- Procedure to end a test. + --------------------------------------------------------------------------- + procedure TestEnd; + +end package; + +------------------------------------------------------------------------------- +-- RioCommon package body description. +------------------------------------------------------------------------------- +package body rio_common is + ----------------------------------------------------------------------------- + -- Crc5 calculation function. + -- ITU, polynom=0x15. + ----------------------------------------------------------------------------- + function Crc5(constant data : in std_logic_vector(18 downto 0); + constant crc : in std_logic_vector(4 downto 0)) + return std_logic_vector is + type crcTableType is array (0 to 31) of std_logic_vector(7 downto 0); + constant crcTable : crcTableType := ( + x"00", x"15", x"1f", x"0a", x"0b", x"1e", x"14", x"01", + x"16", x"03", x"09", x"1c", x"1d", x"08", x"02", x"17", + x"19", x"0c", x"06", x"13", x"12", x"07", x"0d", x"18", + x"0f", x"1a", x"10", x"05", x"04", x"11", x"1b", x"0e" ); + variable index : natural range 0 to 31; + variable result : std_logic_vector(4 downto 0); + begin + result := crc; + index := to_integer(unsigned(data(18 downto 14) xor result)); + result := crcTable(index)(4 downto 0); + index := to_integer(unsigned(data(13 downto 9) xor result)); + result := crcTable(index)(4 downto 0); + index := to_integer(unsigned(data(8 downto 4) xor result)); + result := crcTable(index)(4 downto 0); + index := to_integer(unsigned((data(3 downto 0) & '0') xor result)); + return crcTable(index)(4 downto 0); + end Crc5; + + --------------------------------------------------------------------------- + -- Create a RapidIO physical layer control symbol. + --------------------------------------------------------------------------- + function RioControlSymbolCreate( + constant stype0 : in std_logic_vector(2 downto 0); + constant parameter0 : in std_logic_vector(4 downto 0); + constant parameter1 : in std_logic_vector(4 downto 0); + constant stype1 : in std_logic_vector(2 downto 0); + constant cmd : in std_logic_vector(2 downto 0)) + return std_logic_vector is + variable returnValue : std_logic_vector(31 downto 0); + variable symbolData : std_logic_vector(18 downto 0); + begin + symbolData(18 downto 16) := stype0; + symbolData(15 downto 11) := parameter0; + symbolData(10 downto 6) := parameter1; + symbolData(5 downto 3) := stype1; + symbolData(2 downto 0) := cmd; + + returnValue(31 downto 13) := symbolData; + returnValue(12 downto 8) := Crc5(symbolData, "11111"); + returnValue(7 downto 0) := x"00"; + + return returnValue; + end function; + + ----------------------------------------------------------------------------- + -- Crc16 calculation function. + -- CITT, polynom=0x1021. + ----------------------------------------------------------------------------- + function Crc16(constant data : in std_logic_vector(15 downto 0); + constant crc : in std_logic_vector(15 downto 0)) + return std_logic_vector is + type crcTableType is array (0 to 255) of std_logic_vector(15 downto 0); + constant crcTable : crcTableType := ( + x"0000", x"1021", x"2042", x"3063", x"4084", x"50a5", x"60c6", x"70e7", + x"8108", x"9129", x"a14a", x"b16b", x"c18c", x"d1ad", x"e1ce", x"f1ef", + x"1231", x"0210", x"3273", x"2252", x"52b5", x"4294", x"72f7", x"62d6", + x"9339", x"8318", x"b37b", x"a35a", x"d3bd", x"c39c", x"f3ff", x"e3de", + x"2462", x"3443", x"0420", x"1401", x"64e6", x"74c7", x"44a4", x"5485", + x"a56a", x"b54b", x"8528", x"9509", x"e5ee", x"f5cf", x"c5ac", x"d58d", + x"3653", x"2672", x"1611", x"0630", x"76d7", x"66f6", x"5695", x"46b4", + x"b75b", x"a77a", x"9719", x"8738", x"f7df", x"e7fe", x"d79d", x"c7bc", + x"48c4", x"58e5", x"6886", x"78a7", x"0840", x"1861", x"2802", x"3823", + x"c9cc", x"d9ed", x"e98e", x"f9af", x"8948", x"9969", x"a90a", x"b92b", + x"5af5", x"4ad4", x"7ab7", x"6a96", x"1a71", x"0a50", x"3a33", x"2a12", + x"dbfd", x"cbdc", x"fbbf", x"eb9e", x"9b79", x"8b58", x"bb3b", x"ab1a", + x"6ca6", x"7c87", x"4ce4", x"5cc5", x"2c22", x"3c03", x"0c60", x"1c41", + x"edae", x"fd8f", x"cdec", x"ddcd", x"ad2a", x"bd0b", x"8d68", x"9d49", + x"7e97", x"6eb6", x"5ed5", x"4ef4", x"3e13", x"2e32", x"1e51", x"0e70", + x"ff9f", x"efbe", x"dfdd", x"cffc", x"bf1b", x"af3a", x"9f59", x"8f78", + x"9188", x"81a9", x"b1ca", x"a1eb", x"d10c", x"c12d", x"f14e", x"e16f", + x"1080", x"00a1", x"30c2", x"20e3", x"5004", x"4025", x"7046", x"6067", + x"83b9", x"9398", x"a3fb", x"b3da", x"c33d", x"d31c", x"e37f", x"f35e", + x"02b1", x"1290", x"22f3", x"32d2", x"4235", x"5214", x"6277", x"7256", + x"b5ea", x"a5cb", x"95a8", x"8589", x"f56e", x"e54f", x"d52c", x"c50d", + x"34e2", x"24c3", x"14a0", x"0481", x"7466", x"6447", x"5424", x"4405", + x"a7db", x"b7fa", x"8799", x"97b8", x"e75f", x"f77e", x"c71d", x"d73c", + x"26d3", x"36f2", x"0691", x"16b0", x"6657", x"7676", x"4615", x"5634", + x"d94c", x"c96d", x"f90e", x"e92f", x"99c8", x"89e9", x"b98a", x"a9ab", + x"5844", x"4865", x"7806", x"6827", x"18c0", x"08e1", x"3882", x"28a3", + x"cb7d", x"db5c", x"eb3f", x"fb1e", x"8bf9", x"9bd8", x"abbb", x"bb9a", + x"4a75", x"5a54", x"6a37", x"7a16", x"0af1", x"1ad0", x"2ab3", x"3a92", + x"fd2e", x"ed0f", x"dd6c", x"cd4d", x"bdaa", x"ad8b", x"9de8", x"8dc9", + x"7c26", x"6c07", x"5c64", x"4c45", x"3ca2", x"2c83", x"1ce0", x"0cc1", + x"ef1f", x"ff3e", x"cf5d", x"df7c", x"af9b", x"bfba", x"8fd9", x"9ff8", + x"6e17", x"7e36", x"4e55", x"5e74", x"2e93", x"3eb2", x"0ed1", x"1ef0" ); + variable index : natural range 0 to 255; + variable result : std_logic_vector(15 downto 0); + begin + result := crc; + index := to_integer(unsigned(data(15 downto 8) xor result(15 downto 8))); + result := crcTable(index) xor (result(7 downto 0) & x"00"); + index := to_integer(unsigned(data(7 downto 0) xor result(15 downto 8))); + result := crcTable(index) xor (result(7 downto 0) & x"00"); + return result; + end Crc16; + + --------------------------------------------------------------------------- + -- Create a randomly initialized data array. + --------------------------------------------------------------------------- + procedure CreateRandomPayload( + variable payload : out HalfwordArray(0 to 132); + variable seed1 : inout positive; + variable seed2 : inout positive) is + variable rand: real; + variable int_rand: integer; + variable stim: std_logic_vector(7 downto 0); + begin + for i in payload'range loop + uniform(seed1, seed2, rand); + int_rand := integer(trunc(rand*256.0)); + payload(i)(7 downto 0) := std_logic_vector(to_unsigned(int_rand, 8)); + uniform(seed1, seed2, rand); + int_rand := integer(trunc(rand*256.0)); + payload(i)(15 downto 8) := std_logic_vector(to_unsigned(int_rand, 8)); + end loop; + end procedure; + + procedure CreateRandomPayload( + variable payload : out DoublewordArray(0 to 31); + variable seed1 : inout positive; + variable seed2 : inout positive) is + variable rand: real; + variable int_rand: integer; + variable stim: std_logic_vector(7 downto 0); + begin + for i in payload'range loop + uniform(seed1, seed2, rand); + int_rand := integer(trunc(rand*256.0)); + payload(i)(7 downto 0) := std_logic_vector(to_unsigned(int_rand, 8)); + uniform(seed1, seed2, rand); + int_rand := integer(trunc(rand*256.0)); + payload(i)(15 downto 8) := std_logic_vector(to_unsigned(int_rand, 8)); + uniform(seed1, seed2, rand); + int_rand := integer(trunc(rand*256.0)); + payload(i)(23 downto 16) := std_logic_vector(to_unsigned(int_rand, 8)); + uniform(seed1, seed2, rand); + int_rand := integer(trunc(rand*256.0)); + payload(i)(31 downto 24) := std_logic_vector(to_unsigned(int_rand, 8)); + uniform(seed1, seed2, rand); + int_rand := integer(trunc(rand*256.0)); + payload(i)(39 downto 32) := std_logic_vector(to_unsigned(int_rand, 8)); + uniform(seed1, seed2, rand); + int_rand := integer(trunc(rand*256.0)); + payload(i)(47 downto 40) := std_logic_vector(to_unsigned(int_rand, 8)); + uniform(seed1, seed2, rand); + int_rand := integer(trunc(rand*256.0)); + payload(i)(55 downto 48) := std_logic_vector(to_unsigned(int_rand, 8)); + uniform(seed1, seed2, rand); + int_rand := integer(trunc(rand*256.0)); + payload(i)(63 downto 56) := std_logic_vector(to_unsigned(int_rand, 8)); + end loop; + end procedure; + --------------------------------------------------------------------------- + -- Create a generic RapidIO frame. + --------------------------------------------------------------------------- + function RioFrameCreate( + constant ackId : in std_logic_vector(4 downto 0); + constant vc : in std_logic; + constant crf : in std_logic; + constant prio : in std_logic_vector(1 downto 0); + constant tt : in std_logic_vector(1 downto 0); + constant ftype : in std_logic_vector(3 downto 0); + constant sourceId : in std_logic_vector(15 downto 0); + constant destId : in std_logic_vector(15 downto 0); + constant payload : in RioPayload) return RioFrame is + variable frame : RioFrame; + variable result : HalfwordArray(0 to 137); + variable crc : std_logic_vector(15 downto 0) := x"ffff"; + begin + -- Add the header and addresses. + result(0) := ackId & "0" & vc & crf & prio & tt & ftype; + result(1) := destId; + result(2) := sourceId; + + -- Update the calculated CRC with the header contents. + crc := Crc16("00000" & result(0)(10 downto 0), crc); + crc := Crc16(result(1), crc); + crc := Crc16(result(2), crc); + + -- Check if a single CRC should be added or two. + if (payload.length <= 37) then + -- Single CRC. + for i in 0 to payload.length-1 loop + result(i+3) := payload.data(i); + crc := Crc16(payload.data(i), crc); + end loop; + result(payload.length+3) := crc; + + -- Check if paddning is needed to make the payload even 32-bit. + if ((payload.length mod 2) = 1) then + result(payload.length+4) := x"0000"; + frame.length := (payload.length+5) / 2; + else + frame.length := (payload.length+4) / 2; + end if; + else + -- Double CRC. + for i in 0 to 36 loop + result(i+3) := payload.data(i); + crc := Crc16(payload.data(i), crc); + end loop; + + -- Add in-the-middle crc. + result(40) := crc; + crc := Crc16(crc, crc); + + for i in 37 to payload.length-1 loop + result(i+4) := payload.data(i); + crc := Crc16(payload.data(i), crc); + end loop; + result(payload.length+4) := crc; + + -- Check if paddning is needed to make the payload even 32-bit. + if ((payload.length mod 2) = 0) then + result(payload.length+5) := x"0000"; + frame.length := (payload.length+6) / 2; + else + frame.length := (payload.length+5) / 2; + end if; + end if; + + -- Update the result length. + for i in 0 to frame.length-1 loop + frame.payload(i) := result(2*i) & result(2*i+1); + end loop; + + return frame; + end function; + + ----------------------------------------------------------------------------- + -- + ----------------------------------------------------------------------------- + function RioNwrite( + constant wrsize : in std_logic_vector(3 downto 0); + constant tid : in std_logic_vector(7 downto 0); + constant address : in std_logic_vector(28 downto 0); + constant wdptr : in std_logic; + constant xamsbs : in std_logic_vector(1 downto 0); + constant dataLength : in natural range 1 to 32; + constant data : in DoublewordArray(0 to 31)) + return RioPayload is + variable payload : RioPayload; + begin + payload.data(0)(15 downto 12) := "0100"; + payload.data(0)(11 downto 8) := wrsize; + payload.data(0)(7 downto 0) := tid; + + payload.data(1) := address(28 downto 13); + + payload.data(2)(15 downto 3) := address(12 downto 0); + payload.data(2)(2) := wdptr; + payload.data(2)(1 downto 0) := xamsbs; + + for i in 0 to dataLength-1 loop + payload.data(3+4*i) := data(i)(63 downto 48); + payload.data(4+4*i) := data(i)(47 downto 32); + payload.data(5+4*i) := data(i)(31 downto 16); + payload.data(6+4*i) := data(i)(15 downto 0); + end loop; + + payload.length := 3 + 4*dataLength; + + return payload; + end function; + + ----------------------------------------------------------------------------- + -- + ----------------------------------------------------------------------------- + function RioNread( + constant rdsize : in std_logic_vector(3 downto 0); + constant tid : in std_logic_vector(7 downto 0); + constant address : in std_logic_vector(28 downto 0); + constant wdptr : in std_logic; + constant xamsbs : in std_logic_vector(1 downto 0)) + return RioPayload is + variable payload : RioPayload; + begin + payload.data(0)(15 downto 12) := "0100"; + payload.data(0)(11 downto 8) := rdsize; + payload.data(0)(7 downto 0) := tid; + + payload.data(1) := address(28 downto 13); + + payload.data(2)(15 downto 3) := address(12 downto 0); + payload.data(2)(2) := wdptr; + payload.data(2)(1 downto 0) := xamsbs; + + payload.length := 3; + + return payload; + end function; + + --------------------------------------------------------------------------- + -- Create a RESPONSE RapidIO frame. + --------------------------------------------------------------------------- + function RioResponse( + constant status : in std_logic_vector(3 downto 0); + constant tid : in std_logic_vector(7 downto 0); + constant dataLength : in natural range 0 to 32; + constant data : in DoublewordArray(0 to 31)) + return RioPayload is + variable payload : RioPayload; + begin + payload.data(0)(11 downto 8) := status; + payload.data(0)(7 downto 0) := tid; + + if (dataLength = 0) then + payload.data(0)(15 downto 12) := "0000"; + payload.length := 1; + else + payload.data(0)(15 downto 12) := "1000"; + + for i in 0 to dataLength-1 loop + payload.data(1+4*i) := data(i)(63 downto 48); + payload.data(2+4*i) := data(i)(47 downto 32); + payload.data(3+4*i) := data(i)(31 downto 16); + payload.data(4+4*i) := data(i)(15 downto 0); + end loop; + + payload.length := 1 + 4*dataLength; + end if; + + return payload; + end function; + + --------------------------------------------------------------------------- + -- Create a Maintenance RapidIO frame. + --------------------------------------------------------------------------- + function RioMaintenance( + constant transaction : in std_logic_vector(3 downto 0); + constant size : in std_logic_vector(3 downto 0); + constant tid : in std_logic_vector(7 downto 0); + constant hopCount : in std_logic_vector(7 downto 0); + constant configOffset : in std_logic_vector(20 downto 0); + constant wdptr : in std_logic; + constant dataLength : in natural range 0 to 8; + constant data : in DoublewordArray(0 to 7)) + return RioPayload is + variable payload : RioPayload; + begin + payload.data(0)(15 downto 12) := transaction; + payload.data(0)(11 downto 8) := size; + payload.data(0)(7 downto 0) := tid; + + payload.data(1)(15 downto 8) := hopCount; + payload.data(1)(7 downto 0) := configOffset(20 downto 13); + + payload.data(2)(15 downto 3) := configOffset(12 downto 0); + payload.data(2)(2) := wdptr; + payload.data(2)(1 downto 0) := "00"; + + if (dataLength = 0) then + payload.length := 3; + else + for i in 0 to dataLength-1 loop + payload.data(3+4*i) := data(i)(63 downto 48); + payload.data(4+4*i) := data(i)(47 downto 32); + payload.data(5+4*i) := data(i)(31 downto 16); + payload.data(6+4*i) := data(i)(15 downto 0); + end loop; + + payload.length := 3 + 4*dataLength; + end if; + + return payload; + end function; + + ----------------------------------------------------------------------------- + -- Function to convert a std_logic_vector to a string. + ----------------------------------------------------------------------------- + function byteToString(constant byte : std_logic_vector(7 downto 0)) + return string is + constant table : string(1 to 16) := "0123456789abcdef"; + variable returnValue : string(1 to 2); + begin + returnValue(1) := table(to_integer(unsigned(byte(7 downto 4))) + 1); + returnValue(2) := table(to_integer(unsigned(byte(3 downto 0))) + 1); + return returnValue; + end function; + + --------------------------------------------------------------------------- + -- Procedure to print test report + --------------------------------------------------------------------------- + procedure PrintR( constant str : string ) is + file reportFile : text; + variable reportLine, outputLine : line; + variable fStatus: FILE_OPEN_STATUS; + begin + --Write report note to wave/transcript window + report str severity NOTE; + end PrintR; + + --------------------------------------------------------------------------- + -- Procedure to print test spec + --------------------------------------------------------------------------- + procedure PrintS( constant str : string ) is + file specFile : text; + variable specLine, outputLine : line; + variable fStatus: FILE_OPEN_STATUS; + begin + --Write to spec file + file_open(fStatus, specFile, "testspec.txt", append_mode); + write(specLine, string'(str)); + writeline (specFile, specLine); + file_close(specFile); + end PrintS; + + --------------------------------------------------------------------------- + -- Procedure to Assert Expression + --------------------------------------------------------------------------- + procedure AssertE( constant exp: boolean; constant str : string ) is + file reportFile : text; + variable reportLine, outputLine : line; + variable fStatus: FILE_OPEN_STATUS; + begin + if (not exp) then + --Write to STD_OUTPUT + report(str) severity error; + else + PrintR("Status: Passed"); + PrintS("Status: Passed"); + end if; + end AssertE; + + --------------------------------------------------------------------------- + -- Procedure to Print Error + --------------------------------------------------------------------------- + procedure PrintE( constant str : string ) is + file reportFile : text; + variable reportLine, outputLine : line; + variable fStatus: FILE_OPEN_STATUS; + begin + --Write to STD_OUTPUT + report str severity error; + end PrintE; + + --------------------------------------------------------------------------- + -- Procedure to end a test. + --------------------------------------------------------------------------- + procedure TestEnd is + begin + assert false report "Test complete." severity failure; + wait; + end TestEnd; + +end rio_common; + + + +------------------------------------------------------------------------------- +-- Crc16CITT +-- A CRC-16 calculator following the implementation proposed in the 2.2 +-- standard. +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; + + +------------------------------------------------------------------------------- +-- Entity for Crc16CITT. +------------------------------------------------------------------------------- +entity 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 entity; + + +------------------------------------------------------------------------------- +-- Architecture for Crc16CITT. +------------------------------------------------------------------------------- +architecture Crc16Impl of Crc16CITT is + signal d : std_logic_vector(0 to 15); + signal c : std_logic_vector(0 to 15); + signal e : std_logic_vector(0 to 15); + signal cc : std_logic_vector(0 to 15); +begin + + -- Reverse the bit vector indexes to make them the same as in the standard. + d(15) <= d_i(0); d(14) <= d_i(1); d(13) <= d_i(2); d(12) <= d_i(3); + d(11) <= d_i(4); d(10) <= d_i(5); d(9) <= d_i(6); d(8) <= d_i(7); + d(7) <= d_i(8); d(6) <= d_i(9); d(5) <= d_i(10); d(4) <= d_i(11); + d(3) <= d_i(12); d(2) <= d_i(13); d(1) <= d_i(14); d(0) <= d_i(15); + + -- Reverse the bit vector indexes to make them the same as in the standard. + c(15) <= crc_i(0); c(14) <= crc_i(1); c(13) <= crc_i(2); c(12) <= crc_i(3); + c(11) <= crc_i(4); c(10) <= crc_i(5); c(9) <= crc_i(6); c(8) <= crc_i(7); + c(7) <= crc_i(8); c(6) <= crc_i(9); c(5) <= crc_i(10); c(4) <= crc_i(11); + c(3) <= crc_i(12); c(2) <= crc_i(13); c(1) <= crc_i(14); c(0) <= crc_i(15); + + -- Calculate the resulting crc. + e <= c xor d; + cc(0) <= e(4) xor e(5) xor e(8) xor e(12); + cc(1) <= e(5) xor e(6) xor e(9) xor e(13); + cc(2) <= e(6) xor e(7) xor e(10) xor e(14); + cc(3) <= e(0) xor e(7) xor e(8) xor e(11) xor e(15); + cc(4) <= e(0) xor e(1) xor e(4) xor e(5) xor e(9); + cc(5) <= e(1) xor e(2) xor e(5) xor e(6) xor e(10); + cc(6) <= e(0) xor e(2) xor e(3) xor e(6) xor e(7) xor e(11); + cc(7) <= e(0) xor e(1) xor e(3) xor e(4) xor e(7) xor e(8) xor e(12); + cc(8) <= e(0) xor e(1) xor e(2) xor e(4) xor e(5) xor e(8) xor e(9) xor e(13); + cc(9) <= e(1) xor e(2) xor e(3) xor e(5) xor e(6) xor e(9) xor e(10) xor e(14); + cc(10) <= e(2) xor e(3) xor e(4) xor e(6) xor e(7) xor e(10) xor e(11) xor e(15); + cc(11) <= e(0) xor e(3) xor e(7) xor e(11); + cc(12) <= e(0) xor e(1) xor e(4) xor e(8) xor e(12); + cc(13) <= e(1) xor e(2) xor e(5) xor e(9) xor e(13); + cc(14) <= e(2) xor e(3) xor e(6) xor e(10) xor e(14); + cc(15) <= e(3) xor e(4) xor e(7) xor e(11) xor e(15); + + -- Reverse the bit vector indexes to make them the same as in the standard. + crc_o(15) <= cc(0); crc_o(14) <= cc(1); crc_o(13) <= cc(2); crc_o(12) <= cc(3); + crc_o(11) <= cc(4); crc_o(10) <= cc(5); crc_o(9) <= cc(6); crc_o(8) <= cc(7); + crc_o(7) <= cc(8); crc_o(6) <= cc(9); crc_o(5) <= cc(10); crc_o(4) <= cc(11); + crc_o(3) <= cc(12); crc_o(2) <= cc(13); crc_o(1) <= cc(14); crc_o(0) <= cc(15); + +end architecture; + + + +------------------------------------------------------------------------------- +-- MemoryDualPort +-- Generic synchronous memory with one read/write port and one read port. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + +------------------------------------------------------------------------------- +-- Entity for MemoryDualPort. +------------------------------------------------------------------------------- +entity MemoryDualPort is + generic( + ADDRESS_WIDTH : natural := 1; + DATA_WIDTH : natural := 1); + port( + clkA_i : in std_logic; + enableA_i : in std_logic; + writeEnableA_i : in std_logic; + addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0); + dataA_o : out std_logic_vector(DATA_WIDTH-1 downto 0); + + clkB_i : in std_logic; + enableB_i : in std_logic; + addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for MemoryDualPort. +------------------------------------------------------------------------------- +architecture MemoryDualPortImpl of MemoryDualPort is + type MemoryType is array (natural range <>) of + std_logic_vector(DATA_WIDTH-1 downto 0); + + signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1); + +begin + process(clkA_i) + begin + if (clkA_i'event and clkA_i = '1') then + if (enableA_i = '1') then + if (writeEnableA_i = '1') then + memory(to_integer(unsigned(addressA_i))) <= dataA_i; + end if; + + dataA_o <= memory(to_integer(unsigned(addressA_i))); + end if; + end if; + end process; + + process(clkB_i) + begin + if (clkB_i'event and clkB_i = '1') then + if (enableB_i = '1') then + dataB_o <= memory(to_integer(unsigned(addressB_i))); + end if; + end if; + end process; + +end architecture; + + + +------------------------------------------------------------------------------- +-- MemorySimpleDualPort +-- Generic synchronous memory with one write port and one read port. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + +------------------------------------------------------------------------------- +-- Entity for MemorySimpleDualPort. +------------------------------------------------------------------------------- +entity MemorySimpleDualPort is + generic( + ADDRESS_WIDTH : natural := 1; + DATA_WIDTH : natural := 1); + port( + clkA_i : in std_logic; + enableA_i : in std_logic; + addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0); + + clkB_i : in std_logic; + enableB_i : in std_logic; + addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for MemorySimpleDualPort. +------------------------------------------------------------------------------- +architecture MemorySimpleDualPortImpl of MemorySimpleDualPort is + type MemoryType is array (natural range <>) of + std_logic_vector(DATA_WIDTH-1 downto 0); + + signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1); + +begin + process(clkA_i) + begin + if (clkA_i'event and clkA_i = '1') then + if (enableA_i = '1') then + memory(to_integer(unsigned(addressA_i))) <= dataA_i; + end if; + end if; + end process; + + process(clkB_i) + begin + if (clkB_i'event and clkB_i = '1') then + if (enableB_i = '1') then + dataB_o <= memory(to_integer(unsigned(addressB_i))); + end if; + end if; + end process; + +end architecture; + + + +------------------------------------------------------------------------------- +-- MemorySinglePort +-- Generic synchronous memory with one read/write port. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + +------------------------------------------------------------------------------- +-- Entity for MemorySinglePort. +------------------------------------------------------------------------------- +entity 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 entity; + + +------------------------------------------------------------------------------- +-- Architecture for MemorySinglePort. +------------------------------------------------------------------------------- +architecture MemorySinglePortImpl of MemorySinglePort is + type MemoryType is array (natural range <>) of + std_logic_vector(DATA_WIDTH-1 downto 0); + + signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1); + +begin + process(clk_i) + begin + if (clk_i'event and clk_i = '1') then + if (enable_i = '1') then + if (writeEnable_i = '1') then + memory(to_integer(unsigned(address_i))) <= data_i; + end if; + + data_o <= memory(to_integer(unsigned(address_i))); + end if; + end if; + end process; + +end architecture; + + + + +------------------------------------------------------------------------------- +-- MemorySimpleDualPortAsync +-- Generic memory with one synchronous write port and one asynchronous read port. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + +------------------------------------------------------------------------------- +-- Entity for MemorySimpleDualPortAsync. +------------------------------------------------------------------------------- +entity MemorySimpleDualPortAsync is + generic( + ADDRESS_WIDTH : natural := 1; + DATA_WIDTH : natural := 1; + INIT_VALUE : std_logic := 'U'); + port( + clkA_i : in std_logic; + enableA_i : in std_logic; + addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0); + + addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for MemorySimpleDualPortAsync. +------------------------------------------------------------------------------- +architecture MemorySimpleDualPortAsyncImpl of MemorySimpleDualPortAsync is + type MemoryType is array (natural range <>) of + std_logic_vector(DATA_WIDTH-1 downto 0); + + signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1) := (others=>(others=>INIT_VALUE)); + +begin + process(clkA_i) + begin + if (clkA_i'event and clkA_i = '1') then + if (enableA_i = '1') then + memory(to_integer(unsigned(addressA_i))) <= dataA_i; + end if; + end if; + end process; + + dataB_o <= memory(to_integer(unsigned(addressB_i))); + +end architecture; + + + + +
2.0.0-alpha/rtl/vhdl/RioCommon.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: 2.0.0-alpha/rtl/vhdl/RioSwitch.vhd =================================================================== --- 2.0.0-alpha/rtl/vhdl/RioSwitch.vhd (nonexistent) +++ 2.0.0-alpha/rtl/vhdl/RioSwitch.vhd (revision 23) @@ -0,0 +1,2510 @@ +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- Description +-- Containing RapidIO packet switching functionality contained in the top +-- entity RioSwitch. +-- +-- To Do: +-- - +-- +-- Author(s): +-- - Magnus Rosenius, magro732@opencores.org +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------- + + +------------------------------------------------------------------------------- +-- RioSwitch +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + +------------------------------------------------------------------------------- +-- Entity for RioSwitch. +------------------------------------------------------------------------------- +entity RioSwitch is + generic( + SWITCH_PORTS : natural range 3 to 255 := 4; + DEVICE_IDENTITY : std_logic_vector(15 downto 0); + DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0); + DEVICE_REV : std_logic_vector(31 downto 0); + ASSY_IDENTITY : std_logic_vector(15 downto 0); + ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0); + ASSY_REV : std_logic_vector(15 downto 0)); + port( + clk : in std_logic; + areset_n : in std_logic; + + writeFrameFull_i : in Array1(SWITCH_PORTS-1 downto 0); + writeFrame_o : out Array1(SWITCH_PORTS-1 downto 0); + writeFrameAbort_o : out Array1(SWITCH_PORTS-1 downto 0); + writeContent_o : out Array1(SWITCH_PORTS-1 downto 0); + writeContentData_o : out Array32(SWITCH_PORTS-1 downto 0); + + readFrameEmpty_i : in Array1(SWITCH_PORTS-1 downto 0); + readFrame_o : out Array1(SWITCH_PORTS-1 downto 0); + readFrameRestart_o : out Array1(SWITCH_PORTS-1 downto 0); + readFrameAborted_i : in Array1(SWITCH_PORTS-1 downto 0); + readContentEmpty_i : in Array1(SWITCH_PORTS-1 downto 0); + readContent_o : out Array1(SWITCH_PORTS-1 downto 0); + readContentEnd_i : in Array1(SWITCH_PORTS-1 downto 0); + readContentData_i : in Array32(SWITCH_PORTS-1 downto 0); + + portLinkTimeout_o : out std_logic_vector(23 downto 0); + + linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0); + outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0); + inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0); + + localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0); + clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0); + inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0); + outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0); + outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0); + inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0); + outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0); + outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0); + + configStb_o : out std_logic; + configWe_o : out std_logic; + configAddr_o : out std_logic_vector(23 downto 0); + configData_o : out std_logic_vector(31 downto 0); + configData_i : in std_logic_vector(31 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for RioSwitch. +------------------------------------------------------------------------------- +architecture RioSwitchImpl of RioSwitch is + + component RouteTableInterconnect is + generic( + WIDTH : natural range 1 to 256 := 8); + port( + clk : in std_logic; + areset_n : in std_logic; + + stb_i : in Array1(WIDTH-1 downto 0); + addr_i : in Array16(WIDTH-1 downto 0); + dataM_o : out Array8(WIDTH-1 downto 0); + ack_o : out Array1(WIDTH-1 downto 0); + + stb_o : out std_logic; + addr_o : out std_logic_vector(15 downto 0); + dataS_i : in std_logic_vector(7 downto 0); + ack_i : in std_logic); + end component; + + component SwitchPortInterconnect is + generic( + WIDTH : natural range 1 to 256 := 8); + port( + clk : in std_logic; + areset_n : in std_logic; + + masterCyc_i : in Array1(WIDTH-1 downto 0); + masterStb_i : in Array1(WIDTH-1 downto 0); + masterWe_i : in Array1(WIDTH-1 downto 0); + masterAddr_i : in Array10(WIDTH-1 downto 0); + masterData_i : in Array32(WIDTH-1 downto 0); + masterData_o : out Array1(WIDTH-1 downto 0); + masterAck_o : out Array1(WIDTH-1 downto 0); + + slaveCyc_o : out Array1(WIDTH-1 downto 0); + slaveStb_o : out Array1(WIDTH-1 downto 0); + slaveWe_o : out Array1(WIDTH-1 downto 0); + slaveAddr_o : out Array10(WIDTH-1 downto 0); + slaveData_o : out Array32(WIDTH-1 downto 0); + slaveData_i : in Array1(WIDTH-1 downto 0); + slaveAck_i : in Array1(WIDTH-1 downto 0)); + end component; + + component SwitchPortMaintenance is + generic( + SWITCH_PORTS : natural range 0 to 255; + DEVICE_IDENTITY : std_logic_vector(15 downto 0); + DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0); + DEVICE_REV : std_logic_vector(31 downto 0); + ASSY_IDENTITY : std_logic_vector(15 downto 0); + ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0); + ASSY_REV : std_logic_vector(15 downto 0)); + port( + clk : in std_logic; + areset_n : in std_logic; + + lookupStb_i : in std_logic; + lookupAddr_i : in std_logic_vector(15 downto 0); + lookupData_o : out std_logic_vector(7 downto 0); + lookupAck_o : out std_logic; + + masterCyc_o : out std_logic; + masterStb_o : out std_logic; + masterWe_o : out std_logic; + masterAddr_o : out std_logic_vector(9 downto 0); + masterData_o : out std_logic_vector(31 downto 0); + masterData_i : in std_logic; + masterAck_i : in std_logic; + + slaveCyc_i : in std_logic; + slaveStb_i : in std_logic; + slaveWe_i : in std_logic; + slaveAddr_i : in std_logic_vector(9 downto 0); + slaveData_i : in std_logic_vector(31 downto 0); + slaveData_o : out std_logic; + slaveAck_o : out std_logic; + + lookupStb_o : out std_logic; + lookupAddr_o : out std_logic_vector(15 downto 0); + lookupData_i : in std_logic_vector(7 downto 0); + lookupAck_i : in std_logic; + + portLinkTimeout_o : out std_logic_vector(23 downto 0); + + linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0); + outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0); + inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0); + localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0); + clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0); + inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0); + outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0); + outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0); + inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0); + outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0); + outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0); + + configStb_o : out std_logic; + configWe_o : out std_logic; + configAddr_o : out std_logic_vector(23 downto 0); + configData_o : out std_logic_vector(31 downto 0); + configData_i : in std_logic_vector(31 downto 0)); + end component; + + component SwitchPort is + generic( + PORT_INDEX : natural); + port( + clk : in std_logic; + areset_n : in std_logic; + + masterCyc_o : out std_logic; + masterStb_o : out std_logic; + masterWe_o : out std_logic; + masterAddr_o : out std_logic_vector(9 downto 0); + masterData_o : out std_logic_vector(31 downto 0); + masterData_i : in std_logic; + masterAck_i : in std_logic; + + slaveCyc_i : in std_logic; + slaveStb_i : in std_logic; + slaveWe_i : in std_logic; + slaveAddr_i : in std_logic_vector(9 downto 0); + slaveData_i : in std_logic_vector(31 downto 0); + slaveData_o : out std_logic; + slaveAck_o : out std_logic; + + lookupStb_o : out std_logic; + lookupAddr_o : out std_logic_vector(15 downto 0); + lookupData_i : in std_logic_vector(7 downto 0); + lookupAck_i : in std_logic; + + readFrameEmpty_i : in std_logic; + readFrame_o : out std_logic; + readFrameRestart_o : out std_logic; + readFrameAborted_i : in std_logic; + readContentEmpty_i : in std_logic; + readContent_o : out std_logic; + readContentEnd_i : in std_logic; + readContentData_i : in std_logic_vector(31 downto 0); + writeFrameFull_i : in std_logic; + writeFrame_o : out std_logic; + writeFrameAbort_o : out std_logic; + writeContent_o : out std_logic; + writeContentData_o : out std_logic_vector(31 downto 0)); + end component; + + signal masterLookupStb : Array1(SWITCH_PORTS downto 0); + signal masterLookupAddr : Array16(SWITCH_PORTS downto 0); + signal masterLookupData : Array8(SWITCH_PORTS downto 0); + signal masterLookupAck : Array1(SWITCH_PORTS downto 0); + + signal slaveLookupStb : std_logic; + signal slaveLookupAddr : std_logic_vector(15 downto 0); + signal slaveLookupData : std_logic_vector(7 downto 0); + signal slaveLookupAck : std_logic; + + signal masterCyc : Array1(SWITCH_PORTS downto 0); + signal masterStb : Array1(SWITCH_PORTS downto 0); + signal masterWe : Array1(SWITCH_PORTS downto 0); + signal masterAddr : Array10(SWITCH_PORTS downto 0); + signal masterDataWrite : Array32(SWITCH_PORTS downto 0); + signal masterDataRead : Array1(SWITCH_PORTS downto 0); + signal masterAck : Array1(SWITCH_PORTS downto 0); + + signal slaveCyc : Array1(SWITCH_PORTS downto 0); + signal slaveStb : Array1(SWITCH_PORTS downto 0); + signal slaveWe : Array1(SWITCH_PORTS downto 0); + signal slaveAddr : Array10(SWITCH_PORTS downto 0); + signal slaveDataWrite : Array32(SWITCH_PORTS downto 0); + signal slaveDataRead : Array1(SWITCH_PORTS downto 0); + signal slaveAck : Array1(SWITCH_PORTS downto 0); + +begin + + ----------------------------------------------------------------------------- + -- The routing table interconnect. + ----------------------------------------------------------------------------- + RouteInterconnect: RouteTableInterconnect + generic map( + WIDTH=>SWITCH_PORTS+1) + port map( + clk=>clk, areset_n=>areset_n, + stb_i=>masterLookupStb, addr_i=>masterLookupAddr, + dataM_o=>masterLookupData, ack_o=>masterLookupAck, + stb_o=>slaveLookupStb, addr_o=>slaveLookupAddr, + dataS_i=>slaveLookupData, ack_i=>slaveLookupAck); + + ----------------------------------------------------------------------------- + -- The port interconnect. + ----------------------------------------------------------------------------- + PortInterconnect: SwitchPortInterconnect + generic map( + WIDTH=>SWITCH_PORTS+1) + port map( + clk=>clk, areset_n=>areset_n, + masterCyc_i=>masterCyc, masterStb_i=>masterStb, masterWe_i=>masterWe, masterAddr_i=>masterAddr, + masterData_i=>masterDataWrite, masterData_o=>masterDataRead, masterAck_o=>masterAck, + slaveCyc_o=>slaveCyc, slaveStb_o=>slaveStb, slaveWe_o=>slaveWe, slaveAddr_o=>slaveAddr, + slaveData_o=>slaveDataWrite, slaveData_i=>slaveDataRead, slaveAck_i=>slaveAck); + + ----------------------------------------------------------------------------- + -- Data relaying port instantiation. + ----------------------------------------------------------------------------- + PortGeneration: for portIndex in 0 to SWITCH_PORTS-1 generate + PortInst: SwitchPort + generic map( + PORT_INDEX=>portIndex) + port map( + clk=>clk, areset_n=>areset_n, + masterCyc_o=>masterCyc(portIndex), masterStb_o=>masterStb(portIndex), + masterWe_o=>masterWe(portIndex), masterAddr_o=>masterAddr(portIndex), + masterData_o=>masterDataWrite(portIndex), + masterData_i=>masterDataRead(portIndex), masterAck_i=>masterAck(portIndex), + slaveCyc_i=>slaveCyc(portIndex), slaveStb_i=>slaveStb(portIndex), + slaveWe_i=>slaveWe(portIndex), slaveAddr_i=>slaveAddr(portIndex), + slaveData_i=>slaveDataWrite(portIndex), + slaveData_o=>slaveDataRead(portIndex), slaveAck_o=>slaveAck(portIndex), + lookupStb_o=>masterLookupStb(portIndex), + lookupAddr_o=>masterLookupAddr(portIndex), + lookupData_i=>masterLookupData(portIndex), lookupAck_i=>masterLookupAck(portIndex), + readFrameEmpty_i=>readFrameEmpty_i(portIndex), readFrame_o=>readFrame_o(portIndex), + readFrameRestart_o=>readFrameRestart_o(portIndex), + readFrameAborted_i=>readFrameAborted_i(portIndex), + readContentEmpty_i=>readContentEmpty_i(portIndex), readContent_o=>readContent_o(portIndex), + readContentEnd_i=>readContentEnd_i(portIndex), readContentData_i=>readContentData_i(portIndex), + writeFrameFull_i=>writeFrameFull_i(portIndex), writeFrame_o=>writeFrame_o(portIndex), + writeFrameAbort_o=>writeFrameAbort_o(portIndex), writeContent_o=>writeContent_o(portIndex), + writeContentData_o=>writeContentData_o(portIndex)); + end generate; + + ----------------------------------------------------------------------------- + -- Maintenance port instantiation. + ----------------------------------------------------------------------------- + MaintenancePort: SwitchPortMaintenance + generic map( + SWITCH_PORTS=>SWITCH_PORTS, + DEVICE_IDENTITY=>DEVICE_IDENTITY, + DEVICE_VENDOR_IDENTITY=>DEVICE_VENDOR_IDENTITY, + DEVICE_REV=>DEVICE_REV, + ASSY_IDENTITY=>ASSY_IDENTITY, + ASSY_VENDOR_IDENTITY=>ASSY_VENDOR_IDENTITY, + ASSY_REV=>ASSY_REV) + port map( + clk=>clk, areset_n=>areset_n, + lookupStb_i=>slaveLookupStb, lookupAddr_i=>slaveLookupAddr, + lookupData_o=>slaveLookupData, lookupAck_o=>slaveLookupAck, + masterCyc_o=>masterCyc(SWITCH_PORTS), masterStb_o=>masterStb(SWITCH_PORTS), + masterWe_o=>masterWe(SWITCH_PORTS), masterAddr_o=>masterAddr(SWITCH_PORTS), + masterData_o=>masterDataWrite(SWITCH_PORTS), + masterData_i=>masterDataRead(SWITCH_PORTS), masterAck_i=>masterAck(SWITCH_PORTS), + slaveCyc_i=>slaveCyc(SWITCH_PORTS), slaveStb_i=>slaveStb(SWITCH_PORTS), + slaveWe_i=>slaveWe(SWITCH_PORTS), slaveAddr_i=>slaveAddr(SWITCH_PORTS), + slaveData_i=>slaveDataWrite(SWITCH_PORTS), + slaveData_o=>slaveDataRead(SWITCH_PORTS), slaveAck_o=>slaveAck(SWITCH_PORTS), + lookupStb_o=>masterLookupStb(SWITCH_PORTS), + lookupAddr_o=>masterLookupAddr(SWITCH_PORTS), + lookupData_i=>masterLookupData(SWITCH_PORTS), lookupAck_i=>masterLookupAck(SWITCH_PORTS), + portLinkTimeout_o=>portLinkTimeout_o, + linkInitialized_i=>linkInitialized_i, + outputPortEnable_o=>outputPortEnable_o, inputPortEnable_o=>inputPortEnable_o, + localAckIdWrite_o=>localAckIdWrite_o, clrOutstandingAckId_o=>clrOutstandingAckId_o, + inboundAckId_o=>inboundAckId_o, outstandingAckId_o=>outstandingAckId_o, + outboundAckId_o=>outboundAckId_o, inboundAckId_i=>inboundAckId_i, + outstandingAckId_i=>outstandingAckId_i, outboundAckId_i=>outboundAckId_i, + configStb_o=>configStb_o, configWe_o=>configWe_o, configAddr_o=>configAddr_o, + configData_o=>configData_o, configData_i=>configData_i); + +end architecture; + + + +------------------------------------------------------------------------------- +-- SwitchPort +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- Entity for SwitchPort. +------------------------------------------------------------------------------- +entity SwitchPort is + generic( + PORT_INDEX : natural); + port( + clk : in std_logic; + areset_n : in std_logic; + + -- Master port signals. + -- Write frames to other ports. + masterCyc_o : out std_logic; + masterStb_o : out std_logic; + masterWe_o : out std_logic; + masterAddr_o : out std_logic_vector(9 downto 0); + masterData_o : out std_logic_vector(31 downto 0); + masterData_i : in std_logic; + masterAck_i : in std_logic; + + -- Slave port signals. + -- Receives frames from other ports. + slaveCyc_i : in std_logic; + slaveStb_i : in std_logic; + slaveWe_i : in std_logic; + slaveAddr_i : in std_logic_vector(9 downto 0); + slaveData_i : in std_logic_vector(31 downto 0); + slaveData_o : out std_logic; + slaveAck_o : out std_logic; + + -- Address-lookup interface. + lookupStb_o : out std_logic; + lookupAddr_o : out std_logic_vector(15 downto 0); + lookupData_i : in std_logic_vector(7 downto 0); + lookupAck_i : in std_logic; + + -- Physical port frame buffer interface. + readFrameEmpty_i : in std_logic; + readFrame_o : out std_logic; + readFrameRestart_o : out std_logic; + readFrameAborted_i : in std_logic; + readContentEmpty_i : in std_logic; + readContent_o : out std_logic; + readContentEnd_i : in std_logic; + readContentData_i : in std_logic_vector(31 downto 0); + writeFrameFull_i : in std_logic; + writeFrame_o : out std_logic; + writeFrameAbort_o : out std_logic; + writeContent_o : out std_logic; + writeContentData_o : out std_logic_vector(31 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for SwitchPort. +------------------------------------------------------------------------------- +architecture SwitchPortImpl of SwitchPort is + + type MasterStateType is (STATE_IDLE, + STATE_WAIT_HEADER_0, STATE_READ_HEADER_0, + STATE_READ_PORT_LOOKUP, + STATE_READ_TARGET_PORT, + STATE_WAIT_TARGET_PORT, + STATE_WAIT_TARGET_WRITE, + STATE_WAIT_COMPLETE); + signal masterState : MasterStateType; + + type SlaveStateType is (STATE_IDLE, STATE_SEND_ACK); + signal slaveState : SlaveStateType; + + alias ftype : std_logic_vector(3 downto 0) is readContentData_i(19 downto 16); + alias tt : std_logic_vector(1 downto 0) is readContentData_i(21 downto 20); + +begin + + ----------------------------------------------------------------------------- + -- Master interface process. + ----------------------------------------------------------------------------- + Master: process(clk, areset_n) + begin + if (areset_n = '0') then + masterState <= STATE_IDLE; + + lookupStb_o <= '0'; + lookupAddr_o <= (others => '0'); + + masterCyc_o <= '0'; + masterStb_o <= '0'; + masterWe_o <= '0'; + masterAddr_o <= (others => '0'); + masterData_o <= (others => '0'); + + readContent_o <= '0'; + readFrame_o <= '0'; + readFrameRestart_o <= '0'; + elsif (clk'event and clk = '1') then + readContent_o <= '0'; + readFrame_o <= '0'; + readFrameRestart_o <= '0'; + + -- REMARK: Add support for aborted frames... + case masterState is + + when STATE_IDLE => + --------------------------------------------------------------------- + -- Wait for a new packet or content of a new packet. + --------------------------------------------------------------------- + + -- Reset bus signals. + masterCyc_o <= '0'; + masterStb_o <= '0'; + + -- Wait for frame content to be available. + -- Use different signals to trigger the forwarding of packets depending + -- on the switch philosofy. + if (readFrameEmpty_i = '0') then + readContent_o <= '1'; + masterState <= STATE_WAIT_HEADER_0; + end if; + + when STATE_WAIT_HEADER_0 => + --------------------------------------------------------------------- + -- Wait for the frame buffer output to be updated. + --------------------------------------------------------------------- + + -- Wait for frame buffer output to be updated. + masterState <= STATE_READ_HEADER_0; + + when STATE_READ_HEADER_0 => + --------------------------------------------------------------------- + -- Check the FTYPE and forward it to the maintenance port if it is a + -- maintenance packet. Otherwise, initiate an address lookup and wait + -- for the result. + --------------------------------------------------------------------- + + -- Check if the frame has ended. + if (readContentEnd_i = '0') then + -- The frame has not ended. + -- This word contains the header and the source id. + + -- Read the tt-field to check the source and destination id size. + if (tt = "01") then + -- This frame contains 16-bit addresses. + + -- Read the new content. + readContent_o <= '1'; + + -- Save the content of the header and destination. + masterData_o <= readContentData_i; + + -- Check if this is a maintenance frame. + if (ftype = FTYPE_MAINTENANCE_CLASS) then + -- This is a maintenance frame. + + -- Always route these frames to the maintenance module in the + -- switch by setting the MSB bit of the port address. + masterAddr_o <= '1' & std_logic_vector(to_unsigned(PORT_INDEX, 8)) & '0'; + + -- Start an access to the maintenance port. + masterState <= STATE_READ_TARGET_PORT; + else + -- This is not a maintenance frame. + + -- Lookup the destination address and proceed to wait for the + -- result. + lookupStb_o <= '1'; + lookupAddr_o <= readContentData_i(15 downto 0); + + -- Wait for the port lookup to return a result. + masterState <= STATE_READ_PORT_LOOKUP; + end if; + else + -- Unsupported tt-value, discard the frame. + readFrame_o <= '1'; + masterState <= STATE_IDLE; + end if; + else + -- End of frame. + -- The frame is too short to contain a valid frame. Discard it. + readFrame_o <= '1'; + masterState <= STATE_IDLE; + end if; + + when STATE_READ_PORT_LOOKUP => + --------------------------------------------------------------------- + -- Wait for the address lookup to be complete. + --------------------------------------------------------------------- + + -- Wait for the routing table to complete the request. + if (lookupAck_i = '1') then + -- The address lookup is complete. + + -- Terminate the lookup cycle. + lookupStb_o <= '0'; + + -- Proceed to read the target port. + masterAddr_o <= '0' & lookupData_i & '0'; + masterState <= STATE_READ_TARGET_PORT; + else + -- Wait until the address lookup is complete. + -- REMARK: Timeout here??? + end if; + + when STATE_READ_TARGET_PORT => + --------------------------------------------------------------------- + -- Initiate an access to the target port. + --------------------------------------------------------------------- + + -- Read the status of the target port using the result from the + -- lookup in the routing table. + masterCyc_o <= '1'; + masterStb_o <= '1'; + masterWe_o <= '0'; + masterState <= STATE_WAIT_TARGET_PORT; + + when STATE_WAIT_TARGET_PORT => + --------------------------------------------------------------------- + -- Wait to get access to the target port. When the port is ready + -- check if it is ready to accept a new frame. If it cannot accept a + -- new frame, terminate the access and go back and start a new one. + -- This is to free the interconnect to let other ports access it if + -- it is a shared bus. If the port is ready, initiate a write access + -- to the selected port. + --------------------------------------------------------------------- + + -- Wait for the target port to complete the request. + if (masterAck_i = '1') then + -- Target port has completed the request. + + -- Check the status of the target port. + if (masterData_i = '0') then + -- The target port has empty buffers to receive the frame. + + -- Hold the bus with cyc until the cycle is complete. + -- Write the first word of the frame to the target port. + -- The masterData_o has already been assigned. + masterCyc_o <= '1'; + masterStb_o <= '1'; + masterWe_o <= '1'; + masterAddr_o(0) <= '1'; + + -- Change state to transfer the frame. + masterState <= STATE_WAIT_TARGET_WRITE; + else + -- The target port has no empty buffer to receive the frame. + -- Terminate the cycle and retry later. + masterCyc_o <= '0'; + masterStb_o <= '0'; + masterState <= STATE_READ_TARGET_PORT; + end if; + else + -- Target port has not completed the request. + -- Dont to anything. + end if; + + when STATE_WAIT_TARGET_WRITE => + --------------------------------------------------------------------- + -- Wait for the write access to complete. When complete, write the + -- next content and update the content to the next. If the frame does + -- not have any more data ready, terminate the access but keep the + -- cycle active and proceed to wait for new data. + --------------------------------------------------------------------- + + -- Wait for the target port to complete the request. + -- REMARK: Remove the ack-condition, we know that the write takes one + -- cycle... + if (masterAck_i = '1') then + -- The target port is ready. + + -- Check if the frame has ended. + if (readContentEnd_i = '0') then + -- The frame has not ended. + + -- There are more data to transfer. + masterData_o <= readContentData_i; + readContent_o <= '1'; + else + -- There are no more data to transfer. + + -- Update to the next frame. + readFrame_o <= '1'; + + -- Tell the target port that the frame is complete. + masterWe_o <= '1'; + masterAddr_o(0) <= '0'; + masterData_o <= x"00000001"; + + -- Change state to wait for the target port to finalize the write + -- of the full frame. + masterState <= STATE_WAIT_COMPLETE; + end if; + else + -- Wait for the target port to reply. + -- Dont do anything. + end if; + + when STATE_WAIT_COMPLETE => + --------------------------------------------------------------------- + -- Wait for the target port to signal that the frame has been + -- completed. + --------------------------------------------------------------------- + + -- Wait for the target port to complete the final request. + if (masterAck_i = '1') then + -- The target port has finalized the write of the frame. + + -- Reset master bus signals. + masterCyc_o <= '0'; + masterStb_o <= '0'; + masterState <= STATE_IDLE; + else + -- Wait for the target port to reply. + -- REMARK: Timeout here??? + end if; + + when others => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + end case; + end if; + end process; + + + ----------------------------------------------------------------------------- + -- Slave interface process. + ----------------------------------------------------------------------------- + -- Addr | Read | Write + -- 0 | full | abort & complete + -- 1 | full | frameData + writeContentData_o <= slaveData_i; + Slave: process(clk, areset_n) + begin + if (areset_n = '0') then + slaveState <= STATE_IDLE; + + slaveData_o <= '0'; + + writeFrame_o <= '0'; + writeFrameAbort_o <= '0'; + writeContent_o <= '0'; + elsif (clk'event and clk = '1') then + writeFrame_o <= '0'; + writeFrameAbort_o <= '0'; + writeContent_o <= '0'; + + case slaveState is + + when STATE_IDLE => + --------------------------------------------------------------------- + -- Wait for an access from a master. + --------------------------------------------------------------------- + + -- Check if any cycle is active. + if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then + -- Cycle is active. + + -- Check if the cycle is accessing the status- or data address. + if (slaveAddr_i(0) = '0') then + -- Accessing port status address. + + -- Check if writing. + if (slaveWe_i = '1') then + -- Writing the status address. + -- Update the buffering output signals according to the input + -- data. + writeFrame_o <= slaveData_i(0); + writeFrameAbort_o <= slaveData_i(1); + else + -- Reading the status address. + slaveData_o <= writeFrameFull_i; + end if; + else + -- Accessing port data address. + + -- Check if writing. + if (slaveWe_i = '1') then + -- Write frame content into the frame buffer. + writeContent_o <= '1'; + else + slaveData_o <= writeFrameFull_i; + end if; + end if; + + -- Change state to send an ack to the master. + slaveState <= STATE_SEND_ACK; + end if; + + when STATE_SEND_ACK => + --------------------------------------------------------------------- + -- Wait for acknowledge to be received by the master. + --------------------------------------------------------------------- + + -- Go back to the idle state and wait for a new cycle. + slaveState <= STATE_IDLE; + + when others => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + null; + + end case; + end if; + end process; + + -- Assign the acknowledge depending on the current slave state. + slaveAck_o <= '1' when (slaveState = STATE_SEND_ACK) else '0'; + +end architecture; + + + +------------------------------------------------------------------------------- +-- SwitchPortMaintenance +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- Entity for SwitchPortMaintenance. +------------------------------------------------------------------------------- +entity SwitchPortMaintenance is + generic( + SWITCH_PORTS : natural range 0 to 255; + DEVICE_IDENTITY : std_logic_vector(15 downto 0); + DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0); + DEVICE_REV : std_logic_vector(31 downto 0); + ASSY_IDENTITY : std_logic_vector(15 downto 0); + ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0); + ASSY_REV : std_logic_vector(15 downto 0)); + port( + clk : in std_logic; + areset_n : in std_logic; + + -- Routing table port lookup signals. + lookupStb_i : in std_logic; + lookupAddr_i : in std_logic_vector(15 downto 0); + lookupData_o : out std_logic_vector(7 downto 0); + lookupAck_o : out std_logic; + + -- Master port signals. + -- Write frames to other ports. + masterCyc_o : out std_logic; + masterStb_o : out std_logic; + masterWe_o : out std_logic; + masterAddr_o : out std_logic_vector(9 downto 0); + masterData_o : out std_logic_vector(31 downto 0); + masterData_i : in std_logic; + masterAck_i : in std_logic; + + -- Slave port signals. + -- Receives frames from other ports. + slaveCyc_i : in std_logic; + slaveStb_i : in std_logic; + slaveWe_i : in std_logic; + slaveAddr_i : in std_logic_vector(9 downto 0); + slaveData_i : in std_logic_vector(31 downto 0); + slaveData_o : out std_logic; + slaveAck_o : out std_logic; + + -- Address-lookup interface. + lookupStb_o : out std_logic; + lookupAddr_o : out std_logic_vector(15 downto 0); + lookupData_i : in std_logic_vector(7 downto 0); + lookupAck_i : in std_logic; + + -- Port common access interface. + portLinkTimeout_o : out std_logic_vector(23 downto 0); + + -- Port specific access interface. + linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0); + outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0); + inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0); + localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0); + clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0); + inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0); + outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0); + outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0); + inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0); + outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0); + outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0); + + -- Configuration space for implementation-defined space. + configStb_o : out std_logic; + configWe_o : out std_logic; + configAddr_o : out std_logic_vector(23 downto 0); + configData_o : out std_logic_vector(31 downto 0); + configData_i : in std_logic_vector(31 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for SwitchPort. +------------------------------------------------------------------------------- +architecture SwitchPortMaintenanceImpl of SwitchPortMaintenance is + + component MemoryDualPort is + generic( + ADDRESS_WIDTH : natural := 1; + DATA_WIDTH : natural := 1); + port( + clkA_i : in std_logic; + enableA_i : in std_logic; + writeEnableA_i : in std_logic; + addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0); + dataA_o : out std_logic_vector(DATA_WIDTH-1 downto 0); + + clkB_i : in std_logic; + enableB_i : in std_logic; + addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0)); + end component; + + 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; + + 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; + + type MasterStateType is (STATE_IDLE, + STATE_CHECK_FRAME, + STATE_RELAY_READ_RESPONSE, + STATE_RELAY_WRITE_RESPONSE, + STATE_SEND_READ_REQUEST, + STATE_SEND_WRITE_REQUEST, + STATE_SEND_READ_RESPONSE, + STATE_SEND_WRITE_RESPONSE, + STATE_START_PORT_LOOKUP, + STATE_READ_PORT_LOOKUP, + STATE_READ_TARGET_PORT, + STATE_WAIT_TARGET_PORT, + STATE_WAIT_TARGET_WRITE, + STATE_WAIT_COMPLETE, + STATE_WAIT_SLAVE); + signal masterState : MasterStateType; + + 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 configEnable : std_logic; + signal configWrite : std_logic; + signal configAddress : std_logic_vector(23 downto 0); + signal configDataWrite : std_logic_vector(31 downto 0); + signal configDataRead, configDataReadInternal : std_logic_vector(31 downto 0); + + signal outboundFrameEnable : std_logic; + signal outboundFrameWrite : std_logic; + signal outboundFrameAddress : std_logic_vector(2 downto 0); + signal outboundFrameDataWrite : std_logic_vector(31 downto 0); + signal outboundFrameDataRead : std_logic_vector(31 downto 0); + signal outboundFrameLength : std_logic_vector(2 downto 0); + + type SlaveStateType is (STATE_READY, + STATE_BUSY); + signal slaveState : SlaveStateType; + signal slaveAck : std_logic; + + signal inboundFrameReady : std_logic; + signal inboundFramePort : std_logic_vector(7 downto 0); + signal inboundFrameLength : natural range 0 to 7; + signal inboundFrameComplete : std_logic; + + signal vc : std_logic; + signal crf : std_logic; + signal prio : std_logic_vector(1 downto 0); + signal tt : std_logic_vector(1 downto 0); + signal ftype : std_logic_vector(3 downto 0); + signal destinationId : std_logic_vector(15 downto 0); + signal sourceId : std_logic_vector(15 downto 0); + signal transaction : std_logic_vector(3 downto 0); + signal size : std_logic_vector(3 downto 0); + signal srcTid : std_logic_vector(7 downto 0); + signal hopCount : std_logic_vector(7 downto 0); + signal configOffset : std_logic_vector(20 downto 0); + signal wdptr : std_logic; + signal content : std_logic_vector(63 downto 0); + + ----------------------------------------------------------------------------- + -- Route table access signals. + ----------------------------------------------------------------------------- + + signal address0 : std_logic_vector(7 downto 0); + signal address1 : std_logic_vector(7 downto 0); + signal address2 : std_logic_vector(7 downto 0); + signal address3 : std_logic_vector(7 downto 0); + + signal lookupEnable : std_logic; + signal lookupAddress : std_logic_vector(10 downto 0); + signal lookupData : std_logic_vector(7 downto 0); + signal lookupAck : std_logic; + + signal routeTableEnable : std_logic; + signal routeTableWrite : std_logic; + signal routeTableAddress : std_logic_vector(10 downto 0); + signal routeTablePortWrite : std_logic_vector(7 downto 0); + signal routeTablePortRead : std_logic_vector(7 downto 0); + + signal routeTablePortDefault : std_logic_vector(7 downto 0); + + ----------------------------------------------------------------------------- + -- Configuration space signals. + ----------------------------------------------------------------------------- + + signal discovered : std_logic; + + signal hostBaseDeviceIdLocked : std_logic; + signal hostBaseDeviceId : std_logic_vector(15 downto 0); + signal componentTag : std_logic_vector(31 downto 0); + + signal portLinkTimeout : std_logic_vector(23 downto 0); + + signal outputPortEnable : Array1(SWITCH_PORTS-1 downto 0); + signal inputPortEnable : Array1(SWITCH_PORTS-1 downto 0); + +begin + + ----------------------------------------------------------------------------- + -- Memory to contain the outbound frame. + ----------------------------------------------------------------------------- + + OutboundFrameMemory: MemorySinglePort + generic map( + ADDRESS_WIDTH=>3, DATA_WIDTH=>32) + port map( + clk_i=>clk, + enable_i=>outboundFrameEnable, writeEnable_i=>outboundFrameWrite, + address_i=>outboundFrameAddress, + data_i=>outboundFrameDataWrite, data_o=>outboundFrameDataRead); + + ----------------------------------------------------------------------------- + -- CRC generation for outbound frames. + ----------------------------------------------------------------------------- + + crc16Data <= outboundFrameDataWrite; + + -- REMARK: Insert FFs here to make the critical path shorter... + Crc16High: Crc16CITT + port map( + d_i=>crc16Data(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp); + Crc16Low: Crc16CITT + port map( + d_i=>crc16Data(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next); + + ----------------------------------------------------------------------------- + -- Master interface process. + ----------------------------------------------------------------------------- + Master: process(clk, areset_n) + begin + if (areset_n = '0') then + masterState <= STATE_IDLE; + + lookupStb_o <= '0'; + lookupAddr_o <= (others => '0'); + + masterCyc_o <= '0'; + masterStb_o <= '0'; + masterWe_o <= '0'; + masterAddr_o <= (others => '0'); + masterData_o <= (others => '0'); + + configEnable <= '0'; + configWrite <= '0'; + configAddress <= (others => '0'); + configDataWrite <= (others => '0'); + + outboundFrameEnable <= '0'; + outboundFrameWrite <= '0'; + outboundFrameAddress <= (others=>'0'); + outboundFrameDataWrite <= (others=>'0'); + outboundFrameLength <= (others=>'0'); + + inboundFrameComplete <= '0'; + elsif (clk'event and clk = '1') then + configEnable <= '0'; + configWrite <= '0'; + inboundFrameComplete <= '0'; + + case masterState is + + when STATE_IDLE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + + -- Wait for a full frame to be available. + if (inboundFrameReady = '1') then + if (inboundFrameLength > 3) then + masterState <= STATE_CHECK_FRAME; + else + -- Frame is too short. + -- REMARK: Discard the frame. + end if; + end if; + + when STATE_CHECK_FRAME => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + + -- Check if the frame has 16-bit addresses and is a maintenance frame. + if (tt = "01") and (ftype = FTYPE_MAINTENANCE_CLASS) then + -- Maintenance class frame and 16-bit addresses. + + -- Check the frame type. + case transaction is + + when "0000" => + --------------------------------------------------------------- + -- Maintenance read request. + --------------------------------------------------------------- + + -- Check if the frame is for us. + if (hopCount = x"00") then + -- This frame is for us. + configEnable <= '1'; + configWrite <= '0'; + configAddress <= configOffset & wdptr & "00"; + + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= (others=>'0'); + outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & sourceId; + crc16Current <= x"ffff"; + + masterState <= STATE_SEND_READ_RESPONSE; + else + -- This frame is not for us. + -- Decrement hop_count and relay. + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= (others=>'0'); + outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId; + crc16Current <= x"ffff"; + + masterState <= STATE_SEND_READ_REQUEST; + end if; + + when "0001" => + --------------------------------------------------------------- + -- Maintenance write request. + --------------------------------------------------------------- + + -- Check if the frame is for us. + if (hopCount = x"00") then + -- This frame is for us. + configEnable <= '1'; + configWrite <= '1'; + configAddress <= configOffset & wdptr & "00"; + + if (wdptr = '0') then + configDataWrite <= content(63 downto 32); + else + configDataWrite <= content(31 downto 0); + end if; + + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= (others=>'0'); + outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & sourceId; + crc16Current <= x"ffff"; + + masterState <= STATE_SEND_WRITE_RESPONSE; + else + -- This frame is not for us. + -- Decrement hop_count and relay. + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= (others=>'0'); + outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId; + crc16Current <= x"ffff"; + + masterState <= STATE_SEND_WRITE_REQUEST; + end if; + + when "0010" => + --------------------------------------------------------------- + -- Maintenance read response frame. + --------------------------------------------------------------- + + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= (others=>'0'); + outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId; + crc16Current <= x"ffff"; + + -- Relay frame. + masterState <= STATE_RELAY_READ_RESPONSE; + + when "0011" => + --------------------------------------------------------------- + -- Maintenance write response frame. + --------------------------------------------------------------- + + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= (others=>'0'); + outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId; + crc16Current <= x"ffff"; + + -- Relay frame. + masterState <= STATE_RELAY_WRITE_RESPONSE; + + when "0100" => + --------------------------------------------------------------- + -- Maintenance port write frame. + --------------------------------------------------------------- + + -- REMARK: Support these??? + + when others => + --------------------------------------------------------------- + -- Unsupported frame type. + --------------------------------------------------------------- + + -- REMARK: Support these??? + end case; + else + -- Non-maintenance class frame or unsupported address type. + -- REMARK: These should not end up here... discard them??? + end if; + + when STATE_RELAY_READ_RESPONSE => + --------------------------------------------------------------------- + -- A maintenance response has been received. It should be relayed as + -- is using the destinationId. + --------------------------------------------------------------------- + + case to_integer(unsigned(outboundFrameAddress)) is + when 0 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= sourceId & transaction & size & srcTid; + crc16Current <= crc16Next; + when 1 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= hopCount & configOffset & wdptr & "00"; + crc16Current <= crc16Next; + when 2 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= content(63 downto 32); + crc16Current <= crc16Next; + when 3 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= content(31 downto 0); + crc16Current <= crc16Next; + when 4 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite(31 downto 16) <= crc16Next; + outboundFrameDataWrite(15 downto 0) <= x"0000"; + when others => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '0'; + outboundFrameAddress <= (others=>'0'); + outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + masterState <= STATE_START_PORT_LOOKUP; + end case; + + when STATE_RELAY_WRITE_RESPONSE => + --------------------------------------------------------------------- + -- A maintenance response has been received. It should be relayed as + -- is using the destinationId. + --------------------------------------------------------------------- + + case to_integer(unsigned(outboundFrameAddress)) is + when 0 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= sourceId & transaction & size & srcTid; + crc16Current <= crc16Next; + when 1 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= hopCount & configOffset & wdptr & "00"; + crc16Current <= crc16Next; + when 2 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite(31 downto 16) <= crc16Next; + outboundFrameDataWrite(15 downto 0) <= x"0000"; + when others => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '0'; + outboundFrameAddress <= (others=>'0'); + outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + masterState <= STATE_START_PORT_LOOKUP; + end case; + + when STATE_SEND_READ_REQUEST => + --------------------------------------------------------------------- + -- A read request has been received but the hopcount is larger than + -- zero. Decrement the hopcount, recalculate the crc and relay the + -- frame using the destinationId. + --------------------------------------------------------------------- + + case to_integer(unsigned(outboundFrameAddress)) is + when 0 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= sourceId & transaction & size & srcTid; + crc16Current <= crc16Next; + when 1 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= std_logic_vector(unsigned(hopCount) - 1) & configOffset & wdptr & "00"; + crc16Current <= crc16Next; + when 2 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite(31 downto 16) <= crc16Next; + outboundFrameDataWrite(15 downto 0) <= x"0000"; + when others => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '0'; + outboundFrameAddress <= (others=>'0'); + outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + masterState <= STATE_START_PORT_LOOKUP; + end case; + + when STATE_SEND_WRITE_REQUEST => + --------------------------------------------------------------------- + -- A write request has been received but the hopcount is larger than + -- zero. Decrement the hopcount, recalculate the crc and relay the + -- frame using the destinationId. + --------------------------------------------------------------------- + + case to_integer(unsigned(outboundFrameAddress)) is + when 0 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= sourceId & transaction & size & srcTid; + crc16Current <= crc16Next; + when 1 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= std_logic_vector(unsigned(hopCount) - 1) & configOffset & wdptr & "00"; + crc16Current <= crc16Next; + when 2 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= content(63 downto 32); + crc16Current <= crc16Next; + when 3 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= content(31 downto 0); + crc16Current <= crc16Next; + when 4 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite(31 downto 16) <= crc16Next; + outboundFrameDataWrite(15 downto 0) <= x"0000"; + when others => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '0'; + outboundFrameAddress <= (others=>'0'); + outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + masterState <= STATE_START_PORT_LOOKUP; + end case; + + when STATE_SEND_READ_RESPONSE => + --------------------------------------------------------------------- + -- A read request has been received with a hopcount that are zero. + -- Create a read response, calculate crc and write it to the port it + -- came from. + --------------------------------------------------------------------- + + case to_integer(unsigned(outboundFrameAddress)) is + when 0 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= destinationId & "0010" & "0000" & srcTid; + crc16Current <= crc16Next; + when 1 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= x"ff" & x"000000"; + crc16Current <= crc16Next; + when 2 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + if (wdptr = '1') then + outboundFrameDataWrite <= (others => '0'); + else + outboundFrameDataWrite <= configDataRead(31 downto 0); + end if; + crc16Current <= crc16Next; + when 3 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + if (wdptr = '1') then + outboundFrameDataWrite <= configDataRead(31 downto 0); + else + outboundFrameDataWrite <= (others => '0'); + end if; + crc16Current <= crc16Next; + when 4 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite(31 downto 16) <= crc16Next; + outboundFrameDataWrite(15 downto 0) <= x"0000"; + when others => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '0'; + outboundFrameAddress <= (others=>'0'); + outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + masterAddr_o <= '0' & inboundFramePort & '0'; + masterState <= STATE_READ_TARGET_PORT; + end case; + + when STATE_SEND_WRITE_RESPONSE => + --------------------------------------------------------------------- + -- A write request has been received with a hopcount that are zero. + -- Create a write response, calculate crc and write it to the port it + -- came from. + --------------------------------------------------------------------- + + case to_integer(unsigned(outboundFrameAddress)) is + when 0 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= destinationId & "0011" & "0000" & srcTid; + crc16Current <= crc16Next; + when 1 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite <= x"ff" & x"000000"; + crc16Current <= crc16Next; + when 2 => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '1'; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + outboundFrameDataWrite(31 downto 16) <= crc16Next; + outboundFrameDataWrite(15 downto 0) <= x"0000"; + when others => + outboundFrameEnable <= '1'; + outboundFrameWrite <= '0'; + outboundFrameAddress <= (others=>'0'); + outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + masterAddr_o <= '0' & inboundFramePort & '0'; + masterState <= STATE_READ_TARGET_PORT; + end case; + + when STATE_START_PORT_LOOKUP => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + + -- Initiate a port-lookup of the destination address. + lookupStb_o <= '1'; + lookupAddr_o <= destinationId; + masterState <= STATE_READ_PORT_LOOKUP; + + when STATE_READ_PORT_LOOKUP => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + + -- Wait for the routing table to complete the request. + if (lookupAck_i = '1') then + -- The address lookup is complete. + + -- Terminate the lookup cycle. + lookupStb_o <= '0'; + + -- Wait for the target port to reply. + masterAddr_o <= '0' & lookupData_i & '0'; + masterState <= STATE_READ_TARGET_PORT; + else + -- Wait until the address lookup is complete. + -- REMARK: Timeout here??? + end if; + + when STATE_READ_TARGET_PORT => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + + -- Read the status of the target port using the result from the + -- lookup in the routing table. + masterCyc_o <= '1'; + masterStb_o <= '1'; + masterWe_o <= '0'; + masterState <= STATE_WAIT_TARGET_PORT; + + when STATE_WAIT_TARGET_PORT => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + + -- Wait for the target port to complete the request. + if (masterAck_i = '1') then + if (masterData_i = '0') then + -- The target port has empty buffers to receive the frame. + + -- Write the first word of the frame to the target port. + -- The masterData_o has already been assigned. + masterCyc_o <= '1'; + masterStb_o <= '1'; + masterWe_o <= '1'; + masterAddr_o(0) <= '1'; + + -- Read the first word in the frame and update the frame address. + masterData_o <= outboundFrameDataRead; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + + -- Change state to transfer the frame. + masterState <= STATE_WAIT_TARGET_WRITE; + else + -- The target port has no empty buffer to receive the frame. + -- Terminate the cycle and retry later. + masterCyc_o <= '0'; + masterStb_o <= '0'; + masterState <= STATE_READ_TARGET_PORT; + end if; + else + -- Wait for the target port to reply. + -- REMARK: Timeout here??? + end if; + + when STATE_WAIT_TARGET_WRITE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + + -- Wait for the target port to complete the request. + if (masterAck_i = '1') then + -- The target port is ready. + + -- Check if the frame has ended. + if (outboundFrameLength /= outboundFrameAddress) then + -- The frame has not ended. + + -- There are more data to transfer. + masterData_o <= outboundFrameDataRead; + outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1); + else + -- There are no more data to transfer. + + -- Tell the target port that the frame is complete. + masterWe_o <= '1'; + masterAddr_o(0) <= '0'; + masterData_o <= x"00000001"; + outboundFrameAddress <= (others=>'0'); + + -- Change state to wait for the target port to finalize the write + -- of the full frame. + masterState <= STATE_WAIT_COMPLETE; + end if; + else + -- Wait for the target port to reply. + -- REMARK: Timeout here??? + end if; + + when STATE_WAIT_COMPLETE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + + -- Wait for the target port to complete the final request. + if (masterAck_i = '1') then + -- The target port has finalized the write of the frame. + masterCyc_o <= '0'; + masterStb_o <= '0'; + masterState <= STATE_WAIT_SLAVE; + + -- Indicate the frame has been read. + inboundFrameComplete <= '1'; + else + -- Wait for the target port to reply. + -- REMARK: Timeout here??? + end if; + + when STATE_WAIT_SLAVE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + masterState <= STATE_IDLE; + + when others => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + end case; + end if; + end process; + + + ----------------------------------------------------------------------------- + -- Slave interface process. + ----------------------------------------------------------------------------- + -- Addr | Read | Write + -- 0 | full | abort & complete + -- 1 | full | frameData + Slave: process(clk, areset_n) + begin + if (areset_n = '0') then + slaveState <= STATE_READY; + slaveData_o <= '0'; + slaveAck <= '0'; + + vc <= '0'; + crf <= '0'; + prio <= (others=>'0'); + tt <= (others=>'0'); + ftype <= (others=>'0'); + destinationId <= (others=>'0'); + sourceId <= (others=>'0'); + transaction <= (others=>'0'); + size <= (others=>'0'); + srcTid <= (others=>'0'); + hopCount <= (others=>'0'); + configOffset <= (others=>'0'); + wdptr <= '0'; + content <= (others=>'0'); + + inboundFrameReady <= '0'; + inboundFramePort <= (others => '0'); + inboundFrameLength <= 0; + elsif (clk'event and clk = '1') then + slaveAck <= '0'; + + case slaveState is + when STATE_READY => + --------------------------------------------------------------------- + -- Ready to receive a new frame. + --------------------------------------------------------------------- + + -- Check if any cycle is active. + if ((slaveCyc_i = '1') and (slaveStb_i = '1') and (slaveAck = '0')) then + -- Cycle is active. + + -- Check if writing. + if (slaveWe_i = '1') then + -- Writing request. + + -- Check if the cycle is accessing the status- or data address. + if (slaveAddr_i(0) = '0') then + -- Writing to port status address. + + if (slaveData_i(0) = '1') and (slaveData_i(1) = '0') then + -- A frame has been written. + + -- Indicate the frame is ready for processing. + -- The slave address contains the number of the accessing port. + inboundFrameReady <= '1'; + inboundFramePort <= slaveAddr_i(8 downto 1); + + -- Change state until the frame has been processed. + slaveState <= STATE_BUSY; + else + -- The frame has been aborted. + -- Reset the received frame length. + inboundFrameLength <= 0; + end if; + else + -- Write frame content into the frame buffer. + + -- Check which frame index that is written. + case inboundFrameLength is + when 0 => + vc <= slaveData_i(25); + crf <= slaveData_i(24); + prio <= slaveData_i(23 downto 22); + tt <= slaveData_i(21 downto 20); + ftype <= slaveData_i(19 downto 16); + destinationId <= slaveData_i(15 downto 0); + inboundFrameLength <= inboundFrameLength + 1; + when 1 => + sourceId <= slaveData_i(31 downto 16); + transaction <= slaveData_i(15 downto 12); + size <= slaveData_i(11 downto 8); + srcTid <= slaveData_i(7 downto 0); + inboundFrameLength <= inboundFrameLength + 1; + when 2 => + hopCount <= slaveData_i(31 downto 24); + configOffset <= slaveData_i(23 downto 3); + wdptr <= slaveData_i(2); + inboundFrameLength <= inboundFrameLength + 1; + when 3 => + -- Note that crc will be assigned here if there are no + -- content in the frame. + content(63 downto 32) <= slaveData_i; + inboundFrameLength <= inboundFrameLength + 1; + when 4 => + content(31 downto 0) <= slaveData_i; + inboundFrameLength <= inboundFrameLength + 1; + when others => + -- Dont support longer frames. + -- REMARK: Add support for longer frames??? Especially + -- received frames that only should be routed... + end case; + end if; + + -- Send acknowledge. + slaveAck <= '1'; + else + -- Reading request. + + -- Reading the status address. + -- Always indicate that we are ready to accept a new frame. + slaveData_o <= '0'; + + -- Send acknowledge. + slaveAck <= '1'; + end if; + else + -- No cycle is active. + end if; + + when STATE_BUSY => + --------------------------------------------------------------------- + -- Waiting for a received frame to be processed. + --------------------------------------------------------------------- + + -- Check if any cycle is active. + if ((slaveCyc_i = '1') and (slaveStb_i = '1') and (slaveAck = '0')) then + -- Cycle is active. + + -- Check if writing. + if (slaveWe_i = '1') then + -- Writing. + -- Dont do anything. + + -- Send acknowledge. + slaveAck <= '1'; + else + -- Read port data address. + + -- Reading the status address. + -- Always indicate that we are busy. + slaveData_o <= '1'; + + -- Send acknowledge. + slaveAck <= '1'; + end if; + else + -- No cycle is active. + -- Dont do anything. + end if; + + -- Check if the master process has processed the received frame. + if (inboundFrameComplete = '1') then + -- The master has processed the frame. + inboundFrameReady <= '0'; + inboundFrameLength <= 0; + slaveState <= STATE_READY; + else + -- The master is not ready yet. + -- Dont do anything. + end if; + + when others => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + null; + + end case; + end if; + end process; + + slaveAck_o <= slaveAck; + + ----------------------------------------------------------------------------- + -- Logic implementing the routing table access. + ----------------------------------------------------------------------------- + + -- Lookup interface port memory signals. + lookupEnable <= '1' when (lookupStb_i = '1') and (lookupAddr_i(15 downto 11) = "00000") else '0'; + lookupAddress <= lookupAddr_i(10 downto 0); + lookupData_o <= lookupData when (lookupEnable = '1') else routeTablePortDefault; + lookupAck_o <= lookupAck; + LookupProcess: process(clk, areset_n) + begin + if (areset_n = '0') then + lookupAck <= '0'; + elsif (clk'event and clk = '1') then + if ((lookupStb_i = '1') and (lookupAck = '0')) then + lookupAck <= '1'; + else + lookupAck <= '0'; + end if; + end if; + end process; + + -- Dual port memory containing the routing table. + RoutingTable: MemoryDualPort + generic map( + ADDRESS_WIDTH=>11, DATA_WIDTH=>8) + port map( + clkA_i=>clk, enableA_i=>routeTableEnable, writeEnableA_i=>routeTableWrite, + addressA_i=>routeTableAddress, + dataA_i=>routeTablePortWrite, dataA_o=>routeTablePortRead, + clkB_i=>clk, enableB_i=>lookupEnable, + addressB_i=>lookupAddress, dataB_o=>lookupData); + + ----------------------------------------------------------------------------- + -- Configuration memory. + ----------------------------------------------------------------------------- + + portLinkTimeout_o <= portLinkTimeout; + outputPortEnable_o <= outputPortEnable; + inputPortEnable_o <= inputPortEnable; + + configStb_o <= '1' when ((configEnable = '1') and (configAddress(23 downto 16) /= x"00")) else '0'; + configWe_o <= configWrite; + configAddr_o <= configAddress; + configData_o <= configDataWrite; + configDataRead <= configData_i when (configAddress(23 downto 16) /= x"00") else + configDataReadInternal; + + ConfigMemory: process(areset_n, clk) + begin + if (areset_n = '0') then + configDataReadInternal <= (others => '0'); + + routeTableEnable <= '1'; + routeTableWrite <= '0'; + routeTableAddress <= (others => '0'); + routeTablePortWrite <= (others => '0'); + routeTablePortDefault <= (others => '0'); + + discovered <= '0'; + + hostBaseDeviceIdLocked <= '0'; + hostBaseDeviceId <= (others => '1'); + componentTag <= (others => '0'); + + portLinkTimeout <= (others => '1'); + + -- REMARK: These should be set to zero when a port gets initialized... + outputPortEnable <= (others => '0'); + inputPortEnable <= (others => '0'); + + localAckIdWrite_o <= (others => '0'); + elsif (clk'event and clk = '1') then + routeTableWrite <= '0'; + localAckIdWrite_o <= (others => '0'); + + if (configEnable = '1') then + -- Check if the access is into implementation defined space or if the + -- access should be handled here. + if (configAddress(23 downto 16) /= x"00") then + -- Accessing implementation defined space. + -- Make an external access and return the resonse. + configDataReadInternal <= (others=>'0'); + else + -- Access should be handled here. + + case (configAddress) is + when x"000000" => + ----------------------------------------------------------------- + -- Device Identity CAR. Read-only. + ----------------------------------------------------------------- + + configDataReadInternal(31 downto 16) <= DEVICE_IDENTITY; + configDataReadInternal(15 downto 0) <= DEVICE_VENDOR_IDENTITY; + + when x"000004" => + ----------------------------------------------------------------- + -- Device Information CAR. Read-only. + ----------------------------------------------------------------- + + configDataReadInternal(31 downto 0) <= DEVICE_REV; + + when x"000008" => + ----------------------------------------------------------------- + -- Assembly Identity CAR. Read-only. + ----------------------------------------------------------------- + + configDataReadInternal(31 downto 16) <= ASSY_IDENTITY; + configDataReadInternal(15 downto 0) <= ASSY_VENDOR_IDENTITY; + + when x"00000c" => + ----------------------------------------------------------------- + -- Assembly Informaiton CAR. Read-only. + ----------------------------------------------------------------- + + configDataReadInternal(31 downto 16) <= ASSY_REV; + configDataReadInternal(15 downto 0) <= x"0100"; + + when x"000010" => + ----------------------------------------------------------------- + -- Processing Element Features CAR. Read-only. + ----------------------------------------------------------------- + + -- Bridge. + configDataReadInternal(31) <= '0'; + + -- Memory. + configDataReadInternal(30) <= '0'; + + -- Processor. + configDataReadInternal(29) <= '0'; + + -- Switch. + configDataReadInternal(28) <= '1'; + + -- Reserved. + configDataReadInternal(27 downto 10) <= (others => '0'); + + -- Extended route table configuration support. + configDataReadInternal(9) <= '0'; + + -- Standard route table configuration support. + configDataReadInternal(8) <= '1'; + + -- Reserved. + configDataReadInternal(7 downto 5) <= (others => '0'); + + -- Common transport large system support. + configDataReadInternal(4) <= '1'; + + -- Extended features. + configDataReadInternal(3) <= '1'; + + -- Extended addressing support. + -- Not a processing element. + configDataReadInternal(2 downto 0) <= "000"; + + when x"000014" => + ----------------------------------------------------------------- + -- Switch Port Information CAR. Read-only. + ----------------------------------------------------------------- + + -- Reserved. + configDataReadInternal(31 downto 16) <= (others => '0'); + + -- PortTotal. + configDataReadInternal(15 downto 8) <= + std_logic_vector(to_unsigned(SWITCH_PORTS, 8)); + + -- PortNumber. + configDataReadInternal(7 downto 0) <= inboundFramePort; + + when x"000034" => + ----------------------------------------------------------------- + -- Switch Route Table Destination ID Limit CAR. + ----------------------------------------------------------------- + + -- Max_destId. + -- Support 2048 addresses. + configDataReadInternal(15 downto 0) <= x"0800"; + + when x"000068" => + ----------------------------------------------------------------- + -- Host Base Device ID Lock CSR. + ----------------------------------------------------------------- + + if (configWrite = '1') then + -- Check if this field has been written before. + if (hostBaseDeviceIdLocked = '0') then + -- The field has not been written. + -- Lock the field and set the host base device id. + hostBaseDeviceIdLocked <= '1'; + hostBaseDeviceId <= configDataWrite(15 downto 0); + else + -- The field has been written. + -- Check if the written data is the same as the stored. + if (hostBaseDeviceId = configDataWrite(15 downto 0)) then + -- Same as stored, reset the value to its initial value. + hostBaseDeviceIdLocked <= '0'; + hostBaseDeviceId <= (others => '1'); + else + -- Not writing the same as the stored value. + -- Ignore the write. + end if; + end if; + end if; + + configDataReadInternal(31 downto 16) <= (others => '0'); + configDataReadInternal(15 downto 0) <= hostBaseDeviceId; + + when x"00006c" => + ----------------------------------------------------------------- + -- Component TAG CSR. + ----------------------------------------------------------------- + + if (configWrite = '1') then + componentTag <= configDataWrite; + end if; + + configDataReadInternal <= componentTag; + + when x"000070" => + ----------------------------------------------------------------- + -- Standard Route Configuration Destination ID Select CSR. + ----------------------------------------------------------------- + + if (configWrite = '1') then + -- Write the address to access the routing table. + routeTableAddress <= configDataWrite(10 downto 0); + end if; + + configDataReadInternal(31 downto 11) <= (others => '0'); + configDataReadInternal(10 downto 0) <= routeTableAddress; + + when x"000074" => + ----------------------------------------------------------------- + -- Standard Route Configuration Port Select CSR. + ----------------------------------------------------------------- + + if (configWrite = '1') then + -- Write the port information for the address selected by the + -- above register. + routeTableWrite <= '1'; + routeTablePortWrite <= configDataWrite(7 downto 0); + end if; + + configDataReadInternal(31 downto 8) <= (others => '0'); + configDataReadInternal(7 downto 0) <= routeTablePortRead; + + when x"000078" => + ----------------------------------------------------------------- + -- Standard Route Default Port CSR. + ----------------------------------------------------------------- + + if (configWrite = '1') then + -- Write the default route device id. + routeTablePortDefault <= configDataWrite(7 downto 0); + end if; + + configDataReadInternal(31 downto 8) <= (others => '0'); + configDataReadInternal(7 downto 0) <= routeTablePortDefault; + + when x"000100" => + ----------------------------------------------------------------- + -- Extended features. LP-Serial Register Block Header. + ----------------------------------------------------------------- + + -- One feature only, 0x0003=Generic End Point Free Device. + configDataReadInternal(31 downto 16) <= x"0000"; + configDataReadInternal(15 downto 0) <= x"0003"; + + when x"000120" => + ----------------------------------------------------------------- + -- Port Link Timeout Control CSR. + ----------------------------------------------------------------- + + if (configWrite = '1') then + portLinkTimeout <= configDataWrite(31 downto 8); + end if; + + configDataReadInternal(31 downto 8) <= portLinkTimeout; + configDataReadInternal(7 downto 0) <= x"00"; + + when x"00013c" => + ----------------------------------------------------------------- + -- Port General Control CSR. + ----------------------------------------------------------------- + + if (configWrite = '1') then + discovered <= configDataWrite(29); + end if; + + configDataReadInternal(31 downto 30) <= "00"; + configDataReadInternal(29) <= discovered; + configDataReadInternal(28 downto 0) <= (others => '0'); + + when others => + ----------------------------------------------------------------- + -- Other port specific registers. + ----------------------------------------------------------------- + + -- Make sure the output is always set to something. + configDataReadInternal <= (others=>'0'); + + -- Iterate through all active ports. + for portIndex in 0 to SWITCH_PORTS-1 loop + + if(unsigned(configAddress) = (x"000148" + (x"000020"*portIndex))) then + ----------------------------------------------------------------- + -- Port N Local ackID CSR. + ----------------------------------------------------------------- + if (configWrite = '1') then + localAckIdWrite_o(portIndex) <= '1'; + clrOutstandingAckId_o(portIndex) <= configDataWrite(31); + inboundAckId_o(portIndex) <= configDataWrite(28 downto 24); + outstandingAckId_o(portIndex) <= configDataWrite(12 downto 8); + outboundAckId_o(portIndex) <= configDataWrite(4 downto 0); + end if; + configDataReadInternal(31 downto 29) <= (others => '0'); + configDataReadInternal(28 downto 24) <= inboundAckId_i(portIndex); + configDataReadInternal(23 downto 13) <= (others => '0'); + configDataReadInternal(12 downto 8) <= outstandingAckId_i(portIndex); + configDataReadInternal(7 downto 5) <= (others => '0'); + configDataReadInternal(4 downto 0) <= outboundAckId_i(portIndex); + + elsif(unsigned(configAddress) = (x"000154" + (x"000020"*portIndex))) then + ----------------------------------------------------------------- + -- Port N Control 2 CSR. + ----------------------------------------------------------------- + configDataReadInternal <= (others => '0'); + + elsif(unsigned(configAddress) = (x"000158" + (x"000020"*portIndex))) then + ----------------------------------------------------------------- + -- Port N Error and Status CSR. + ----------------------------------------------------------------- + -- Idle Sequence 2 Support. + configDataReadInternal(31) <= '0'; + + -- Idle Sequence 2 Enable. + configDataReadInternal(30) <= '0'; + + -- Idle Sequence. + configDataReadInternal(29) <= '0'; + + -- Reserved. + configDataReadInternal(28) <= '0'; + + -- Flow Control Mode. + configDataReadInternal(27) <= '0'; + + -- Reserved. + configDataReadInternal(26 downto 21) <= (others => '0'); + + -- Output retry-encountered. + configDataReadInternal(20) <= '0'; + + -- Output retried. + configDataReadInternal(19) <= '0'; + + -- Output retried-stopped. + configDataReadInternal(18) <= '0'; + + -- Output error-encountered. + configDataReadInternal(17) <= '0'; + + -- Output error-stopped. + configDataReadInternal(16) <= '0'; + + -- Reserved. + configDataReadInternal(15 downto 11) <= (others => '0'); + + -- Input retry-stopped. + configDataReadInternal(10) <= '0'; + + -- Input error-encountered. + configDataReadInternal(9) <= '0'; + + -- Input error-stopped. + configDataReadInternal(8) <= '0'; + + -- Reserved. + configDataReadInternal(7 downto 5) <= (others => '0'); + + -- Port-write pending. + configDataReadInternal(4) <= '0'; + + -- Port unavailable. + configDataReadInternal(3) <= '0'; + + -- Port error. + configDataReadInternal(2) <= '0'; + + -- Port OK. + configDataReadInternal(1) <= linkInitialized_i(portIndex); + + -- Port uninitialized. + configDataReadInternal(0) <= not linkInitialized_i(portIndex); + + elsif(unsigned(configAddress) = (x"00015c" + (x"000020"*portIndex))) then + ----------------------------------------------------------------- + -- Port N Control CSR. + ----------------------------------------------------------------- + + -- Port Width Support. + configDataReadInternal(31 downto 30) <= (others=>'0'); + + -- Initialized Port Width. + configDataReadInternal(29 downto 27) <= (others=>'0'); + + -- Port Width Override. + configDataReadInternal(26 downto 24) <= (others=>'0'); + + -- Port disable. + configDataReadInternal(23) <= '0'; + + -- Output Port Enable. + if (configWrite = '1') then + outputPortEnable(portIndex) <= configDataWrite(22); + end if; + configDataReadInternal(22) <= outputPortEnable(portIndex); + + -- Input Port Enable. + if (configWrite = '1') then + inputPortEnable(portIndex) <= configDataWrite(21); + end if; + configDataReadInternal(21) <= inputPortEnable(portIndex); + + -- Error Checking Disabled. + configDataReadInternal(20) <= '0'; + + -- Multicast-event Participant. + configDataReadInternal(19) <= '0'; + + -- Reserved. + configDataReadInternal(18) <= '0'; + + -- Enumeration Boundry. + configDataReadInternal(17) <= '0'; + + -- Reserved. + configDataReadInternal(16) <= '0'; + + -- Extended Port Width Override. + configDataReadInternal(15 downto 14) <= (others=>'0'); + + -- Extended Port Width Support. + configDataReadInternal(13 downto 12) <= (others=>'0'); + + -- Implementation defined. + configDataReadInternal(11 downto 4) <= (others=>'0'); + + -- Reserved. + configDataReadInternal(3 downto 1) <= (others=>'0'); + + -- Port Type. + configDataReadInternal(0) <= '1'; + end if; + end loop; + + end case; + end if; + else + -- Config memory not enabled. + end if; + end if; + end process; + +end architecture; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +entity RouteTableInterconnect is + generic( + WIDTH : natural range 1 to 256 := 8); + port( + clk : in std_logic; + areset_n : in std_logic; + + stb_i : in Array1(WIDTH-1 downto 0); + addr_i : in Array16(WIDTH-1 downto 0); + dataM_o : out Array8(WIDTH-1 downto 0); + ack_o : out Array1(WIDTH-1 downto 0); + + stb_o : out std_logic; + addr_o : out std_logic_vector(15 downto 0); + dataS_i : in std_logic_vector(7 downto 0); + ack_i : in std_logic); +end entity; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +architecture RouteTableInterconnectImpl of RouteTableInterconnect is + signal activeCycle : std_logic; + signal selectedMaster : natural range 0 to WIDTH-1; +begin + + ----------------------------------------------------------------------------- + -- Arbitration. + ----------------------------------------------------------------------------- + Arbiter: process(areset_n, clk) + begin + if (areset_n = '0') then + activeCycle <= '0'; + selectedMaster <= 0; + elsif (clk'event and clk = '1') then + if (activeCycle = '0') then + for i in 0 to WIDTH-1 loop + if (stb_i(i) = '1') then + activeCycle <= '1'; + selectedMaster <= i; + end if; + end loop; + else + if (stb_i(selectedMaster) = '0') then + activeCycle <= '0'; + end if; + end if; + end if; + end process; + + ----------------------------------------------------------------------------- + -- Interconnection. + ----------------------------------------------------------------------------- + stb_o <= stb_i(selectedMaster); + addr_o <= addr_i(selectedMaster); + + Interconnect: for i in 0 to WIDTH-1 generate + dataM_o(i) <= dataS_i; + ack_o(i) <= ack_i when (selectedMaster = i) else '0'; + end generate; + +end architecture; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +entity SwitchPortInterconnect is + generic( + WIDTH : natural range 1 to 256 := 8); + port( + clk : in std_logic; + areset_n : in std_logic; + + masterCyc_i : in Array1(WIDTH-1 downto 0); + masterStb_i : in Array1(WIDTH-1 downto 0); + masterWe_i : in Array1(WIDTH-1 downto 0); + masterAddr_i : in Array10(WIDTH-1 downto 0); + masterData_i : in Array32(WIDTH-1 downto 0); + masterData_o : out Array1(WIDTH-1 downto 0); + masterAck_o : out Array1(WIDTH-1 downto 0); + + slaveCyc_o : out Array1(WIDTH-1 downto 0); + slaveStb_o : out Array1(WIDTH-1 downto 0); + slaveWe_o : out Array1(WIDTH-1 downto 0); + slaveAddr_o : out Array10(WIDTH-1 downto 0); + slaveData_o : out Array32(WIDTH-1 downto 0); + slaveData_i : in Array1(WIDTH-1 downto 0); + slaveAck_i : in Array1(WIDTH-1 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +architecture SwitchPortInterconnectImpl of SwitchPortInterconnect is + --component ChipscopeIcon1 is + -- port ( + -- CONTROL0 : inout STD_LOGIC_VECTOR ( 35 downto 0 ) + -- ); + --end component; + --component ChipscopeIlaWb is + -- port ( + -- CLK : in STD_LOGIC := 'X'; + -- TRIG0 : in STD_LOGIC_VECTOR ( 46 downto 0); + -- CONTROL : inout STD_LOGIC_VECTOR ( 35 downto 0 ) + -- ); + --end component; + --signal control : std_logic_vector(35 downto 0); + --signal trig : std_logic_vector(46 downto 0); + + signal activeCycle : std_logic; + signal selectedMaster : natural range 0 to WIDTH-1; + signal selectedSlave : natural range 0 to WIDTH-1; + +begin + + ----------------------------------------------------------------------------- + -- Arbitration process. + ----------------------------------------------------------------------------- + + RoundRobinArbiter: process(areset_n, clk) + variable index : natural range 0 to WIDTH-1; + begin + if (areset_n = '0') then + activeCycle <= '0'; + selectedMaster <= 0; + elsif (clk'event and clk = '1') then + -- Check if a cycle is ongoing. + if (activeCycle = '0') then + -- No ongoing cycles. + + -- Iterate through all ports and check if any new cycle has started. + for i in 0 to WIDTH-1 loop + if ((selectedMaster+i) >= WIDTH) then + index := (selectedMaster+i) - WIDTH; + else + index := (selectedMaster+i); + end if; + + if (masterCyc_i(index) = '1') then + activeCycle <= '1'; + selectedMaster <= index; + end if; + end loop; + else + -- Ongoing cycle. + + -- Check if the cycle has ended. + if (masterCyc_i(selectedMaster) = '0') then + -- Cycle has ended. + activeCycle <= '0'; + + -- Check if a new cycle has started from another master. + -- Start to check from the one that ended its cycle, this way, the + -- ports will be scheduled like round-robin. + for i in 0 to WIDTH-1 loop + if ((selectedMaster+i) >= WIDTH) then + index := (selectedMaster+i) - WIDTH; + else + index := (selectedMaster+i); + end if; + + if (masterCyc_i(index) = '1') then + activeCycle <= '1'; + selectedMaster <= index; + end if; + end loop; + end if; + end if; + end if; + end process; + + ----------------------------------------------------------------------------- + -- Address decoding. + ----------------------------------------------------------------------------- + + -- Select the last port when the top bit is set. + -- The last port must be the maintenance slave port. + selectedSlave <= WIDTH-1 when masterAddr_i(selectedMaster)(9) = '1' else + to_integer(unsigned(masterAddr_i(selectedMaster)(8 downto 1))); + + ----------------------------------------------------------------------------- + -- Interconnection matrix. + ----------------------------------------------------------------------------- + Interconnect: for i in 0 to WIDTH-1 generate + slaveCyc_o(i) <= masterCyc_i(selectedMaster) when (selectedSlave = i) else '0'; + slaveStb_o(i) <= masterStb_i(selectedMaster) when (selectedSlave = i) else '0'; + slaveWe_o(i) <= masterWe_i(selectedMaster); + slaveAddr_o(i) <= masterAddr_i(selectedMaster); + slaveData_o(i) <= masterData_i(selectedMaster); + masterData_o(i) <= slaveData_i(selectedSlave); + masterAck_o(i) <= slaveAck_i(selectedSlave) when (selectedMaster = i) else '0'; + end generate; + + ----------------------------------------------------------------------------- + -- Chipscope debugging probe. + ----------------------------------------------------------------------------- + --trig <= masterCyc_i(selectedMaster) & masterStb_i(selectedMaster) & + -- masterWe_i(selectedMaster) & masterAddr_i(selectedMaster) & + -- masterData_i(selectedMaster) & slaveData_i(selectedSlave) & + -- slaveAck_i(selectedSlave); + --ChipscopeIconInst: ChipscopeIcon1 + -- port map(CONTROL0=>control); + --ChipscopeIlaInst: ChipscopeIlaWb + -- port map(CLK=>clk, TRIG0=>trig, CONTROL=>control); + +end architecture; + + +
2.0.0-alpha/rtl/vhdl/RioSwitch.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: 2.0.0-alpha/bench/vhdl/TestRioSerial.vhd =================================================================== --- 2.0.0-alpha/bench/vhdl/TestRioSerial.vhd (nonexistent) +++ 2.0.0-alpha/bench/vhdl/TestRioSerial.vhd (revision 23) @@ -0,0 +1,2536 @@ +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- Description +-- Contains automatic simulation test code to verify a RioSerial implementation. +-- +-- To Do: +-- - +-- +-- Author(s): +-- - Magnus Rosenius, magro732@opencores.org +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------- + + +------------------------------------------------------------------------------- +-- TestRioSerial. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library std; +use std.textio.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- Entity for TestRioSerial. +------------------------------------------------------------------------------- +entity TestRioSerial is +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for TestUart. +------------------------------------------------------------------------------- +architecture TestRioSerialImpl of TestRioSerial is + + component TestSwitchPort is + generic( + NUMBER_WORDS : natural range 1 to 8 := 1); + port( + clk : in std_logic; + areset_n : in std_logic; + + frameValid_i : in std_logic_vector(0 to 63); + frameWrite_i : in RioFrameArray(0 to 63); + frameComplete_o : out std_logic_vector(0 to 63); + + frameExpected_i : in std_logic; + frameRead_i : in RioFrame; + frameReceived_o : out std_logic; + + readFrameEmpty_o : out std_logic; + readFrame_i : in std_logic; + readFrameRestart_i : in std_logic; + readFrameAborted_o : out std_logic; + + readWindowEmpty_o : out std_logic; + readWindowReset_i : in std_logic; + readWindowNext_i : in std_logic; + + readContentEmpty_o : out std_logic; + readContent_i : in std_logic; + readContentEnd_o : out std_logic; + readContentData_o : out std_logic_vector(31 downto 0); + + writeFrameFull_o : out std_logic; + writeFrame_i : in std_logic; + writeFrameAbort_i : in std_logic; + writeContent_i : in std_logic; + writeContentData_i : in std_logic_vector(31 downto 0)); + end component; + + component RioSerial is + generic( + TIMEOUT_WIDTH : natural); + port( + clk : in std_logic; + areset_n : in std_logic; + + portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0); + linkInitialized_o : out std_logic; + inputPortEnable_i : in std_logic; + outputPortEnable_i : in std_logic; + + localAckIdWrite_i : in std_logic; + clrOutstandingAckId_i : in std_logic; + inboundAckId_i : in std_logic_vector(4 downto 0); + outstandingAckId_i : in std_logic_vector(4 downto 0); + outboundAckId_i : in std_logic_vector(4 downto 0); + inboundAckId_o : out std_logic_vector(4 downto 0); + outstandingAckId_o : out std_logic_vector(4 downto 0); + outboundAckId_o : out std_logic_vector(4 downto 0); + + readFrameEmpty_i : in std_logic; + readFrame_o : out std_logic; + readFrameRestart_o : out std_logic; + readFrameAborted_i : in std_logic; + readWindowEmpty_i : in std_logic; + readWindowReset_o : out std_logic; + readWindowNext_o : out std_logic; + readContentEmpty_i : in std_logic; + readContent_o : out std_logic; + readContentEnd_i : in std_logic; + readContentData_i : in std_logic_vector(31 downto 0); + + writeFrameFull_i : in std_logic; + writeFrame_o : out std_logic; + writeFrameAbort_o : out std_logic; + writeContent_o : out std_logic; + writeContentData_o : out std_logic_vector(31 downto 0); + + 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)); + end component; + + constant NUMBER_WORDS : natural range 1 to 4 := 1; + + signal clk : std_logic; + signal areset_n : std_logic; + + signal portLinkTimeout : std_logic_vector(10 downto 0); + signal linkInitialized : std_logic; + signal inputPortEnable : std_logic; + signal outputPortEnable : std_logic; + + signal localAckIdWrite : std_logic; + signal clrOutstandingAckId : std_logic; + signal inboundAckIdWrite : std_logic_vector(4 downto 0); + signal outstandingAckIdWrite : std_logic_vector(4 downto 0); + signal outboundAckIdWrite : std_logic_vector(4 downto 0); + signal inboundAckIdRead : std_logic_vector(4 downto 0); + signal outstandingAckIdRead : std_logic_vector(4 downto 0); + signal outboundAckIdRead : std_logic_vector(4 downto 0); + + signal portInitialized : std_logic; + signal outboundSymbolFull : std_logic; + signal outboundSymbolWrite : std_logic; + signal outboundSymbol : std_logic_vector((2+32)-1 downto 0); + signal inboundSymbolEmpty : std_logic; + signal inboundSymbolRead : std_logic; + signal inboundSymbol : std_logic_vector((2+32)-1 downto 0); + + signal readFrameEmpty : std_logic; + signal readFrame : std_logic; + signal readFrameRestart : std_logic; + signal readFrameAborted : std_logic; + signal readWindowEmpty : std_logic; + signal readWindowReset : std_logic; + signal readWindowNext : std_logic; + signal readContentEmpty : std_logic; + signal readContent : std_logic; + signal readContentEnd : std_logic; + signal readContentData : std_logic_vector(31 downto 0); + + signal writeFrameFull : std_logic; + signal writeFrame : std_logic; + signal writeFrameAbort : std_logic; + signal writeContent : std_logic; + signal writeContentData : std_logic_vector(31 downto 0); + + signal frameValid : std_logic_vector(0 to 63); + signal frameWrite : RioFrameArray(0 to 63); + signal frameComplete : std_logic_vector(0 to 63); + signal frameExpected : std_logic; + signal frameRead : RioFrame; + signal frameReceived : std_logic; + +begin + + ----------------------------------------------------------------------------- + -- Clock generation. + ----------------------------------------------------------------------------- + ClockGenerator: process + begin + clk <= '0'; + wait for 20 ns; + clk <= '1'; + wait for 20 ns; + end process; + + + ----------------------------------------------------------------------------- + -- Serial protocol test driver. + ----------------------------------------------------------------------------- + TestDriver: process + + --------------------------------------------------------------------------- + -- Procedure to receive a symbol. + --------------------------------------------------------------------------- + procedure ReceiveSymbol( + constant symbolType : in std_logic_vector(1 downto 0); + constant symbolContent : in std_logic_vector(31 downto 0) := x"00000000"; + constant acceptIdle : in boolean := true) is + begin + outboundSymbolFull <= '0'; + wait until clk'event and clk = '1' and outboundSymbolWrite = '1'; + + if (acceptIdle) then + while ((outboundSymbol(33 downto 32) = SYMBOL_IDLE) and + (symbolType /= SYMBOL_IDLE)) loop + wait until clk'event and clk = '1' and outboundSymbolWrite = '1'; + end loop; + end if; + + assert symbolType = outboundSymbol(33 downto 32) + report "Missmatching symbol type:expected=" & + integer'image(to_integer(unsigned(symbolType))) & + " got=" & + integer'image(to_integer(unsigned(outboundSymbol(33 downto 32)))) + severity error; + + if (outboundSymbol(33 downto 32) = SYMBOL_CONTROL) then + assert symbolContent(31 downto 8) = outboundSymbol(31 downto 8) + report "Missmatching symbol content:expected=" & + integer'image(to_integer(unsigned(symbolContent(31 downto 8)))) & + " got=" & + integer'image(to_integer(unsigned(outboundSymbol(31 downto 8)))) + severity error; + elsif (outboundSymbol(33 downto 32) = SYMBOL_DATA) then + assert symbolContent(31 downto 0) = outboundSymbol(31 downto 0) + report "Missmatching symbol content:expected=" & + integer'image(to_integer(unsigned(symbolContent(31 downto 0)))) & + " got=" & + integer'image(to_integer(unsigned(outboundSymbol(31 downto 0)))) + severity error; + end if; + + outboundSymbolFull <= '1'; + end procedure; + + --------------------------------------------------------------------------- + -- Procedure to send a symbol. + --------------------------------------------------------------------------- + procedure SendSymbol( + constant symbolType : in std_logic_vector(1 downto 0); + constant symbolContent : in std_logic_vector(31 downto 0) := x"00000000") is + begin + inboundSymbolEmpty <= '0'; + inboundSymbol <= symbolType & symbolContent; + + wait until clk'event and clk = '1' and inboundSymbolRead = '1'; + inboundSymbolEmpty <= '1'; + end procedure; + + --------------------------------------------------------------------------- + -- Process variables. + --------------------------------------------------------------------------- + variable seed1 : positive := 1; + variable seed2 : positive := 1; + variable payload : RioPayload; + + variable frame : RioFrame; + + begin + --------------------------------------------------------------------------- + -- Test case initialization. + --------------------------------------------------------------------------- + + frameValid <= (others=>'0'); + frameExpected <= '0'; + + portLinkTimeout <= (others=>'1'); + inputPortEnable <= '1'; + outputPortEnable <= '1'; + + portInitialized <= '0'; + outboundSymbolFull <= '1'; + inboundSymbolEmpty <= '1'; + inboundSymbol <= (others => '0'); + + localAckIdWrite <= '0'; + clrOutstandingAckId <= '0'; + inboundAckIdWrite <= (others=>'0'); + outstandingAckIdWrite <= (others=>'0'); + outboundAckIdWrite <= (others=>'0'); + + -- Generate a startup reset pulse. + areset_n <= '0'; + wait until clk'event and clk = '1'; + wait until clk'event and clk = '1'; + areset_n <= '1'; + wait until clk'event and clk = '1'; + wait until clk'event and clk = '1'; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioSerial"); + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioSerial-TC1"); + PrintS("Description: Test idle-sequence transmission at startup."); + PrintS("Requirement: XXXXX"); + PrintS("-----------------------------------------------------------------"); + PrintS("Step 1:"); + PrintS("Action: Read transmission port."); + PrintS("Result: Idle sequence symbols should be read."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC1-Step1"); + --------------------------------------------------------------------------- + + -- Make sure only idle-sequences are transmitted at startup. + for i in 0 to 1024 loop + ReceiveSymbol(SYMBOL_IDLE); + end loop; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioSerial-TC2"); + PrintS("Description: Test idle-sequence and status symbol transmission"); + PrintS(" when the port has been initialized."); + PrintS("Requirement: XXXXX"); + PrintS("-----------------------------------------------------------------"); + PrintS("Step 1:"); + PrintS("Action: Set port initialized and read transmission port."); + PrintS("Result: Idle sequence and status symbols should be read."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC2-Step1"); + --------------------------------------------------------------------------- + + -- Initialize the port to trigger a change of state. + portInitialized <= '1'; + + -- The transmitter should send idle sequences at startup and a status once + -- in a while. + for i in 0 to 256 loop + ReceiveSymbol(SYMBOL_IDLE); + end loop; + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_NOP, "000"), + false); + for i in 0 to 254 loop + ReceiveSymbol(SYMBOL_IDLE); + end loop; + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_NOP, "000"), + false); + for i in 0 to 254 loop + ReceiveSymbol(SYMBOL_IDLE); + end loop; + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_NOP, "000"), + false); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 2:"); + PrintS("Action: Toggle port initialized pin and check that no status "); + PrintS(" symbols are transmitted when uninitialized."); + PrintS("Result: Only idle sequences should be read when uninitialized."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC2-Step2"); + --------------------------------------------------------------------------- + + -- Deassert the port initialized flag. + portInitialized <= '0'; + + -- Make sure only idle-sequences are transmitted at startup. + for i in 0 to 1024 loop + ReceiveSymbol(SYMBOL_IDLE); + end loop; + + -- Initialize the port to trigger a change of state. + portInitialized <= '1'; + + -- The transmitter should send idle sequences at startup and a status once + -- in a while. + for i in 0 to 256 loop + ReceiveSymbol(SYMBOL_IDLE); + end loop; + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_NOP, "000"), + false); + for i in 0 to 254 loop + ReceiveSymbol(SYMBOL_IDLE); + end loop; + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_NOP, "000"), + false); + for i in 0 to 254 loop + ReceiveSymbol(SYMBOL_IDLE); + end loop; + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_NOP, "000"), + false); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 3:"); + PrintS("Action: Send one error free status symbol to trigger the "); + PrintS(" transmission of status symbols with a higher frequency."); + PrintS("Result: Idle sequence and status symbols should be read but "); + PrintS(" status symbols should be recived more often."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC2-Step3"); + --------------------------------------------------------------------------- + + -- A received error-free status triggers transmission of status symbols in + -- a more rapid past. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_NOP, "000")); + + -- The transmitter should send at least 15 additional statuses after + -- receiving an error free status. + for j in 0 to 15 loop + for i in 0 to 15 loop + ReceiveSymbol(SYMBOL_IDLE); + end loop; + + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_NOP, "000"), + false); + end loop; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 4:"); + PrintS("Action: Send one errornous status symbol to restart the status "); + PrintS(" counting."); + PrintS("Result: Idle sequence and status symbols should be read but "); + PrintS(" status symbols should still be received more often."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC2-Step4"); + --------------------------------------------------------------------------- + + -- REMARK: Add this... + PrintR("Not implemented."); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 5:"); + PrintS("Action: Send one errornous status symbol to restart the status "); + PrintS(" counting."); + PrintS("Result: Idle sequence and status symbols should be read but "); + PrintS(" status symbols should still be received more often."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC2-Step5"); + --------------------------------------------------------------------------- + + -- Make the link fully initialized by sending 7 additional statuses. + for i in 0 to 6 loop + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_NOP, "000")); + end loop; + + -- Tick the transmitter by reading it and check that the link is initialized. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_IDLE); + wait until linkInitialized = '1'; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioSerial-TC3"); + PrintS("Description: Test port reception."); + PrintS("Requirement: XXXXX"); + PrintS("-----------------------------------------------------------------"); + PrintS("Step 1:"); + PrintS("Action: Send an inbound frame with pad after the CRC."); + PrintS("Result: The frame should end up in a frame buffer."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC3-Step1"); + --------------------------------------------------------------------------- + + -- Create the frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 1; + frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameExpected <= '1'; + frameRead <= frame; + + -- Start the reception of a frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Send the data symbols of the frame. + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- End the reception of the frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Check that the frame has been received in the frame buffer. + wait until frameReceived = '1'; + frameExpected <= '0'; + + -- Receive an idle symbol left in the FIFO before the ack was generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- Receive acknowledge for the transmitted frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00000", "11111", + STYPE1_NOP, "000")); + + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 2:"); + PrintS("Action: Send an inbound frame without a pad after the CRC."); + PrintS("Result: The frame should end up in a frame buffer."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC3-Step2"); + --------------------------------------------------------------------------- + + -- Create the frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 2; + frame := RioFrameCreate(ackId=>"00001", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameExpected <= '1'; + frameRead <= frame; + + -- Start the reception of a frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Send the data symbols of the frame. + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- End the reception of the frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Check that the frame has been received in the frame buffer. + wait until frameReceived = '1'; + frameExpected <= '0'; + + -- Receive an idle symbol left in the FIFO before the ack was generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- Receive acknowledge for the transmited frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00001", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 3:"); + PrintS("Action: Send an inbound frame with maximum size."); + PrintS("Result: The frame should end up in a frame buffer."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC3-Step3"); + --------------------------------------------------------------------------- + + -- Create the frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 133; + frame := RioFrameCreate(ackId=>"00010", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameExpected <= '1'; + frameRead <= frame; + + -- Start the reception of a frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Send the data symbols of the frame. + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- End the reception of the frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Check that the frame has been received in the frame buffer. + wait until frameReceived = '1'; + frameExpected <= '0'; + + -- Receive an idle symbol left in the FIFO before the ack was generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- Receive acknowledge for the transmitted frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00010", "11111", + STYPE1_NOP, "000")); + + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 4:"); + PrintS("Action: Send two packets without end-of-packet in between."); + PrintS("Result: Both packets should be accepted."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC3-Step4"); + --------------------------------------------------------------------------- + + -- Create the first frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 10; + frame := RioFrameCreate(ackId=>"00011", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameExpected <= '1'; + frameRead <= frame; + + -- Start the reception of a frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Send the data symbols of the frame. + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- Start the reception of a frame, implicitly ending the previous. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Check that the frame has been received in the frame buffer. + wait until frameReceived = '1'; + frameExpected <= '0'; + wait until clk'event and clk = '1'; + + -- Receive an idle symbol left in the FIFO before the ack was generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- Receive acknowledge for the transmitted frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00011", "11111", + STYPE1_NOP, "000")); + + -- Create the second frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 13; + frame := RioFrameCreate(ackId=>"00100", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameExpected <= '1'; + frameRead <= frame; + + -- Send the data symbols of the frame. + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- End the reception of the frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Check that the frame has been received in the frame buffer. + wait until frameReceived = '1'; + frameExpected <= '0'; + + -- Receive an idle symbol left in the FIFO before the ack was generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- Receive acknowledge for the transmitted frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00100", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 5:"); + PrintS("Action: Start to send a packet. Abort it with stomp. Then send "); + PrintS(" another packet."); + PrintS("Result: The first packet should be discarded and the second should"); + PrintS(" be accepted. The retried packet should be acknowledged."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC3-Step5"); + --------------------------------------------------------------------------- + + -- Create the frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 7; + frame := RioFrameCreate(ackId=>"00101", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameExpected <= '1'; + frameRead <= frame; + + -- Start the reception of a frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Send the data symbols of the frame. + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- Abort the reception of the frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_STOMP, "000")); + + -- Dont expect the aborted frame anymore. + frameExpected <= '0'; + + -- Receive an idle symbol left in the FIFO before the retry was generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- Receive acknowledge for the transmitted frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_RETRY, "00101", "11111", + STYPE1_NOP, "000")); + + -- Acknowledge the canceled packet. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_RESTART_FROM_RETRY, "000")); + + -- Create a new frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 8; + frame := RioFrameCreate(ackId=>"00101", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameExpected <= '1'; + frameRead <= frame; + + -- Start the reception of a frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Send the data symbols of the frame. + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- Abort the reception of the frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Check that the frame has been received in the frame buffer. + wait until frameReceived = '1'; + frameExpected <= '0'; + + -- Receive an idle symbol left in the FIFO before the ack was generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- Receive acknowledge for the transmitted frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00101", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 6:"); + PrintS("Action: Start to send a packet but dont send any payload. Abort it"); + PrintS(" with stomp. Then send another packet."); + PrintS("Result: The first packet should be discarded and the second should"); + PrintS(" be accepted. The retried packet should be acknowledged."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC3-Step6"); + --------------------------------------------------------------------------- + + -- Start the reception of a frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Abort the reception of the frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_STOMP, "000")); + + -- Receive an idle symbol left in the FIFO before the retry was generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- Receive acknowledge for the transmitted frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_RETRY, "00110", "11111", + STYPE1_NOP, "000")); + + -- Acknowledge the canceled packet. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_RESTART_FROM_RETRY, "000")); + + -- Create a new frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 8; + frame := RioFrameCreate(ackId=>"00110", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameExpected <= '1'; + frameRead <= frame; + + -- Start the reception of a frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Send the data symbols of the frame. + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- Abort the reception of the frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Check that the frame has been received in the frame buffer. + wait until frameReceived = '1'; + frameExpected <= '0'; + + -- Receive an idle symbol left in the FIFO before the ack was generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- Receive acknowledge for the transmitted frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00110", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 7:"); + PrintS("Action: Start to send a packet with payload, then send a "); + PrintS(" link-request. Then send another packet."); + PrintS("Result: The first packet should be canceled without any "); + PrintS(" confirmation and a link-response should be returned. The"); + PrintS(" second packet should be accepted."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC3-Step7"); + --------------------------------------------------------------------------- + + -- Create a new frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 9; + frame := RioFrameCreate(ackId=>"00111", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameExpected <= '1'; + frameRead <= frame; + + -- Start the reception of a frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Send the data symbols of the frame. + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- Send a link-request/input-status to abort the current packet. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_LINK_REQUEST, "100")); + + -- Receive an idle symbol left in the FIFO before the ack was generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- The frame should be canceled by the link-request, dont expect it anymore. + frameExpected <= '0'; + + -- Receive link-response indicating normal operation and expected ackId. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00111", "10000", + STYPE1_NOP, "000")); + + -- Create a new frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 10; + frame := RioFrameCreate(ackId=>"00111", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameExpected <= '1'; + frameRead <= frame; + + -- Start the reception of a frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Send the data symbols of the frame. + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- Abort the reception of the frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Check that the frame has been received in the frame buffer. + wait until frameReceived = '1'; + frameExpected <= '0'; + + -- Receive an idle symbol left in the FIFO before the ack was generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- Receive acknowledge for the transmitted frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00111", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 8:"); + PrintS("Action: Start to send a packet, no payload, then send a "); + PrintS(" link-request. Then send another packet."); + PrintS("Result: The first packet should be canceled without any "); + PrintS(" confirmation and a link-response should be returned. The"); + PrintS(" second packet should be accepted."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC3-Step8"); + --------------------------------------------------------------------------- + + -- Expect an empty packet to be aborted. + frameExpected <= '1'; + + -- Start the reception of a frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Send a link-request/input-status to abort the current packet. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_LINK_REQUEST, "100")); + + -- Receive an idle symbol left in the FIFO before the ack was generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- Dont expect any frames anymore. + frameExpected <= '0'; + + -- Receive link-response indicating normal operation and expected ackId. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01000", "10000", + STYPE1_NOP, "000")); + + -- Create a new frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 11; + frame := RioFrameCreate(ackId=>"01000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameExpected <= '1'; + frameRead <= frame; + + -- Start the reception of a frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Send the data symbols of the frame. + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- Abort the reception of the frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Check that the frame has been received in the frame buffer. + wait until frameReceived = '1'; + frameExpected <= '0'; + + -- Receive an idle symbol left in the FIFO before the ack was generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- Receive acknowledge for the transmitted frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01000", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 9:"); + PrintS("Action: Send a packet when no buffers is available. Reset receiver"); + PrintS(" with link-request."); + PrintS("Result: A packet-retry should be transmitted and receiver should"); + PrintS(" enter input-retry-stopped."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC3-Step9"); + --------------------------------------------------------------------------- + + -- Create a new frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 11; + frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + + -- Start the reception of a frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + SendSymbol(SYMBOL_DATA, frame.payload(0)); + + -- Receive notification about that the packet needs to be retried. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_RETRY, "01001", "11111", + STYPE1_NOP, "000")); + + -- Check the status of the input port and verify the input-retry-stopped state. + -- This should also set the receiver into normal operation. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_LINK_REQUEST, "100")); + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "00100", + STYPE1_NOP, "000")); + + -- Check the status of the input port and verify the input-retry-stopped state. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_LINK_REQUEST, "100")); + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "10000", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 10:"); + PrintS("Action: Send a packet when no buffers is available. Reset receiver"); + PrintS(" with restart-from-retry."); + PrintS("Result: A packet-retry should be transmitted and receiver should"); + PrintS(" enter input-retry-stopped."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC3-Step10"); + --------------------------------------------------------------------------- + + -- Create a new frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 11; + frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + + -- Start the reception of a frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + SendSymbol(SYMBOL_DATA, frame.payload(0)); + + -- Receive notification about that the packet needs to be retried. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_RETRY, "01001", "11111", + STYPE1_NOP, "000")); + + -- Acknowledge the retried packet. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_RESTART_FROM_RETRY, "000")); + + -- Check the status of the input port and verify the input-retry-stopped state. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_LINK_REQUEST, "100")); + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "10000", + STYPE1_NOP, "000")); + + -- Always receive a status after a link response when leaving input-error-stopped. +-- ReceiveSymbol(SYMBOL_CONTROL, +-- RioControlSymbolCreate(STYPE0_STATUS, "01001", "11111", +-- STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 11:"); + PrintS("Action: Start a new packet when in input-retry-stopped state."); + PrintS("Result: The packet should be discarded."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC3-Step11"); + --------------------------------------------------------------------------- + + -- Create a new frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 11; + frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + + -- Start the reception of a frame. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + SendSymbol(SYMBOL_DATA, frame.payload(0)); + + -- Receive notification about that the packet needs to be retried. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_RETRY, "01001", "11111", + STYPE1_NOP, "000")); + + -- Create a packet and send it. It should be discarded. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 12; + frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Acknowledge the retried packet. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_RESTART_FROM_RETRY, "000")); + + -- Create a packet and send it. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 13; + frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameExpected <= '1'; + frameRead <= frame; + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_END_OF_PACKET, "000")); + wait until frameReceived = '1'; + frameExpected <= '0'; + + -- Receive acknowledge for the transmitted frame. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01001", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 12:"); + PrintS("Action: Send an erronous control-symbol. Then restore with"); + PrintS(" link-request."); + PrintS("Result: Receiver should enter input-error-stopped and return to"); + PrintS(" normal operation after the link-request was receiver."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC3-Step12"); + --------------------------------------------------------------------------- + + -- Create, corrupt and send a control symbol. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000") xor x"00100000"); + + -- Receive a packet-not-accepted indicating error in control-symbol crc. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_NOT_ACCEPTED, "00000", "00010", + STYPE1_NOP, "000")); + + -- Create a packet and send it. It should be discarded. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 14; + frame := RioFrameCreate(ackId=>"01010", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Make the receiver go back to normal operation by sending a link-request. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_LINK_REQUEST, "100")); + + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01010", "00101", + STYPE1_NOP, "000")); + + -- Always receive a status after a link response when leaving input-error-stopped. +-- ReceiveSymbol(SYMBOL_CONTROL, +-- RioControlSymbolCreate(STYPE0_STATUS, "01010", "11111", +-- STYPE1_NOP, "000")); + + -- Create a packet and send it. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 15; + frame := RioFrameCreate(ackId=>"01010", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameExpected <= '1'; + frameRead <= frame; + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_END_OF_PACKET, "000")); + wait until frameReceived = '1'; + frameExpected <= '0'; + + -- Receive acknowledge for the transmitted frame. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01010", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 13:"); + PrintS("Action: Send an erronous packet. Then restore with link-request."); + PrintS("Result: Receiver should enter input-error-stopped and return to"); + PrintS(" normal operation after the link-request was receiver."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC3-Step13"); + --------------------------------------------------------------------------- + + -- Create a packet and send it with a bit error. It should be discarded. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 15; + frame := RioFrameCreate(ackId=>"01011", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frame.payload(0) := frame.payload(0) xor x"00000010"; + frameExpected <= '1'; + frameRead <= frame; + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Receive a packet-not-accepted indicating error in control-symbol crc. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_NOT_ACCEPTED, "00000", "00100", + STYPE1_NOP, "000")); + + -- Dont expect any frame anymore. + frameExpected <= '0'; + + -- Make the receiver go back to normal operation by sending a link-request. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_LINK_REQUEST, "100")); + + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01011", "00101", + STYPE1_NOP, "000")); + + -- Send a new frame without error. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 16; + frame := RioFrameCreate(ackId=>"01011", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameExpected <= '1'; + frameRead <= frame; + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frame.length-1 loop + SendSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111", + STYPE1_END_OF_PACKET, "000")); + wait until frameReceived = '1'; + frameExpected <= '0'; + + -- Receive acknowledge for the transmitted frame. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01011", "11111", + STYPE1_NOP, "000")); + + -- REMARK: Complete with some more error situations: invalid ackId, too + -- short packet, too long packet, etc... + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioSerial-TC4"); + PrintS("Description: Test port transmission."); + PrintS("Requirement: XXXXX"); + PrintS("-----------------------------------------------------------------"); + PrintS("Step 1:"); + PrintS("Action: Send an outbound frame."); + PrintS("Result: The frame should be read from the frame buffer and "); + PrintS(" received as symbols."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-Step1"); + --------------------------------------------------------------------------- + + -- Create the frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 3; + frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameValid(0) <= '1'; + frameWrite(0) <= frame; + + -- Make sure the transmitter fills in the correct ackId and dont use the + -- one in the input packet. + frameWrite(0).payload(0)(31 downto 27) <= "UUUUU"; + + -- Receive an idle symbol left in the FIFO before the start of the frame was + -- generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- Receive the start of the frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Receive the data symbols of the frame. + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- Wait for the frame to complete. + wait until frameComplete(0) = '1' and clk'event and clk = '1'; + frameValid(0) <= '0'; + + -- Receive the end of the frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Send acknowledge that the frame was received. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00000", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 2:"); + PrintS("Action: Send an outbound packet with maximum length."); + PrintS("Result: The packet should be fragmented and received in symbols."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-Step2"); + --------------------------------------------------------------------------- + + -- Create the frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 133; + frame := RioFrameCreate(ackId=>"00001", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameValid(1) <= '1'; + frameWrite(1) <= frame; + + -- Receive an idle symbol left in the FIFO before the start of the frame was + -- generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- Receive the start of the frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Receive the data symbols of the frame. + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- Wait for the frame to complete. + wait until frameComplete(1) = '1' and clk'event and clk = '1'; + frameValid(1) <= '0'; + + -- Receive the end of the frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Send acknowledge that the frame was received. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00001", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 3:"); + PrintS("Action: Send a packet and confirm it with packet-retry."); + PrintS("Result: A restart-from-retry should be transmitted and the packet"); + PrintS(" should be retransmitted."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-Step3"); + --------------------------------------------------------------------------- + + -- Create the frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 4; + frame := RioFrameCreate(ackId=>"00010", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameValid(2) <= '1'; + frameWrite(2) <= frame; + + -- Receive an idle symbol left in the FIFO before the start of the frame was + -- generated. + ReceiveSymbol(SYMBOL_IDLE); + + -- Receive the start of the frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Receive the data symbols of the frame. + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- Receive the end of the frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Send packet-retry that the frame should be retransmitted. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_RETRY, "00010", "11111", + STYPE1_NOP, "000")); + + -- Receive the acknowledgement for the retransmission. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_RESTART_FROM_RETRY, "000")); + + -- Receive the start of the retransmitted frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Receive the data symbols of the retransmitted frame. + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- Wait for the frame to complete. + wait until frameComplete(2) = '1' and clk'event and clk = '1'; + frameValid(2) <= '0'; + + -- Receive the end of the retransmitted frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Send acknowledge that the frame was received. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00010", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 4:"); + PrintS("Action: Send a packet and confirm it with packet-not-accepted. "); + PrintS("Result: A link-request should be transmitted and the packet should"); + PrintS(" be retransmitted."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-Step4"); + --------------------------------------------------------------------------- + + -- Create the frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 5; + frame := RioFrameCreate(ackId=>"00011", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameValid(3) <= '1'; + frameWrite(3) <= frame; + + -- Receive the start of the frame. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Receive the data symbols of the frame. + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- Receive the end of the frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Send packet-retry that the frame should be retransmitted. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_NOT_ACCEPTED, "00000", "11111", + STYPE1_NOP, "000")); + + -- Receive the acknowledgement for the retransmission. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_LINK_REQUEST, "100")); + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00011", "11111", + STYPE1_NOP, "000")); + + -- Receive the start of the retransmitted frame. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + + -- Receive the data symbols of the retransmitted frame. + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- Wait for the frame to complete. + wait until frameComplete(3) = '1' and clk'event and clk = '1'; + frameValid(3) <= '0'; + + -- Receive the end of the retransmitted frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Send acknowledge that the frame was received. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00011", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 5:"); + PrintS("Action: Let a packet timeout expire. Then answer with link-response."); + PrintS("Result: A link-request should be transmitted and the packet should"); + PrintS(" be retransmitted."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-Step5"); + --------------------------------------------------------------------------- + + -- Create the frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 5; + frame := RioFrameCreate(ackId=>"00100", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameValid(4) <= '1'; + frameWrite(4) <= frame; + + -- Receive the frame. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Wait a while to let the timer expire and receive the link-request. + for i in 0 to 2048 loop + wait until clk'event and clk = '1'; + end loop; + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_LINK_REQUEST, "100")); + + -- Send a link-response to make the transmitter to back to normal mode. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00100", "11111", + STYPE1_NOP, "000")); + + -- Receive the retransmitted frame. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + -- Wait for the frame to complete. + wait until frameComplete(4) = '1' and clk'event and clk = '1'; + frameValid(4) <= '0'; + + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Send acknowledge that the frame was received. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00100", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 6:"); + PrintS("Action: Let a packet timeout expire. Then answer with link-response"); + Prints(" that indicates that the packet was received."); + PrintS("Result: A link-request should be transmitted and the packet should"); + PrintS(" not be retransmitted."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-Step6"); + --------------------------------------------------------------------------- + + -- Create the frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 6; + frame := RioFrameCreate(ackId=>"00101", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameValid(5) <= '1'; + frameWrite(5) <= frame; + + -- Receive the frame. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + wait until frameComplete(5) = '1' and clk'event and clk = '1'; + frameValid(5) <= '0'; + + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Wait a while to let the timer expire and receive the link-request. + for i in 0 to 2048 loop + wait until clk'event and clk = '1'; + end loop; + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_LINK_REQUEST, "100")); + + -- Send a link-response that indicates that the frame was received to make + -- the transmitter to back to normal mode. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00110", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 7:"); + PrintS("Action: Let a packet timeout expire. No more replies."); + PrintS("Result: Three link-requests should be transmitted. When the third"); + PrintS(" times out the link will be restarted."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-Step7"); + --------------------------------------------------------------------------- + + -- Create the frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 7; + frame := RioFrameCreate(ackId=>"00110", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameValid(6) <= '1'; + frameWrite(6) <= frame; + + -- Receive the frame. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Wait a while to let the timer expire and receive the link-request. + for i in 0 to 2048 loop + wait until clk'event and clk = '1'; + end loop; + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_LINK_REQUEST, "100")); + + -- Wait a while to let the timer expire and receive the link-request. + for i in 0 to 2048 loop + wait until clk'event and clk = '1'; + end loop; + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_LINK_REQUEST, "100")); + + -- Wait a while to let the timer expire and receive the link-request. + for i in 0 to 2048 loop + wait until clk'event and clk = '1'; + end loop; + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_LINK_REQUEST, "100")); + + -- Wait a while to let the timer expire and receive the link-request. + for i in 0 to 2048 loop + wait until clk'event and clk = '1'; + end loop; + + -- Reinitialize the transmitter. + for i in 0 to 255 loop + ReceiveSymbol(SYMBOL_IDLE); + end loop; + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_NOP, "000")); + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00110", "11111", + STYPE1_NOP, "000")); + for j in 0 to 14 loop + for i in 0 to 15 loop + ReceiveSymbol(SYMBOL_IDLE); + end loop; + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_NOP, "000")); + end loop; + + -- Receive the frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + wait until frameComplete(6) = '1' and clk'event and clk = '1'; + frameValid(6) <= '0'; + + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00110", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 8:"); + PrintS("Action: Let a packet timeout expire. Then answer with totally "); + PrintS(" unexpected ackId."); + PrintS("Result: A link request should be transmitted and the link should "); + PrintS(" be restarted."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-Step8"); + --------------------------------------------------------------------------- + + -- Create the frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 8; + frame := RioFrameCreate(ackId=>"00111", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameValid(7) <= '1'; + frameWrite(7) <= frame; + + -- Receive the frame. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Wait a while to let the timer expire and receive the link-request. + for i in 0 to 2048 loop + wait until clk'event and clk = '1'; + end loop; + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_LINK_REQUEST, "100")); + + -- Send a link-response with unexpected ackId. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "10000", "11111", + STYPE1_NOP, "000")); + + -- Reinitialize the transmitter. + for i in 0 to 255 loop + ReceiveSymbol(SYMBOL_IDLE); + end loop; + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_NOP, "000")); + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "00111", "11111", + STYPE1_NOP, "000")); + for j in 0 to 14 loop + for i in 0 to 15 loop + ReceiveSymbol(SYMBOL_IDLE); + end loop; + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_NOP, "000")); + end loop; + + -- Receive the frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + wait until frameComplete(7) = '1' and clk'event and clk = '1'; + frameValid(7) <= '0'; + + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00111", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 9:"); + PrintS("Action: Send status with unexpected ackId in normal operation."); + PrintS("Result: The transmitter should disregard the error."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-Step9"); + --------------------------------------------------------------------------- + + -- Send a status with unexpected ackId. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "10000", "11111", + STYPE1_NOP, "000")); + + -- Receive no change. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_IDLE); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 10:"); + PrintS("Action: Send packet-retry with unexpected ackId in normal operation."); + PrintS("Result: The transmitter should enter output-error-stopped."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-Step10"); + --------------------------------------------------------------------------- + + -- Send a packet-retry with unexpected ackId. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_RETRY, "10000", "11111", + STYPE1_NOP, "000")); + + -- Receive link-request. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_LINK_REQUEST, "100")); + + -- Send a link-response with unexpected ackId. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01000", "11111", + STYPE1_NOP, "000")); + + -- Create the frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 10; + frame := RioFrameCreate(ackId=>"01000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameValid(8) <= '1'; + frameWrite(8) <= frame; + + -- Receive the frame. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + wait until frameComplete(8) = '1' and clk'event and clk = '1'; + frameValid(8) <= '0'; + + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01000", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 11:"); + PrintS("Action: Send packet-accepted with unexpected ackId in normal "); + PrintS(" operation."); + PrintS("Result: The transmitter should enter output-error-stopped."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-Step11"); + --------------------------------------------------------------------------- + + -- Send a packet-accepted with unexpected ackId. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "10000", "11111", + STYPE1_NOP, "000")); + + -- Receive link-request. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_LINK_REQUEST, "100")); + + -- Send a link-response with unexpected ackId. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "11111", + STYPE1_NOP, "000")); + + -- Create the frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 11; + frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameValid(9) <= '1'; + frameWrite(9) <= frame; + + -- Receive the frame. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + wait until frameComplete(9) = '1' and clk'event and clk = '1'; + frameValid(9) <= '0'; + + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01001", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 12:"); + PrintS("Action: Send a packet and then accept it with unexpected ackId."); + PrintS("Result: The transmitter should enter output-error-stopped."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-Step12"); + --------------------------------------------------------------------------- + + -- Create the frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 12; + frame := RioFrameCreate(ackId=>"01010", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameValid(10) <= '1'; + frameWrite(10) <= frame; + + -- Receive the frame. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frame.length-1 loop + ReceiveSymbol(SYMBOL_DATA, frame.payload(i)); + end loop; + + wait until frameComplete(10) = '1' and clk'event and clk = '1'; + frameValid(10) <= '0'; + + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Send unexpected ackId in packet-accepted. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "10000", "11111", + STYPE1_NOP, "000")); + + -- Receive link-request. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_LINK_REQUEST, "100")); + + -- Send a link-response with expected ackId. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01011", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 13:"); + PrintS("Action: Set two valid packets."); + PrintS("Result: The two packet should be sent without waiting for "); + PrintS(" packet-accepted."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-Step13"); + --------------------------------------------------------------------------- + + -- Create the first frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 13; + frame := RioFrameCreate(ackId=>"01011", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameValid(11) <= '1'; + frameWrite(11) <= frame; + + -- Create the second frame. + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := 14; + frame := RioFrameCreate(ackId=>"01100", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameValid(12) <= '1'; + frameWrite(12) <= frame; + + -- Receive the frame. + ReceiveSymbol(SYMBOL_IDLE); + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frameWrite(11).length-1 loop + ReceiveSymbol(SYMBOL_DATA, frameWrite(11).payload(i)); + end loop; + + -- Receive the frame. + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frameWrite(12).length-1 loop + ReceiveSymbol(SYMBOL_DATA, frameWrite(12).payload(i)); + end loop; + + wait until frameComplete(11) = '1' and clk'event and clk = '1'; + frameValid(11) <= '0'; + wait until frameComplete(12) = '1' and clk'event and clk = '1'; + frameValid(12) <= '0'; + + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + + -- Send packet-accepted for both packets. + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01011", "11111", + STYPE1_NOP, "000")); + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01100", "11111", + STYPE1_NOP, "000")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 14:"); + PrintS("Action: Set maximum number of valid packets."); + PrintS("Result: Maximum 31 packets should be sent without waiting for "); + PrintS(" packet-accepted."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-Step14"); + --------------------------------------------------------------------------- + + --------------------------------------------------------------------------- + -- Create the frames. + --------------------------------------------------------------------------- + + for j in 0 to 47 loop + CreateRandomPayload(payload.data, seed1, seed2); + payload.length := j+13; + frame := RioFrameCreate(ackId=>std_logic_vector(to_unsigned((j+13) mod 32, 5)), + vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>x"0000", destId=>x"0000", + payload=>payload); + frameValid(j+13) <= '1'; + frameWrite(j+13) <= frame; + end loop; + + --------------------------------------------------------------------------- + -- Receive the frames. + --------------------------------------------------------------------------- + + ReceiveSymbol(SYMBOL_IDLE); + + for j in 0 to 29 loop + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frameWrite(j+13).length-1 loop + ReceiveSymbol(SYMBOL_DATA, frameWrite(j+13).payload(i)); + end loop; + + wait until frameComplete(j+13) = '1' and clk'event and clk = '1'; + frameValid(j+13) <= '0'; + end loop; + + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_START_OF_PACKET, "000")); + for i in 0 to frameWrite(43).length-1 loop + ReceiveSymbol(SYMBOL_DATA, frameWrite(43).payload(i)); + end loop; + ReceiveSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111", + STYPE1_END_OF_PACKET, "000")); + wait until frameComplete(43) = '1' and clk'event and clk = '1'; + frameValid(43) <= '0'; + + -- REMARK: Complete the testcase and acknowledge all transmitted packets... + SendSymbol(SYMBOL_CONTROL, + RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01101", "11111", + STYPE1_NOP, "000")); + + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step X:"); + PrintS("Action: Start sending an outbound packet and while in transmission, "); + PrintS(" start and complete an inbound packet."); + PrintS("Result: The ack for the inbound packet should be inserted into the"); + PrintS(" outbound packet."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-StepX"); + --------------------------------------------------------------------------- + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step X:"); + PrintS("Action: Send a packet but not all content is available yet."); + PrintS("Result: Idle symbols should be inserted into the packet."); + --------------------------------------------------------------------------- + PrintR("TG_RioSerial-TC4-StepX"); + --------------------------------------------------------------------------- + + --------------------------------------------------------------------------- + -- REMARK: Send long frames with a CRC in the middle... + --------------------------------------------------------------------------- + + --------------------------------------------------------------------------- + -- Test completed. + --------------------------------------------------------------------------- + + TestEnd; + end process; + + + ----------------------------------------------------------------------------- + -- Instantiate the uart. + ----------------------------------------------------------------------------- + + TestPort: TestSwitchPort + generic map( + NUMBER_WORDS=>1) + port map( + clk=>clk, areset_n=>areset_n, + frameValid_i=>frameValid, frameWrite_i=>frameWrite, frameComplete_o=>frameComplete, + frameExpected_i=>frameExpected, frameRead_i=>frameRead, frameReceived_o=>frameReceived, + readFrameEmpty_o=>readFrameEmpty, readFrame_i=>readFrame, + readFrameRestart_i=>readFrameRestart, readFrameAborted_o=>readFrameAborted, + readWindowEmpty_o=>readWindowEmpty, + readWindowReset_i=>readWindowReset, readWindowNext_i=>readWindowNext, + readContentEmpty_o=>readContentEmpty, readContent_i=>readContent, + readContentEnd_o=>readContentEnd, readContentData_o=>readContentData, + writeFrameFull_o=>writeFrameFull, writeFrame_i=>writeFrame, writeFrameAbort_i=>writeFrameAbort, + writeContent_i=>writeContent, writeContentData_i=>writeContentData); + + TestPhy: RioSerial + generic map( + TIMEOUT_WIDTH=>11) + port map( + clk=>clk, areset_n=>areset_n, + portLinkTimeout_i=>portLinkTimeout, + linkInitialized_o=>linkInitialized, + inputPortEnable_i=>inputPortEnable, + outputPortEnable_i=>outputPortEnable, + localAckIdWrite_i=>localAckIdWrite, + clrOutstandingAckId_i=>clrOutstandingAckId, + inboundAckId_i=>inboundAckIdWrite, + outstandingAckId_i=>outstandingAckIdWrite, + outboundAckId_i=>outboundAckIdWrite, + inboundAckId_o=>inboundAckIdRead, + outstandingAckId_o=>outstandingAckIdRead, + outboundAckId_o=>outboundAckIdRead, + readFrameEmpty_i=>readFrameEmpty, readFrame_o=>readFrame, readFrameRestart_o=>readFrameRestart, + readFrameAborted_i=>readFrameAborted, + readWindowEmpty_i=>readWindowEmpty, + readWindowReset_o=>readWindowReset, readWindowNext_o=>readWindowNext, + readContentEmpty_i=>readContentEmpty, + readContent_o=>readContent, readContentEnd_i=>readContentEnd, readContentData_i=>readContentData, + writeFrameFull_i=>writeFrameFull, writeFrame_o=>writeFrame, writeFrameAbort_o=>writeFrameAbort, + writeContent_o=>writeContent, writeContentData_o=>writeContentData, + portInitialized_i=>portInitialized, + outboundSymbolFull_i=>outboundSymbolFull, + outboundSymbolWrite_o=>outboundSymbolWrite, + outboundSymbol_o=>outboundSymbol, + inboundSymbolEmpty_i=>inboundSymbolEmpty, + inboundSymbolRead_o=>inboundSymbolRead, + inboundSymbol_i=>inboundSymbol); + +end architecture; + + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library std; +use std.textio.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +entity TestSwitchPort is + generic( + NUMBER_WORDS : natural range 1 to 8 := 1); + port( + clk : in std_logic; + areset_n : in std_logic; + + frameValid_i : in std_logic_vector(0 to 63); + frameWrite_i : in RioFrameArray(0 to 63); + frameComplete_o : out std_logic_vector(0 to 63); + + frameExpected_i : in std_logic; + frameRead_i : in RioFrame; + frameReceived_o : out std_logic; + + readFrameEmpty_o : out std_logic; + readFrame_i : in std_logic; + readFrameRestart_i : in std_logic; + readFrameAborted_o : out std_logic; + + readWindowEmpty_o : out std_logic; + readWindowReset_i : in std_logic; + readWindowNext_i : in std_logic; + + readContentEmpty_o : out std_logic; + readContent_i : in std_logic; + readContentEnd_o : out std_logic; + readContentData_o : out std_logic_vector(31 downto 0); + + writeFrameFull_o : out std_logic; + writeFrame_i : in std_logic; + writeFrameAbort_i : in std_logic; + writeContent_i : in std_logic; + writeContentData_i : in std_logic_vector(31 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +architecture TestSwitchPortImpl of TestSwitchPort is +begin + + ----------------------------------------------------------------------------- + -- + ----------------------------------------------------------------------------- + FrameSender: process + variable frameComplete : std_logic_vector(0 to 63); + variable frameIndex : natural range 0 to 70; + variable backIndex, frontIndex : natural range 0 to 63; + begin + readFrameEmpty_o <= '1'; + readFrameAborted_o <= '0'; + readWindowEmpty_o <= '1'; + readContentEmpty_o <= '1'; + readContentEnd_o <= '0'; + readContentData_o <= (others=>'U'); + frameComplete_o <= (others=>'0'); + frameComplete := (others=>'0'); + backIndex := 0; + frontIndex := 0; + wait until areset_n = '1'; + + loop + wait until clk'event and clk = '1'; + + if (readFrame_i = '1') then + assert (frontIndex - backIndex) >= 0 report "Unexpected readFrame." severity error; + if(backIndex < 63) then + backIndex := backIndex + 1; + else + backIndex := 0; + end if; + end if; + + if (readWindowReset_i = '1') then + frameComplete := (others=>'0'); + frameIndex := 0; + frontIndex := backIndex; + readContentEnd_o <= '0'; + readContentData_o <= (others=>'U'); + end if; + + if (readWindowNext_i = '1') then + assert frameComplete(frontIndex) = '0' report "Reading next frame too fast." severity error; + assert frameIndex = frameWrite_i(frontIndex).length report "Did not read all frame content." severity error; + readContentEnd_o <= '0'; + readContentData_o <= (others=>'U'); + frameComplete(frontIndex) := '1'; + frameIndex := 0; + if(frontIndex < 63) then + frontIndex := frontIndex + 1; + else + frontIndex := 0; + end if; + end if; + + for i in 0 to 63 loop + if (frameComplete(i) = '1') and (frameValid_i(i) = '0') then + frameComplete(i) := '0'; + end if; + end loop; + frameComplete_o <= frameComplete; + + if ((frameComplete(frontIndex) = '0') and + (frameValid_i(frontIndex) = '1')) then + readWindowEmpty_o <= '0'; + else + readWindowEmpty_o <= '1'; + end if; + + if (readFrameRestart_i = '1') then + frameIndex := 0; + readContentEnd_o <= '0'; + readContentData_o <= (others=>'U'); + end if; + + if (readContent_i = '1') then + assert frameValid_i(frontIndex) = '1' report "Unexpected content read." severity error; + readContentData_o <= frameWrite_i(frontIndex).payload(frameIndex); + frameIndex := frameIndex + 1; + if (frameIndex /= frameWrite_i(frontIndex).length) then + readContentEnd_o <= '0'; + else + readContentEnd_o <= '1'; + end if; + end if; + + if(frameValid_i(frontIndex) = '1') and (frameComplete(frontIndex) = '0') then + readFrameEmpty_o <= '0'; + readContentEmpty_o <= '0'; + else + readFrameEmpty_o <= '1'; + readContentEmpty_o <= '1'; + end if; + + end loop; + end process; + + ----------------------------------------------------------------------------- + -- + ----------------------------------------------------------------------------- + FrameReader: process + type StateType is (STATE_IDLE, STATE_READ, STATE_UPDATE); + variable state : StateType; + variable frameIndex : natural range 0 to 69; + begin + writeFrameFull_o <= '1'; + frameReceived_o <= '0'; + wait until areset_n = '1'; + + state := STATE_IDLE; + + loop + wait until clk'event and clk = '1'; + + case state is + when STATE_IDLE => + frameReceived_o <= '0'; + if (frameExpected_i = '1') then + state := STATE_READ; + frameIndex := 0; + writeFrameFull_o <= '0'; + end if; + assert writeFrame_i = '0' report "Unexpected frame received." severity error; + --assert writeFrameAbort_i = '0' report "Unexpected frame aborted received." severity error; + assert writeContent_i = '0' report "Unexpected content received." severity error; + + when STATE_READ => + if (writeFrame_i = '1') then + state := STATE_UPDATE; + frameReceived_o <= '1'; + writeFrameFull_o <= '1'; + assert frameIndex = frameRead_i.length report "Did not finish the expected frame." severity error; + end if; + if (writeFrameAbort_i = '1') then + frameIndex := 0; + end if; + if (writeContent_i = '1') then + assert writeContentData_i(32*NUMBER_WORDS-1 downto 0) = frameRead_i.payload(frameIndex) + report "Unexpected frame content received." severity error; + frameIndex := frameIndex + 1; + end if; + if (frameExpected_i = '0') then + state := STATE_IDLE; + end if; + + when STATE_UPDATE => + if (frameExpected_i = '0') then + state := STATE_IDLE; + end if; + + end case; + end loop; + end process; + +end architecture;
2.0.0-alpha/bench/vhdl/TestRioSerial.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: 2.0.0-alpha/bench/vhdl/TestRioPacketBuffer.vhd =================================================================== --- 2.0.0-alpha/bench/vhdl/TestRioPacketBuffer.vhd (nonexistent) +++ 2.0.0-alpha/bench/vhdl/TestRioPacketBuffer.vhd (revision 23) @@ -0,0 +1,2194 @@ +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- Description +-- Contains automatic simulation test code to verify a RioPacketBufferWindow +-- implementation. +-- +-- To Do: +-- - +-- +-- Author(s): +-- - Magnus Rosenius, magro732@opencores.org +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- TestRioPacketBuffer. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.math_real.all; +library std; +use std.textio.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- Entity for TestRioPacketBuffer. +------------------------------------------------------------------------------- +entity TestRioPacketBuffer is +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for TestRioPacketBuffer. +------------------------------------------------------------------------------- +architecture TestRioPacketBufferImpl of TestRioPacketBuffer is + + component RioPacketBufferWindow is + port( + clk : in std_logic; + areset_n : in std_logic; + + inboundWriteFrameFull_o : out std_logic; + inboundWriteFrame_i : in std_logic; + inboundWriteFrameAbort_i : in std_logic; + inboundWriteContent_i : in std_logic; + inboundWriteContentData_i : in std_logic_vector(31 downto 0); + inboundReadFrameEmpty_o : out std_logic; + inboundReadFrame_i : in std_logic; + inboundReadFrameRestart_i : in std_logic; + inboundReadFrameAborted_o : out std_logic; + inboundReadContentEmpty_o : out std_logic; + inboundReadContent_i : in std_logic; + inboundReadContentEnd_o : out std_logic; + inboundReadContentData_o : out std_logic_vector(31 downto 0); + + outboundWriteFrameFull_o : out std_logic; + outboundWriteFrame_i : in std_logic; + outboundWriteFrameAbort_i : in std_logic; + outboundWriteContent_i : in std_logic; + outboundWriteContentData_i : in std_logic_vector(31 downto 0); + outboundReadFrameEmpty_o : out std_logic; + outboundReadFrame_i : in std_logic; + outboundReadFrameRestart_i : in std_logic; + outboundReadFrameAborted_o : out std_logic; + outboundReadWindowEmpty_o : out std_logic; + outboundReadWindowReset_i : in std_logic; + outboundReadWindowNext_i : in std_logic; + outboundReadContentEmpty_o : out std_logic; + outboundReadContent_i : in std_logic; + outboundReadContentEnd_o : out std_logic; + outboundReadContentData_o : out std_logic_vector(31 downto 0)); + end component; + + signal clk : std_logic; + signal areset_n : std_logic; + + signal inboundWriteFrameFull : std_logic; + signal inboundWriteFrame : std_logic; + signal inboundWriteFrameAbort : std_logic; + signal inboundWriteContent : std_logic; + signal inboundWriteContentData : std_logic_vector(31 downto 0); + signal inboundReadFrameEmpty : std_logic; + signal inboundReadFrame : std_logic; + signal inboundReadFrameRestart : std_logic; + signal inboundReadFrameAborted : std_logic; + signal inboundReadContentEmpty : std_logic; + signal inboundReadContent : std_logic; + signal inboundReadContentEnd : std_logic; + signal inboundReadContentData : std_logic_vector(31 downto 0); + + signal outboundWriteFrameFull : std_logic; + signal outboundWriteFrame : std_logic; + signal outboundWriteFrameAbort : std_logic; + signal outboundWriteContent : std_logic; + signal outboundWriteContentData : std_logic_vector(31 downto 0); + signal outboundReadFrameEmpty : std_logic; + signal outboundReadFrame : std_logic; + signal outboundReadFrameRestart : std_logic; + signal outboundReadFrameAborted : std_logic; + signal outboundReadWindowEmpty : std_logic; + signal outboundReadWindowReset : std_logic; + signal outboundReadWindowNext : std_logic; + signal outboundReadContentEmpty : std_logic; + signal outboundReadContent : std_logic; + signal outboundReadContentEnd : std_logic; + signal outboundReadContentData : std_logic_vector(31 downto 0); + +begin + + ----------------------------------------------------------------------------- + -- Clock generation. + ----------------------------------------------------------------------------- + ClockGenerator: process + begin + clk <= '0'; + wait for 20 ns; + clk <= '1'; + wait for 20 ns; + end process; + + + ----------------------------------------------------------------------------- + -- Test case driver. + ----------------------------------------------------------------------------- + TestDriver: process + --------------------------------------------------------------------------- + -- Inbound procedures. + --------------------------------------------------------------------------- + + procedure SetInboundWriteContent( + constant content : in std_logic_vector(31 downto 0)) is + begin + assert inboundWriteFrameFull = '0' + report "Inbound frame cannot be accepted." severity error; + + inboundWriteContent <= '1'; + inboundWriteContentData <= content; + wait until clk'event and clk = '1'; + wait for 1 ns; + inboundWriteContent <= '0'; + inboundWriteContentData <= (others=>'U'); + end procedure; + + procedure SetInboundWriteFrame is + begin + inboundWriteFrame <= '1'; + wait until clk'event and clk = '1'; + wait for 1 ns; + + inboundWriteFrame <= '0'; + end procedure; + + procedure SetInboundWriteFrameAbort is + begin + inboundWriteFrameAbort <= '1'; + wait until clk'event and clk = '1'; + wait for 1 ns; + + inboundWriteFrameAbort <= '0'; + end procedure; + + procedure SetInboundReadContent( + constant content : in std_logic_vector(31 downto 0)) is + begin + inboundReadContent <= '1'; + wait until clk'event and clk = '1'; + wait for 1 ns; + + assert (inboundReadContentData = content) + report "Unexpected content read." severity error; + assert (inboundReadContentEnd = '0') + report "Unexpected content end." severity error; + + inboundReadContent <= '0'; + end procedure; + + procedure SetInboundReadContentEnd is + begin + inboundReadContent <= '1'; + wait until clk'event and clk = '1'; + wait for 1 ns; + + assert (inboundReadContentEnd = '1') + report "Unexpected content end." severity error; + + inboundReadContent <= '0'; + end procedure; + + procedure SetInboundReadFrame is + begin + assert inboundReadFrameEmpty = '0' + report "No pending inbound frame to be read." severity error; + + inboundReadFrame <= '1'; + wait until clk'event and clk = '1'; + wait for 1 ns; + + inboundReadFrame <= '0'; + end procedure; + + procedure SetInboundReadFrameRestart is + begin + inboundReadFrameRestart <= '1'; + wait until clk'event and clk = '1'; + wait for 1 ns; + + inboundReadFrameRestart <= '0'; + end procedure; + + --------------------------------------------------------------------------- + -- Outbound procedures. + --------------------------------------------------------------------------- + + procedure SetOutboundWriteContent( + constant content : in std_logic_vector(31 downto 0)) is + begin + assert outboundWriteFrameFull = '0' + report "Outbound frame cannot be accepted." severity error; + + outboundWriteContent <= '1'; + outboundWriteContentData <= content; + wait until clk'event and clk = '1'; + wait for 1 ns; + outboundWriteContent <= '0'; + outboundWriteContentData <= (others=>'U'); + end procedure; + + procedure SetOutboundWriteFrame is + begin + assert outboundWriteFrameFull = '0' + report "Outbound frame cannot be accepted." severity error; + + outboundWriteFrame <= '1'; + wait until clk'event and clk = '1'; + wait for 1 ns; + + outboundWriteFrame <= '0'; + end procedure; + + procedure SetOutboundWriteFrameAbort is + begin + outboundWriteFrameAbort <= '1'; + wait until clk'event and clk = '1'; + wait for 1 ns; + + outboundWriteFrameAbort <= '0'; + end procedure; + + procedure SetOutboundReadContent( + constant content : in std_logic_vector(31 downto 0); + constant ending : in std_logic := '0') is + begin + outboundReadContent <= '1'; + wait until clk'event and clk = '1'; + wait for 1 ns; + + assert (outboundReadContentData = content) + report "Unexpected content read." severity error; + assert (outboundReadContentEnd = ending) + report "Unexpected content end." severity error; + + outboundReadContent <= '0'; + end procedure; + + procedure SetOutboundReadFrame is + begin + assert outboundReadFrameEmpty = '0' + report "No pending outbound frame to be read." severity error; + + outboundReadFrame <= '1'; + wait until clk'event and clk = '1'; + wait for 1 ns; + + outboundReadFrame <= '0'; + end procedure; + + procedure SetOutboundReadFrameRestart is + begin + outboundReadFrameRestart <= '1'; + wait until clk'event and clk = '1'; + wait for 1 ns; + + outboundReadFrameRestart <= '0'; + end procedure; + + procedure SetOutboundReadWindowReset is + begin + outboundReadWindowReset <= '1'; + wait until clk'event and clk = '1'; + wait for 1 ns; + + outboundReadWindowReset <= '0'; + end procedure; + + procedure SetOutboundReadWindowNext is + begin + assert outboundReadWindowEmpty = '0' + report "No pending outbound window frame to be read." severity error; + + outboundReadWindowNext <= '1'; + wait until clk'event and clk = '1'; + wait for 1 ns; + + outboundReadWindowNext <= '0'; + end procedure; + + begin + inboundWriteFrame <= '0'; + inboundWriteFrameAbort <= '0'; + inboundWriteContent <= '0'; + inboundWriteContentData <= (others=>'U'); + inboundReadFrame <= '0'; + inboundReadFrameRestart <= '0'; + inboundReadContent <= '0'; + + outboundWriteFrame <= '0'; + outboundWriteFrameAbort <= '0'; + outboundWriteContent <= '0'; + outboundWriteContentData <= (others=>'U'); + outboundReadFrame <= '0'; + outboundReadFrameRestart <= '0'; + outboundReadWindowReset <= '0'; + outboundReadWindowNext <= '0'; + outboundReadContent <= '0'; + + areset_n <= '0'; + wait until clk'event and clk = '1'; + wait until clk'event and clk = '1'; + areset_n <= '1'; + wait until clk'event and clk = '1'; + wait until clk'event and clk = '1'; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioPacketBuffer"); + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioPacketBuffer-TC1"); + PrintS("Description: Test normal operation without using the window. Only"); + PrintS(" full frames are tested."); + PrintS("Requirement: XXXXX"); + PrintS("-----------------------------------------------------------------"); + PrintS("Step 1:"); + PrintS("Action: Complete a small frame and read it."); + PrintS("Result: The read frame should be equal to the one written."); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC1-Step1"); + --------------------------------------------------------------------------- + -- REMARK: Update testcases for inbound and outbound... + + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + + SetInboundWriteContent(x"deadbeef"); + + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + + SetInboundWriteFrame; + + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + + SetInboundReadContent(x"deadbeef"); + + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + + SetInboundReadContentEnd; + + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + + SetInboundReadFrame; + + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 2:"); + PrintS("Action: Write a rio maximum size frame and read it."); + PrintS("Result: The read frame should be equal to the one written."); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC1-Step2"); + --------------------------------------------------------------------------- + + for i in 0 to 68 loop + SetInboundWriteContent(std_logic_vector(to_unsigned(i, 32))); + + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + end loop; + + SetInboundWriteFrame; + + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + + for i in 0 to 68 loop + SetInboundReadContent(std_logic_vector(to_unsigned(i, 32))); + + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + end loop; + + SetInboundReadContentEnd; + + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + + SetInboundReadFrame; + + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 3:"); + PrintS("Action: Fill the maximum number of small frames without filling "); + PrintS(" the memory."); + PrintS("Result: The frame buffer should accept 63 frames."); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC1-Step3"); + --------------------------------------------------------------------------- + + --------------------------------------------------------------------------- + -- Write maximum number of frames. + --------------------------------------------------------------------------- + + for i in 0 to 2 loop + SetInboundWriteContent(std_logic_vector(to_unsigned(i, 32))); + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + end loop; + + for j in 1 to 62 loop + SetInboundWriteFrame; + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + + for i in 0 to 2 loop + SetInboundWriteContent(std_logic_vector(to_unsigned(j+i, 32))); + + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + end loop; + end loop; + + SetInboundWriteFrame; + assert (inboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + + --------------------------------------------------------------------------- + -- Read the frames written in the above steps. + --------------------------------------------------------------------------- + + for i in 0 to 2 loop + SetInboundReadContent(std_logic_vector(to_unsigned(i, 32))); + + assert (inboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + end loop; + + SetInboundReadContentEnd; + assert (inboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + + for j in 1 to 62 loop + SetInboundReadFrame; + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + + for i in 0 to 2 loop + SetInboundReadContent(std_logic_vector(to_unsigned(j+i, 32))); + + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + end loop; + + SetInboundReadContentEnd; + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + end loop; + + SetInboundReadFrame; + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 4:"); + PrintS("Action: Fill the memory to its limit."); + PrintS("Result: The frame buffer should accept 255-69 words."); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC1-Step4"); + --------------------------------------------------------------------------- + + for i in 0 to 186 loop + SetInboundWriteContent(std_logic_vector(to_unsigned(i, 32))); + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + end loop; + + SetInboundWriteFrame; + assert (inboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + + --------------------------------------------------------------------------- + + for i in 0 to 186 loop + SetInboundReadContent(std_logic_vector(to_unsigned(i, 32))); + + assert (inboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + end loop; + + SetInboundReadContentEnd; + assert (inboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + + SetInboundReadFrame; + assert (inboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (inboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioPacketBuffer-TC2"); + PrintS("Description: Test operation when using the window."); + PrintS("Requirement: XXXXX"); + PrintS("-----------------------------------------------------------------"); + PrintS("Step 1:"); + PrintS("Action: Add one frame and update the window."); + PrintS("Result: The window empty flag and the read frame empty flag should"); + PrintS(" be updated and it should be possible to read the frame again."); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC2-Step1"); + --------------------------------------------------------------------------- + + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 2 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + + for i in 0 to 1 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(2, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowReset; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 1 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(2, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 2:"); + PrintS("Action: Add two frames and test the window accesses."); + PrintS("Result: ."); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC2-Step2"); + --------------------------------------------------------------------------- + + --------------------------------------------------------------------------- + -- Write two frames. + --------------------------------------------------------------------------- + + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 2 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(1+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 2 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(2+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + -- Read the frames using the window mechanism. + --------------------------------------------------------------------------- + + for i in 0 to 1 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(1+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(1+2, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 1 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(2+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(2+2, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + -- Reset the window and read the frames again. + --------------------------------------------------------------------------- + + SetOutboundReadWindowReset; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 1 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(1+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(1+2, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 1 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(2+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(2+2, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + -- Remove one frame and access the remaining frame. + --------------------------------------------------------------------------- + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowReset; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 1 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(2+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(2+2, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + -- Remove the remaining frame. + --------------------------------------------------------------------------- + + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowReset; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 3:"); + PrintS("Action: Add maximum number of frames and test the window accesses."); + PrintS("Result: The buffer should be full and not accept more frames."); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC2-Step3"); + --------------------------------------------------------------------------- + + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + -- Write 3*63 frames => maximum number of frames. + --------------------------------------------------------------------------- + + for i in 0 to 2 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + end loop; + + for j in 1 to 62 loop + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 2 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(j+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + end loop; + + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + -- Read the whole window until it is empty. + --------------------------------------------------------------------------- + + for j in 0 to 61 loop + for i in 0 to 1 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(j+i, 32))); + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(j+2, 32)), '1'); + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + for i in 0 to 1 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(62+i, 32))); + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(62+2, 32)), '1'); + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + -- Reset the window and remove all frames. + --------------------------------------------------------------------------- + + SetOutboundReadWindowReset; + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for j in 0 to 61 loop + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadWindowReset; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 1 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(62+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(62+2, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 4:"); + PrintS("Action: Add maximum number of words and test the window accesses."); + PrintS("Result: The content memory should be full."); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC2-Step4"); + --------------------------------------------------------------------------- + + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + -- Write 6*31+69=255 words and 7 frames => full content. + --------------------------------------------------------------------------- + + for i in 0 to 30 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + end loop; + + for j in 1 to 5 loop + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 30 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(j+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + end loop; + + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 68 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(1024+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + -- Read the whole window until it is empty. + --------------------------------------------------------------------------- + + for j in 0 to 5 loop + for i in 0 to 29 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(j+i, 32))); + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(j+30, 32)), '1'); + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + for i in 0 to 67 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(1024+i, 32))); + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(1024+68, 32)), '1'); + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + -- Reset the window and remove all frames. + --------------------------------------------------------------------------- + + SetOutboundReadWindowReset; + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for j in 0 to 1 loop + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + for j in 2 to 5 loop + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadWindowReset; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 67 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(1024+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(1024+68, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 5:"); + PrintS("Action: Add maximum number of words -1 and test the window accesses."); + PrintS("Result: The content memory should not accept more frames."); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC2-Step5"); + --------------------------------------------------------------------------- + + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + -- Write 11*17=187 (one full frame will not fit). + --------------------------------------------------------------------------- + + for i in 0 to 16 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + end loop; + + for j in 1 to 10 loop + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 16 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(j+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + end loop; + + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + -- Reset the window and remove all frames. + --------------------------------------------------------------------------- + + SetOutboundReadWindowReset; + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '1') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for j in 1 to 9 loop + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 6:"); + PrintS("Action: Add two frames and start reading the second, then remove"); + PrintS(" the first."); + PrintS("Result: The readContentEnd flag should not be changed when frames"); + PrintS(" are removed."); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC2-Step6"); + --------------------------------------------------------------------------- + + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + -- + --------------------------------------------------------------------------- + + for i in 0 to 3 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(i, 32))); + assert (outboundWriteFrameFull = '0') + + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 3 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(i+1, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + -- + --------------------------------------------------------------------------- + + for i in 0 to 2 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(3, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadContent(std_logic_vector(to_unsigned(1, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadContent(std_logic_vector(to_unsigned(2, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadContent(std_logic_vector(to_unsigned(3, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadContent(std_logic_vector(to_unsigned(4, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioPacketBuffer"); + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioPacketBuffer-TC3"); + PrintS("Description: Test operation when restarting and aborting frames."); + PrintS("Requirement: XXXXX"); + PrintS("-----------------------------------------------------------------"); + PrintS("Step 1:"); + PrintS("Action: Write one frame and abort it."); + PrintS("Result: The aborted frame should be discarded."); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC3-Step1"); + --------------------------------------------------------------------------- + + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 3 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundWriteFrameAbort; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 2:"); + PrintS("Action: Write one full frame then one more that is aborted."); + PrintS("Result: The first frame should remain and the aborted should be "); + PrintS(" discarded."); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC3-Step2"); + --------------------------------------------------------------------------- + + for i in 0 to 3 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(1+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 3 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(2+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundWriteFrameAbort; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 3 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(3+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 2 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(1+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(1+3, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 2 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(3+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(3+3, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 3:"); + PrintS("Action: Write one full frame then read one that is restarted."); + PrintS("Result: The content of the first frame should be read twice. "); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC3-Step3"); + --------------------------------------------------------------------------- + + for i in 0 to 3 loop + SetOutboundWriteContent(std_logic_vector(to_unsigned(1+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 2 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(1+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(1+3, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadFrameRestart; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + for i in 0 to 2 loop + SetOutboundReadContent(std_logic_vector(to_unsigned(1+i, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + end loop; + + SetOutboundReadContent(std_logic_vector(to_unsigned(1+3, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioPacketBuffer"); + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioPacketBuffer-TC4"); + PrintS("Description: Test operation when partial frames are read."); + PrintS("Requirement: XXXXX"); + PrintS("-----------------------------------------------------------------"); + PrintS("Step 1:"); + PrintS("Action: Write a one word frame and read it before it is completed."); + PrintS("Result: Empty signals should reflect the status of the frame."); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC4-Step1"); + --------------------------------------------------------------------------- + + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '1') + report "Unexpected readContentEmpty." severity error; + + SetOutboundWriteContent(std_logic_vector(to_unsigned(1, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '0') + report "Unexpected readContentEmpty." severity error; + + SetOutboundReadContent(std_logic_vector(to_unsigned(1, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '1') + report "Unexpected readContentEmpty." severity error; + + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '0') + report "Unexpected readContentEmpty." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '1') + report "Unexpected readContentEmpty." severity error; + + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '1') + report "Unexpected readContentEmpty." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 2:"); + PrintS("Action: Write content to a frame and read it, then abort the frame."); + PrintS("Result: The reader should be notified about the aborted frame. The"); + PrintS(" notification should be reset when the frame has been "); + PrintS(" restarted."); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC4-Step2"); + --------------------------------------------------------------------------- + + SetOutboundWriteContent(std_logic_vector(to_unsigned(1, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '0') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '0') + report "Unexpected readFrameAborted." severity error; + + SetOutboundReadContent(std_logic_vector(to_unsigned(1, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '1') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '0') + report "Unexpected readFrameAborted." severity error; + + SetOutboundWriteFrameAbort; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '0') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '1') + report "Unexpected readFrameAborted." severity error; + + SetOutboundWriteContent(std_logic_vector(to_unsigned(2, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '1') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '1') + report "Unexpected readFrameAborted." severity error; + + SetOutboundReadFrameRestart; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '0') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '0') + report "Unexpected readFrameAborted." severity error; + + SetOutboundReadContent(std_logic_vector(to_unsigned(2, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '1') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '0') + report "Unexpected readFrameAborted." severity error; + + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '0') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '0') + report "Unexpected readFrameAborted." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '1') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '0') + report "Unexpected readFrameAborted." severity error; + + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '1') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '0') + report "Unexpected readFrameAborted." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 3:"); + PrintS("Action: Write one complete frame then abort a second."); + PrintS("Result: The reader should not notice the aborted frame. "); + --------------------------------------------------------------------------- + PrintR("TG_RioPacketBuffer-TC4-Step3"); + --------------------------------------------------------------------------- + + SetOutboundWriteContent(std_logic_vector(to_unsigned(1, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '0') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '0') + report "Unexpected readFrameAborted." severity error; + + SetOutboundReadContent(std_logic_vector(to_unsigned(1, 32)), '1'); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '1') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '0') + report "Unexpected readFrameAborted." severity error; + + SetOutboundWriteFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '0') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '0') + report "Unexpected readFrameAborted." severity error; + + SetOutboundWriteContent(std_logic_vector(to_unsigned(2, 32))); + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '0') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '0') + report "Unexpected readFrameAborted." severity error; + + SetOutboundWriteFrameAbort; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '0') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '0') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '0') + report "Unexpected readFrameAborted." severity error; + + SetOutboundReadWindowNext; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '0') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '1') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '0') + report "Unexpected readFrameAborted." severity error; + + SetOutboundReadFrame; + assert (outboundWriteFrameFull = '0') + report "Unexpected writeFrameFull." severity error; + assert (outboundReadFrameEmpty = '1') + report "Unexpected readFrameEmpty." severity error; + assert (outboundReadWindowEmpty = '1') + report "Unexpected readWindowEmpty." severity error; + assert (outboundReadContentEmpty = '1') + report "Unexpected readContentEmpty." severity error; + assert (outboundReadFrameAborted = '0') + report "Unexpected readFrameAborted." severity error; + + --------------------------------------------------------------------------- + -- Test completed. + --------------------------------------------------------------------------- + + TestEnd; + end process; + + ----------------------------------------------------------------------------- + -- Instantiate the testobject. + ----------------------------------------------------------------------------- + + TestPacketBuffer: RioPacketBufferWindow + port map( + clk=>clk, areset_n=>areset_n, + inboundWriteFrameFull_o=>inboundWriteFrameFull, + inboundWriteFrame_i=>inboundWriteFrame, + inboundWriteFrameAbort_i=>inboundWriteFrameAbort, + inboundWriteContent_i=>inboundWriteContent, + inboundWriteContentData_i=>inboundWriteContentData, + inboundReadFrameEmpty_o=>inboundReadFrameEmpty, + inboundReadFrame_i=>inboundReadFrame, + inboundReadFrameRestart_i=>inboundReadFrameRestart, + inboundReadFrameAborted_o=>inboundReadFrameAborted, + inboundReadContentEmpty_o=>inboundReadContentEmpty, + inboundReadContent_i=>inboundReadContent, + inboundReadContentEnd_o=>inboundReadContentEnd, + inboundReadContentData_o=>inboundReadContentData, + outboundWriteFrameFull_o=>outboundWriteFrameFull, + outboundWriteFrame_i=>outboundWriteFrame, + outboundWriteFrameAbort_i=>outboundWriteFrameAbort, + outboundWriteContent_i=>outboundWriteContent, + outboundWriteContentData_i=>outboundWriteContentData, + outboundReadFrameEmpty_o=>outboundReadFrameEmpty, + outboundReadFrame_i=>outboundReadFrame, + outboundReadFrameRestart_i=>outboundReadFrameRestart, + outboundReadFrameAborted_o=>outboundReadFrameAborted, + outboundReadWindowEmpty_o=>outboundReadWindowEmpty, + outboundReadWindowReset_i=>outboundReadWindowReset, + outboundReadWindowNext_i=>outboundReadWindowNext, + outboundReadContentEmpty_o=>outboundReadContentEmpty, + outboundReadContent_i=>outboundReadContent, + outboundReadContentEnd_o=>outboundReadContentEnd, + outboundReadContentData_o=>outboundReadContentData); + +end architecture;
2.0.0-alpha/bench/vhdl/TestRioPacketBuffer.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: 2.0.0-alpha/bench/vhdl/TestRioSwitch.vhd =================================================================== --- 2.0.0-alpha/bench/vhdl/TestRioSwitch.vhd (nonexistent) +++ 2.0.0-alpha/bench/vhdl/TestRioSwitch.vhd (revision 23) @@ -0,0 +1,1265 @@ +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- Description +-- Contains automatic simulation test code to verify a RioSwitch implementation. +-- +-- To Do: +-- - +-- +-- Author(s): +-- - Magnus Rosenius, magro732@opencores.org +-- +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 Authors and OPENCORES.ORG +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the GNU Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-- +------------------------------------------------------------------------------- + + +------------------------------------------------------------------------------- +-- TestRioSwitch. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.math_real.all; +library std; +use std.textio.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- Entity for TestRioSwitch. +------------------------------------------------------------------------------- +entity TestRioSwitch is +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for TestRioSwitch. +------------------------------------------------------------------------------- +architecture TestRioSwitchImpl of TestRioSwitch is + + component RioSwitch is + generic( + SWITCH_PORTS : natural range 3 to 255 := 4; + DEVICE_IDENTITY : std_logic_vector(15 downto 0); + DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0); + DEVICE_REV : std_logic_vector(31 downto 0); + ASSY_IDENTITY : std_logic_vector(15 downto 0); + ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0); + ASSY_REV : std_logic_vector(15 downto 0)); + port( + clk : in std_logic; + areset_n : in std_logic; + + writeFrameFull_i : in Array1(SWITCH_PORTS-1 downto 0); + writeFrame_o : out Array1(SWITCH_PORTS-1 downto 0); + writeFrameAbort_o : out Array1(SWITCH_PORTS-1 downto 0); + writeContent_o : out Array1(SWITCH_PORTS-1 downto 0); + writeContentData_o : out Array32(SWITCH_PORTS-1 downto 0); + + readFrameEmpty_i : in Array1(SWITCH_PORTS-1 downto 0); + readFrame_o : out Array1(SWITCH_PORTS-1 downto 0); + readFrameRestart_o : out Array1(SWITCH_PORTS-1 downto 0); + readFrameAborted_i : in Array1(SWITCH_PORTS-1 downto 0); + readContentEmpty_i : in Array1(SWITCH_PORTS-1 downto 0); + readContent_o : out Array1(SWITCH_PORTS-1 downto 0); + readContentEnd_i : in Array1(SWITCH_PORTS-1 downto 0); + readContentData_i : in Array32(SWITCH_PORTS-1 downto 0); + + portLinkTimeout_o : out std_logic_vector(23 downto 0); + + linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0); + outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0); + inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0); + + localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0); + clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0); + inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0); + outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0); + outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0); + inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0); + outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0); + outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0); + + configStb_o : out std_logic; + configWe_o : out std_logic; + configAddr_o : out std_logic_vector(23 downto 0); + configData_o : out std_logic_vector(31 downto 0); + configData_i : in std_logic_vector(31 downto 0)); + end component; + + component TestPort is + port( + clk : in std_logic; + areset_n : in std_logic; + + frameValid_i : in std_logic; + frameWrite_i : in RioFrame; + frameComplete_o : out std_logic; + + frameExpected_i : in std_logic; + frameRead_i : in RioFrame; + frameReceived_o : out std_logic; + + readFrameEmpty_o : out std_logic; + readFrame_i : in std_logic; + readFrameRestart_i : in std_logic; + readFrameAborted_o : out std_logic; + readContentEmpty_o : out std_logic; + readContent_i : in std_logic; + readContentEnd_o : out std_logic; + readContentData_o : out std_logic_vector(31 downto 0); + writeFrameFull_o : out std_logic; + writeFrame_i : in std_logic; + writeFrameAbort_i : in std_logic; + writeContent_i : in std_logic; + writeContentData_i : in std_logic_vector(31 downto 0)); + end component; + + constant PORTS : natural := 7; + constant SWITCH_IDENTITY : std_logic_vector(15 downto 0) := x"0123"; + constant SWITCH_VENDOR_IDENTITY : std_logic_vector(15 downto 0) := x"4567"; + constant SWITCH_REV : std_logic_vector(31 downto 0) := x"89abcdef"; + constant SWITCH_ASSY_IDENTITY : std_logic_vector(15 downto 0) := x"0011"; + constant SWITCH_ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0) := x"2233"; + constant SWITCH_ASSY_REV : std_logic_vector(15 downto 0) := x"4455"; + + signal clk : std_logic; + signal areset_n : std_logic; + + signal frameValid : Array1(PORTS-1 downto 0); + signal frameWrite : RioFrameArray(PORTS-1 downto 0); + signal frameComplete : Array1(PORTS-1 downto 0); + + signal frameExpected : Array1(PORTS-1 downto 0); + signal frameRead : RioFrameArray(PORTS-1 downto 0); + signal frameReceived : Array1(PORTS-1 downto 0); + + signal writeFrameFull : Array1(PORTS-1 downto 0); + signal writeFrame : Array1(PORTS-1 downto 0); + signal writeFrameAbort : Array1(PORTS-1 downto 0); + signal writeContent : Array1(PORTS-1 downto 0); + signal writeContentData : Array32(PORTS-1 downto 0); + + signal readFrameEmpty : Array1(PORTS-1 downto 0); + signal readFrame : Array1(PORTS-1 downto 0); + signal readFrameRestart : Array1(PORTS-1 downto 0); + signal readFrameAborted : Array1(PORTS-1 downto 0); + signal readContentEmpty : Array1(PORTS-1 downto 0); + signal readContent : Array1(PORTS-1 downto 0); + signal readContentEnd : Array1(PORTS-1 downto 0); + signal readContentData : Array32(PORTS-1 downto 0); + + signal portLinkTimeout : std_logic_vector(23 downto 0); + + signal linkInitialized : Array1(PORTS-1 downto 0); + signal outputPortEnable : Array1(PORTS-1 downto 0); + signal inputPortEnable : Array1(PORTS-1 downto 0); + + signal localAckIdWrite : Array1(PORTS-1 downto 0); + signal clrOutstandingAckId : Array1(PORTS-1 downto 0); + signal inboundAckIdWrite : Array5(PORTS-1 downto 0); + signal outstandingAckIdWrite : Array5(PORTS-1 downto 0); + signal outboundAckIdWrite : Array5(PORTS-1 downto 0); + signal inboundAckIdRead : Array5(PORTS-1 downto 0); + signal outstandingAckIdRead : Array5(PORTS-1 downto 0); + signal outboundAckIdRead : Array5(PORTS-1 downto 0); + + signal configStb, configStbExpected : std_logic; + signal configWe, configWeExpected : std_logic; + signal configAddr, configAddrExpected : std_logic_vector(23 downto 0); + signal configDataWrite, configDataWriteExpected : std_logic_vector(31 downto 0); + signal configDataRead, configDataReadExpected : std_logic_vector(31 downto 0); + +begin + + ----------------------------------------------------------------------------- + -- Clock generation. + ----------------------------------------------------------------------------- + ClockGenerator: process + begin + clk <= '0'; + wait for 20 ns; + clk <= '1'; + wait for 20 ns; + end process; + + + ----------------------------------------------------------------------------- + -- Serial port emulator. + ----------------------------------------------------------------------------- + TestDriver: process + + --------------------------------------------------------------------------- + -- + --------------------------------------------------------------------------- + procedure SendFrame(constant portIndex : natural range 0 to 7; + constant frame : RioFrame) is + begin + frameValid(portIndex) <= '1'; + frameWrite(portIndex) <= frame; + wait until frameComplete(portIndex) = '1'; + frameValid(portIndex) <= '0'; + end procedure; + + --------------------------------------------------------------------------- + -- + --------------------------------------------------------------------------- + procedure ReceiveFrame(constant portIndex : natural range 0 to 7; + constant frame : RioFrame) is + begin + frameExpected(portIndex) <= '1'; + frameRead(portIndex) <= frame; + wait until frameReceived(portIndex) = '1'; + frameExpected(portIndex) <= '0'; + end procedure; + + --------------------------------------------------------------------------- + -- + --------------------------------------------------------------------------- + procedure ReadConfig32(constant portIndex : natural range 0 to 7; + constant destinationId : std_logic_vector(15 downto 0); + constant sourceId : std_logic_vector(15 downto 0); + constant hop : std_logic_vector(7 downto 0); + constant tid : std_logic_vector(7 downto 0); + constant address : std_logic_vector(23 downto 0); + constant data : std_logic_vector(31 downto 0)) is + variable maintData : DoubleWordArray(0 to 7); + begin + SendFrame(portIndex, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>sourceId, destId=>destinationId, + payload=>RioMaintenance(transaction=>"0000", + size=>"1000", + tid=>tid, + hopCount=>hop, + configOffset=>address(23 downto 3), + wdptr=>address(2), + dataLength=>0, + data=>maintData))); + if (address(2) = '0') then + maintData(0) := data & x"00000000"; + else + maintData(0) := x"00000000" & data ; + end if; + + ReceiveFrame(portIndex, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>destinationId, destId=>sourceId, + payload=>RioMaintenance(transaction=>"0010", + size=>"0000", + tid=>tid, + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'0', + dataLength=>1, + data=>maintData))); + end procedure; + + --------------------------------------------------------------------------- + -- + --------------------------------------------------------------------------- + procedure WriteConfig32(constant portIndex : natural range 0 to 7; + constant destinationId : std_logic_vector(15 downto 0); + constant sourceId : std_logic_vector(15 downto 0); + constant hop : std_logic_vector(7 downto 0); + constant tid : std_logic_vector(7 downto 0); + constant address : std_logic_vector(23 downto 0); + constant data : std_logic_vector(31 downto 0)) is + variable maintData : DoubleWordArray(0 to 7); + begin + if (address(2) = '0') then + maintData(0) := data & x"00000000"; + else + maintData(0) := x"00000000" & data ; + end if; + + SendFrame(portIndex, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>sourceId, destId=>destinationId, + payload=>RioMaintenance(transaction=>"0001", + size=>"1000", + tid=>tid, + hopCount=>hop, + configOffset=>address(23 downto 3), + wdptr=>address(2), + dataLength=>1, + data=>maintData))); + + ReceiveFrame(portIndex, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>destinationId, destId=>sourceId, + payload=>RioMaintenance(transaction=>"0011", + size=>"0000", + tid=>tid, + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'0', + dataLength=>0, + data=>maintData))); + end procedure; + + --------------------------------------------------------------------------- + -- + --------------------------------------------------------------------------- + procedure RouteFrame(constant sourcePortIndex : natural range 0 to 7; + constant destinationPortIndex : natural range 0 to 7; + constant sourceId : std_logic_vector(15 downto 0); + constant destinationId : std_logic_vector(15 downto 0); + constant payload : RioPayload) is + variable frame : RioFrame; + begin + frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>sourceId, destId=>destinationId, + payload=>payload); + + frameExpected(destinationPortIndex) <= '1'; + frameRead(destinationPortIndex) <= frame; + + frameValid(sourcePortIndex) <= '1'; + frameWrite(sourcePortIndex) <= frame; + wait until frameComplete(sourcePortIndex) = '1'; + frameValid(sourcePortIndex) <= '0'; + + wait until frameReceived(destinationPortIndex) = '1'; + frameExpected(destinationPortIndex) <= '0'; + + end procedure; + + --------------------------------------------------------------------------- + -- + --------------------------------------------------------------------------- + procedure SendFrame(constant portIndex : natural range 0 to 7; + constant sourceId : std_logic_vector(15 downto 0); + constant destinationId : std_logic_vector(15 downto 0); + constant payload : RioPayload) is + variable frame : RioFrame; + begin + frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>sourceId, destId=>destinationId, + payload=>payload); + + frameValid(portIndex) <= '1'; + frameWrite(portIndex) <= frame; + end procedure; + + --------------------------------------------------------------------------- + -- + --------------------------------------------------------------------------- + procedure ReceiveFrame(constant portIndex : natural range 0 to 7; + constant sourceId : std_logic_vector(15 downto 0); + constant destinationId : std_logic_vector(15 downto 0); + constant payload : RioPayload) is + variable frame : RioFrame; + begin + frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>"0000", + sourceId=>sourceId, destId=>destinationId, + payload=>payload); + + frameExpected(portIndex) <= '1'; + frameRead(portIndex) <= frame; + end procedure; + + -- These variabels are needed for the random number generation. + variable seed1 : positive := 1; + variable seed2: positive := 1; + + variable data : DoubleWordArray(0 to 31); + variable randomPayload : RioPayload; + variable randomPayload1 : RioPayload; + variable randomPayload2 : RioPayload; + variable frame : RioFrameArray(0 to PORTS-1); + + begin + areset_n <= '0'; + + linkInitialized <= (others=>'0'); + + for portIndex in 0 to PORTS-1 loop + frameValid(portIndex) <= '0'; + frameExpected(portIndex) <= '0'; + localAckIdWrite(portIndex) <= '0'; + clrOutstandingAckId(portIndex) <= '0'; + inboundAckIdWrite(portIndex) <= (others=>'0'); + outstandingAckIdWrite(portIndex) <= (others=>'0'); + outboundAckIdWrite(portIndex) <= (others=>'0'); + end loop; + + wait until clk'event and clk = '1'; + wait until clk'event and clk = '1'; + areset_n <= '1'; + wait until clk'event and clk = '1'; + wait until clk'event and clk = '1'; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioSwitch"); + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioSwitch-TC1"); + PrintS("Description: Test switch maintenance accesses on different ports."); + PrintS("Requirement: XXXXX"); + PrintS("-----------------------------------------------------------------"); + PrintS("Step 1:"); + PrintS("Action: Send maintenance read request packets to read switch identity."); + PrintS("Result: The switch should answer with its configured identitiy."); + --------------------------------------------------------------------------- + PrintR("TG_RioSwitch-TC1-Step1"); + --------------------------------------------------------------------------- + + ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"00", address=>x"000000", data=>(SWITCH_IDENTITY & SWITCH_VENDOR_IDENTITY)); + ReadConfig32(portIndex=>1, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"01", address=>x"000004", data=>SWITCH_REV); + ReadConfig32(portIndex=>2, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"02", address=>x"000008", data=>(SWITCH_ASSY_IDENTITY & SWITCH_ASSY_VENDOR_IDENTITY)); + ReadConfig32(portIndex=>3, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"03", address=>x"00000c", data=>(SWITCH_ASSY_REV & x"0100")); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 2:"); + PrintS("Action: Check the switch Processing Element Features."); + PrintS("Result: The expected switch features should be returned. "); + PrintS(" Switch with extended features pointer valid. Common "); + PrintS(" transport large system support and standard route table "); + PrintS(" configuration support."); + --------------------------------------------------------------------------- + PrintR("TG_RioSwitch-TC1-Step2"); + --------------------------------------------------------------------------- + + ReadConfig32(portIndex=>4, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"04", address=>x"000010", data=>x"10000118"); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 3:"); + PrintS("Action: Check the switch port information."); + PrintS("Result: The expected port and number of ports should be returned."); + --------------------------------------------------------------------------- + PrintR("TG_RioSwitch-TC1-Step3"); + --------------------------------------------------------------------------- + + ReadConfig32(portIndex=>5, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"05", address=>x"000014", data=>x"00000705"); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 4:"); + PrintS("Action: Check the switch number of supported routes."); + PrintS("Result: The expected number of supported routes should be returned."); + --------------------------------------------------------------------------- + PrintR("TG_RioSwitch-TC1-Step4"); + --------------------------------------------------------------------------- + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"000034", data=>x"00000800"); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 5:"); + PrintS("Action: Test host base device id lock by reading it, then hold it "); + PrintS(" and try to grab it from another address."); + PrintS("Result: The value should follow the specification."); + --------------------------------------------------------------------------- + PrintR("TG_RioSwitch-TC1-Step5"); + --------------------------------------------------------------------------- + + -- Check that the lock is released. + ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"00", address=>x"000068", data=>x"0000ffff"); + + -- Try to accuire the lock. + WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"00", address=>x"000068", data=>x"00000002"); + + -- Check that the lock has been accuired. + ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"00", address=>x"000068", data=>x"00000002"); + + -- Try to accuire the lock from another source. + WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"00", address=>x"000068", data=>x"00000003"); + + -- Check that the lock refuses the new access. + ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"00", address=>x"000068", data=>x"00000002"); + + -- Release the lock. + WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"00", address=>x"000068", data=>x"00000002"); + + -- Check that the lock is released. + ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"00", address=>x"000068", data=>x"0000ffff"); + + -- Check that the lock can be accuired from another source once unlocked. + WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"00", address=>x"000068", data=>x"00000003"); + + -- Check that the lock is released. + ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"00", address=>x"000068", data=>x"00000003"); + + -- Release the lock again. + WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"00", address=>x"000068", data=>x"00000003"); + + -- Check that the lock is released. + ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"00", address=>x"000068", data=>x"0000ffff"); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 6"); + PrintS("Action: Check the component tag register."); + PrintS("Result: The written value in the component tag should be saved."); + --------------------------------------------------------------------------- + PrintR("TG_RioSwitch-TC1-Step6"); + --------------------------------------------------------------------------- + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00006c", data=>x"00000000"); + + WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00006c", data=>x"ffffffff"); + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00006c", data=>x"ffffffff"); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 7"); + PrintS("Action: Read and write to the port link timeout."); + PrintS("Result: Check that the portLinkTimeout output from the switch changes."); + --------------------------------------------------------------------------- + PrintR("TG_RioSwitch-TC1-Step7"); + --------------------------------------------------------------------------- + + assert portLinkTimeout = x"ffffff" report "Unexpected portLinkTimeout." severity error; + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"000120", data=>x"ffffff00"); + + WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"000120", data=>x"00000100"); + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"000120", data=>x"00000100"); + + assert portLinkTimeout = x"000001" report "Unexpected portLinkTimeout." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 8"); + PrintS("Action: Read from the port general control."); + PrintS("Result: Check the discovered bit."); + --------------------------------------------------------------------------- + PrintR("TG_RioSwitch-TC1-Step8"); + --------------------------------------------------------------------------- + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00013c", data=>x"00000000"); + + WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00013c", data=>x"20000000"); + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00013c", data=>x"20000000"); + + WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00013c", data=>x"00000000"); + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00013c", data=>x"00000000"); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 9"); + PrintS("Action: Read from the port N error and status."); + PrintS("Result: Check the port ok and port uninitialized bits."); + --------------------------------------------------------------------------- + PrintR("TG_RioSwitch-TC1-Step9"); + --------------------------------------------------------------------------- + + linkInitialized(0) <= '0'; + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"000158", data=>x"00000001"); + linkInitialized(0) <= '1'; + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"000158", data=>x"00000002"); + + linkInitialized(1) <= '0'; + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"000178", data=>x"00000001"); + linkInitialized(1) <= '1'; + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"000178", data=>x"00000002"); + + linkInitialized(2) <= '0'; + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"000198", data=>x"00000001"); + linkInitialized(2) <= '1'; + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"000198", data=>x"00000002"); + + linkInitialized(3) <= '0'; + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"0001b8", data=>x"00000001"); + linkInitialized(3) <= '1'; + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"0001b8", data=>x"00000002"); + + linkInitialized(4) <= '0'; + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"0001d8", data=>x"00000001"); + linkInitialized(4) <= '1'; + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"0001d8", data=>x"00000002"); + + linkInitialized(5) <= '0'; + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"0001f8", data=>x"00000001"); + linkInitialized(5) <= '1'; + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"0001f8", data=>x"00000002"); + + linkInitialized(6) <= '0'; + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"000218", data=>x"00000001"); + linkInitialized(6) <= '1'; + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"000218", data=>x"00000002"); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 10"); + PrintS("Action: Read and write to/from the port N control."); + PrintS("Result: Check the output/input port enable."); + --------------------------------------------------------------------------- + PrintR("TG_RioSwitch-TC1-Step10"); + --------------------------------------------------------------------------- + + assert outputPortEnable(0) = '0' report "Unexpected outputPortEnable." severity error; + assert inputPortEnable(0) = '0' report "Unexpected inputPortEnable." severity error; + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00015c", data=>x"00000001"); + + WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00015c", data=>x"00600001"); + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00015c", data=>x"00600001"); + + assert outputPortEnable(0) = '1' report "Unexpected outputPortEnable." severity error; + assert inputPortEnable(0) = '1' report "Unexpected inputPortEnable." severity error; + + --------------------------------------------------------------------------- + + assert outputPortEnable(1) = '0' report "Unexpected outputPortEnable." severity error; + assert inputPortEnable(1) = '0' report "Unexpected inputPortEnable." severity error; + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00017c", data=>x"00000001"); + + WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00017c", data=>x"00600001"); + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00017c", data=>x"00600001"); + + assert outputPortEnable(1) = '1' report "Unexpected outputPortEnable." severity error; + assert inputPortEnable(1) = '1' report "Unexpected inputPortEnable." severity error; + + --------------------------------------------------------------------------- + + assert outputPortEnable(2) = '0' report "Unexpected outputPortEnable." severity error; + assert inputPortEnable(2) = '0' report "Unexpected inputPortEnable." severity error; + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00019c", data=>x"00000001"); + + WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00019c", data=>x"00600001"); + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00019c", data=>x"00600001"); + + assert outputPortEnable(2) = '1' report "Unexpected outputPortEnable." severity error; + assert inputPortEnable(2) = '1' report "Unexpected inputPortEnable." severity error; + + --------------------------------------------------------------------------- + + assert outputPortEnable(3) = '0' report "Unexpected outputPortEnable." severity error; + assert inputPortEnable(3) = '0' report "Unexpected inputPortEnable." severity error; + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"0001bc", data=>x"00000001"); + + WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"0001bc", data=>x"00600001"); + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"0001bc", data=>x"00600001"); + + assert outputPortEnable(3) = '1' report "Unexpected outputPortEnable." severity error; + assert inputPortEnable(3) = '1' report "Unexpected inputPortEnable." severity error; + + --------------------------------------------------------------------------- + + assert outputPortEnable(4) = '0' report "Unexpected outputPortEnable." severity error; + assert inputPortEnable(4) = '0' report "Unexpected inputPortEnable." severity error; + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"0001dc", data=>x"00000001"); + + WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"0001dc", data=>x"00600001"); + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"0001dc", data=>x"00600001"); + + assert outputPortEnable(4) = '1' report "Unexpected outputPortEnable." severity error; + assert inputPortEnable(4) = '1' report "Unexpected inputPortEnable." severity error; + + --------------------------------------------------------------------------- + + assert outputPortEnable(5) = '0' report "Unexpected outputPortEnable." severity error; + assert inputPortEnable(5) = '0' report "Unexpected inputPortEnable." severity error; + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"0001fc", data=>x"00000001"); + + WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"0001fc", data=>x"00600001"); + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"0001fc", data=>x"00600001"); + + assert outputPortEnable(5) = '1' report "Unexpected outputPortEnable." severity error; + assert inputPortEnable(5) = '1' report "Unexpected inputPortEnable." severity error; + + --------------------------------------------------------------------------- + + assert outputPortEnable(6) = '0' report "Unexpected outputPortEnable." severity error; + assert inputPortEnable(6) = '0' report "Unexpected inputPortEnable." severity error; + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00021c", data=>x"00000001"); + + WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00021c", data=>x"00600001"); + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"00021c", data=>x"00600001"); + + assert outputPortEnable(6) = '1' report "Unexpected outputPortEnable." severity error; + assert inputPortEnable(6) = '1' report "Unexpected inputPortEnable." severity error; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 11"); + PrintS("Action: Read and write to/from the implementation defined space."); + PrintS("Result: Check the accesses on the external configuration port."); + --------------------------------------------------------------------------- + PrintR("TG_RioSwitch-TC1-Step11"); + --------------------------------------------------------------------------- + + configStbExpected <= '1'; + configWeExpected <= '0'; + configAddrExpected <= x"010000"; + configDataReadExpected <= x"deadbeef"; + + ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"010000", data=>x"deadbeef"); + + configStbExpected <= '1'; + configWeExpected <= '1'; + configAddrExpected <= x"010004"; + configDataWriteExpected <= x"c0debabe"; + + WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"06", address=>x"010004", data=>x"c0debabe"); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioSwitch-TC2"); + PrintS("Description: Test the configuration of the routing table and the "); + PrintS(" routing of packets."); + PrintS("Requirement: XXXXX"); + PrintS("-----------------------------------------------------------------"); + PrintS("Step 1:"); + PrintS("Action: Configure the routing table for address 0->port 1."); + PrintS("Result: A packet to address 0 should be forwarded to port 1."); + --------------------------------------------------------------------------- + PrintR("TG_RioSwitch-TC2-Step1"); + --------------------------------------------------------------------------- + + ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"07", address=>x"000070", data=>x"00000000"); + WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"08", address=>x"000074", data=>x"00000001"); + ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"09", address=>x"000074", data=>x"00000001"); + + -- Send a frame from a port and check if it is correctly routed. + randomPayload.length := 3; + CreateRandomPayload(randomPayload.data, seed1, seed2); + RouteFrame(sourcePortIndex=>0, destinationPortIndex=>1, + sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 2:"); + PrintS("Action: Test the configuration of the default route->port 6."); + PrintS("Result: An unknown address should be routed to port 6."); + --------------------------------------------------------------------------- + PrintR("TG_RioSwitch-TC2-Step2"); + --------------------------------------------------------------------------- + + ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"0a", address=>x"000078", data=>x"00000000"); + WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"0b", address=>x"000078", data=>x"00000006"); + ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", + tid=>x"0c", address=>x"000078", data=>x"00000006"); + + -- Send a frame from a port and check if it is correctly routed. + randomPayload.length := 4; + CreateRandomPayload(randomPayload.data, seed1, seed2); + RouteFrame(sourcePortIndex=>1, destinationPortIndex=>6, + sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioSwitch-TC3"); + PrintS("Description: Test the routing of normal packets."); + PrintS("Requirement: XXXXX"); + PrintS("-----------------------------------------------------------------"); + PrintS("Step 1:"); + PrintS("Action: Send two packets but not the same time."); + PrintS("Result: Both packets should be received at the expected ports."); + --------------------------------------------------------------------------- + PrintR("TG_RioSwitch-TC3-Step1"); + --------------------------------------------------------------------------- + + -- Frame on port 0 to port 1. + randomPayload.length := 3; + CreateRandomPayload(randomPayload.data, seed1, seed2); + SendFrame(portIndex=>0, + sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload); + ReceiveFrame(portIndex=>1, + sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload); + + -- Frame on port 1 to port 6. + randomPayload.length := 4; + CreateRandomPayload(randomPayload.data, seed1, seed2); + SendFrame(portIndex=>1, + sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload); + ReceiveFrame(portIndex=>6, + sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload); + + wait until frameComplete(1) = '1'; + frameValid(1) <= '0'; + wait until frameReceived(6) = '1'; + frameExpected(6) <= '0'; + + wait until frameComplete(0) = '1'; + frameValid(0) <= '0'; + wait until frameReceived(1) = '1'; + frameExpected(1) <= '0'; + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 2:"); + PrintS("Action: Send two packets to the same port with is full and one to"); + PrintS(" another that is also full. Then receive the packets one at"); + PrintS(" a time."); + PrintS("Result: The packet to the port that is ready should go though."); + --------------------------------------------------------------------------- + PrintR("TG_RioSwitch-TC3-Step2"); + --------------------------------------------------------------------------- + + -- Frame on port 0 to port 1. + randomPayload.length := 5; + CreateRandomPayload(randomPayload.data, seed1, seed2); + SendFrame(portIndex=>0, + sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload); + + -- Frame on port 1 to port 6. + randomPayload1.length := 6; + CreateRandomPayload(randomPayload1.data, seed1, seed2); + SendFrame(portIndex=>1, + sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload1); + + -- Frame on port 2 to port 6. + randomPayload2.length := 7; + CreateRandomPayload(randomPayload2.data, seed1, seed2); + SendFrame(portIndex=>2, + sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload2); + + wait for 10 us; + + ReceiveFrame(portIndex=>1, + sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload); + wait until frameComplete(0) = '1'; + frameValid(0) <= '0'; + wait until frameReceived(1) = '1'; + frameExpected(1) <= '0'; + + wait for 10 us; + + ReceiveFrame(portIndex=>6, + sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload1); + wait until frameComplete(1) = '1'; + frameValid(1) <= '0'; + wait until frameReceived(6) = '1'; + frameExpected(6) <= '0'; + + wait for 10 us; + + ReceiveFrame(portIndex=>6, + sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload2); + wait until frameComplete(2) = '1'; + frameValid(2) <= '0'; + wait until frameReceived(6) = '1'; + frameExpected(6) <= '0'; + + --------------------------------------------------------------------------- + -- Test completed. + --------------------------------------------------------------------------- + + wait for 10 us; + + assert readContentEmpty = "1111111" + report "Pending frames exist." severity error; + + TestEnd; + end process; + + ----------------------------------------------------------------------------- + -- Instantiate a process receiving the configuration accesses to the + -- implementation defined space. + ----------------------------------------------------------------------------- + process + begin + loop + wait until configStb = '1' and clk'event and clk = '1'; + assert configStb = configStbExpected report "Unexpected configStb." severity error; + assert configWe = configWeExpected report "Unexpected configWe." severity error; + assert configAddr = configAddrExpected report "Unexpected configAddr." severity error; + if (configWe = '1') then + assert configDataWrite = configDataWriteExpected report "Unexpected configDataWrite." severity error; + else + configDataRead <= configDataReadExpected; + end if; + end loop; + end process; + + ----------------------------------------------------------------------------- + -- Instantiate the test port array. + ----------------------------------------------------------------------------- + + TestPortGeneration: for portIndex in 0 to PORTS-1 generate + TestPortInst: TestPort + port map( + clk=>clk, areset_n=>areset_n, + frameValid_i=>frameValid(portIndex), + frameWrite_i=>frameWrite(portIndex), + frameComplete_o=>frameComplete(portIndex), + frameExpected_i=>frameExpected(portIndex), + frameRead_i=>frameRead(portIndex), + frameReceived_o=>frameReceived(portIndex), + readFrameEmpty_o=>readFrameEmpty(portIndex), + readFrame_i=>readFrame(portIndex), + readFrameRestart_i=>readFrameRestart(portIndex), + readFrameAborted_o=>readFrameAborted(portIndex), + readContentEmpty_o=>readContentEmpty(portIndex), + readContent_i=>readContent(portIndex), + readContentEnd_o=>readContentEnd(portIndex), + readContentData_o=>readContentData(portIndex), + writeFrameFull_o=>writeFrameFull(portIndex), + writeFrame_i=>writeFrame(portIndex), + writeFrameAbort_i=>writeFrameAbort(portIndex), + writeContent_i=>writeContent(portIndex), + writeContentData_i=>writeContentData(portIndex)); + end generate; + + ----------------------------------------------------------------------------- + -- Instantiate the switch. + ----------------------------------------------------------------------------- + + TestSwitch: RioSwitch + generic map( + SWITCH_PORTS=>7, + DEVICE_IDENTITY=>SWITCH_IDENTITY, + DEVICE_VENDOR_IDENTITY=>SWITCH_VENDOR_IDENTITY, + DEVICE_REV=>SWITCH_REV, + ASSY_IDENTITY=>SWITCH_ASSY_IDENTITY, + ASSY_VENDOR_IDENTITY=>SWITCH_ASSY_VENDOR_IDENTITY, + ASSY_REV=>SWITCH_ASSY_REV) + port map( + clk=>clk, areset_n=>areset_n, + writeFrameFull_i=>writeFrameFull, + writeFrame_o=>writeFrame, writeFrameAbort_o=>writeFrameAbort, + writeContent_o=>writeContent, writeContentData_o=>writeContentData, + readFrameEmpty_i=>readFrameEmpty, + readFrame_o=>readFrame, readFrameRestart_o=>readFrameRestart, + readFrameAborted_i=>readFrameAborted, + readContentEmpty_i=>readContentEmpty, + readContent_o=>readContent, readContentEnd_i=>readContentEnd, + readContentData_i=>readContentData, + portLinkTimeout_o=>portLinkTimeout, + linkInitialized_i=>linkInitialized, + outputPortEnable_o=>outputPortEnable, inputPortEnable_o=>inputPortEnable, + localAckIdWrite_o=>localAckIdWrite, + clrOutstandingAckId_o=>clrOutstandingAckId, + inboundAckId_o=>inboundAckIdWrite, + outstandingAckId_o=>outstandingAckIdWrite, + outboundAckId_o=>outboundAckIdWrite, + inboundAckId_i=>inboundAckIdRead, + outstandingAckId_i=>outstandingAckIdRead, + outboundAckId_i=>outboundAckIdRead, + configStb_o=>configStb, configWe_o=>configWe, configAddr_o=>configAddr, + configData_o=>configDataWrite, configData_i=>configDataRead); + + +end architecture; + + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +-- REMARK: Add support for testing partially complete frames, cut-through-routing... +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library std; +use std.textio.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +entity TestPort is + port( + clk : in std_logic; + areset_n : in std_logic; + + frameValid_i : in std_logic; + frameWrite_i : in RioFrame; + frameComplete_o : out std_logic; + + frameExpected_i : in std_logic; + frameRead_i : in RioFrame; + frameReceived_o : out std_logic; + + readFrameEmpty_o : out std_logic; + readFrame_i : in std_logic; + readFrameRestart_i : in std_logic; + readFrameAborted_o : out std_logic; + readContentEmpty_o : out std_logic; + readContent_i : in std_logic; + readContentEnd_o : out std_logic; + readContentData_o : out std_logic_vector(31 downto 0); + + writeFrameFull_o : out std_logic; + writeFrame_i : in std_logic; + writeFrameAbort_i : in std_logic; + writeContent_i : in std_logic; + writeContentData_i : in std_logic_vector(31 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +architecture TestPortImpl of TestPort is +begin + + ----------------------------------------------------------------------------- + -- + ----------------------------------------------------------------------------- + FrameReader: process + type StateType is (STATE_IDLE, STATE_WRITE); + variable state : StateType; + variable frameIndex : natural range 0 to 69; + begin + writeFrameFull_o <= '1'; + frameReceived_o <= '0'; + wait until areset_n = '1'; + + state := STATE_IDLE; + + loop + wait until clk'event and clk = '1'; + + case state is + + when STATE_IDLE => + frameReceived_o <= '0'; + if (frameExpected_i = '1') then + writeFrameFull_o <= '0'; + state := STATE_WRITE; + frameIndex := 0; + else + writeFrameFull_o <= '1'; + end if; + assert writeFrame_i = '0' report "Unexpected frame." severity error; + assert writeFrameAbort_i = '0' report "Unexpected frame abort." severity error; + assert writeContent_i = '0' report "Unexpected data." severity error; + + when STATE_WRITE => + if (writeContent_i = '1') then + -- Writing content. + if (frameIndex < frameRead_i.length) then + assert writeContentData_i = frameRead_i.payload(frameIndex) + report "Unexpected frame content received:" & + " index=" & integer'image(frameIndex) & + " expected=" & integer'image(to_integer(unsigned(frameRead_i.payload(frameIndex)))) & + " got=" & integer'image(to_integer(unsigned(writeContentData_i))) + severity error; + + frameIndex := frameIndex + 1; + else + report "Unexpected frame content received:" & + " index=" & integer'image(frameIndex) & + " expected=" & integer'image(to_integer(unsigned(frameRead_i.payload(frameIndex)))) & + " got=" & integer'image(to_integer(unsigned(writeContentData_i))) + severity error; + + frameIndex := frameIndex + 1; + end if; + else + -- Not writing any content. + end if; + + if (writeFrame_i = '1') then + -- Writing a complete frame. + assert frameIndex = frameRead_i.length report "Unexpected frame length received." severity error; + state := STATE_IDLE; + frameReceived_o <= '1'; + writeFrameFull_o <= '1'; + else + -- Not writing any frame. + end if; + + if (writeFrameAbort_i = '1') then + -- The frame should be aborted. + frameIndex := 0; + else + -- Not aborting any frame. + end if; + end case; + end loop; + end process; + + ----------------------------------------------------------------------------- + -- + ----------------------------------------------------------------------------- + -- REMARK: add support for these signals... + -- readFrameEmpty_i : in std_logic; + -- readFrameAborted_i : in std_logic; + FrameSender: process + type StateType is (STATE_IDLE, STATE_READ); + variable state : StateType; + variable frameIndex : natural range 0 to 69; + begin + readFrameEmpty_o <= '1'; + readFrameAborted_o <= '0'; + readContentEmpty_o <= '1'; + readContentEnd_o <= '1'; + readContentData_o <= (others => 'U'); + frameComplete_o <= '0'; + wait until areset_n = '1'; + + state := STATE_IDLE; + + loop + wait until clk'event and clk = '1'; + + case state is + + when STATE_IDLE => + frameComplete_o <= '0'; + if (frameValid_i = '1') then + state := STATE_READ; + frameIndex := 0; + readContentEmpty_o <= '0'; + readFrameEmpty_o <= '0'; + else + readContentEmpty_o <= '1'; + end if; + + when STATE_READ => + if (readFrameRestart_i = '1') then + readContentEnd_o <= '0'; + frameIndex := 0; + else + -- Not restarting a frame. + end if; + + if (readContent_i = '1') then + if (frameIndex < frameWrite_i.length) then + readContentData_o <= frameWrite_i.payload(frameIndex); + readContentEnd_o <= '0'; + frameIndex := frameIndex + 1; + elsif (frameIndex = frameWrite_i.length) then + readContentEnd_o <= '1'; + else + report "Reading empty frame." severity error; + end if; + else + -- Not reading data. + end if; + + if (readFrame_i = '1') then + state := STATE_IDLE; + assert frameIndex = frameWrite_i.length report "Unread frame data discarded." severity error; + frameComplete_o <= '1'; + readFrameEmpty_o <= '1'; + readContentEmpty_o <= '1'; + readContentData_o <= (others => 'U'); + else + -- Not reading a frame. + end if; + + end case; + end loop; + end process; + +end architecture;
2.0.0-alpha/bench/vhdl/TestRioSwitch.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: 2.0.0-alpha/doc/rio.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: 2.0.0-alpha/doc/rio.pdf =================================================================== --- 2.0.0-alpha/doc/rio.pdf (nonexistent) +++ 2.0.0-alpha/doc/rio.pdf (revision 23)
2.0.0-alpha/doc/rio.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: 2.0.0-alpha/doc/rio.odt =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: 2.0.0-alpha/doc/rio.odt =================================================================== --- 2.0.0-alpha/doc/rio.odt (nonexistent) +++ 2.0.0-alpha/doc/rio.odt (revision 23)
2.0.0-alpha/doc/rio.odt Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property

powered by: WebSVN 2.1.0

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