URL
https://opencores.org/ocsvn/rio/rio/trunk
Subversion Repositories rio
Compare Revisions
- This comparison shows the changes necessary to convert path
/rio/branches
- from Rev 19 to Rev 21
- ↔ Reverse comparison
Rev 19 → Rev 21
/singleSymbol/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; |
|
singleSymbol/rtl/vhdl/RioSerial.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: singleSymbol/rtl/vhdl/RioPacketBuffer.vhd
===================================================================
--- singleSymbol/rtl/vhdl/RioPacketBuffer.vhd (nonexistent)
+++ singleSymbol/rtl/vhdl/RioPacketBuffer.vhd (revision 21)
@@ -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;
singleSymbol/rtl/vhdl/RioPacketBuffer.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: singleSymbol/rtl/vhdl/srio_pcs_struct.vhd
===================================================================
--- singleSymbol/rtl/vhdl/srio_pcs_struct.vhd (nonexistent)
+++ singleSymbol/rtl/vhdl/srio_pcs_struct.vhd (revision 21)
@@ -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: singleSymbol/rtl/vhdl/RioWbBridge.vhd
===================================================================
--- singleSymbol/rtl/vhdl/RioWbBridge.vhd (nonexistent)
+++ singleSymbol/rtl/vhdl/RioWbBridge.vhd (revision 21)
@@ -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;
singleSymbol/rtl/vhdl/RioWbBridge.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: singleSymbol/rtl/vhdl/RioCommon.vhd
===================================================================
--- singleSymbol/rtl/vhdl/RioCommon.vhd (nonexistent)
+++ singleSymbol/rtl/vhdl/RioCommon.vhd (revision 21)
@@ -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;
+
+
+
+
+
singleSymbol/rtl/vhdl/RioCommon.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: singleSymbol/rtl/vhdl/RioSwitch.vhd
===================================================================
--- singleSymbol/rtl/vhdl/RioSwitch.vhd (nonexistent)
+++ singleSymbol/rtl/vhdl/RioSwitch.vhd (revision 21)
@@ -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;
+
+
+
singleSymbol/rtl/vhdl/RioSwitch.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: singleSymbol/bench/vhdl/TestRioSerial.vhd
===================================================================
--- singleSymbol/bench/vhdl/TestRioSerial.vhd (nonexistent)
+++ singleSymbol/bench/vhdl/TestRioSerial.vhd (revision 21)
@@ -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;
singleSymbol/bench/vhdl/TestRioSerial.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: singleSymbol/bench/vhdl/TestRioPacketBuffer.vhd
===================================================================
--- singleSymbol/bench/vhdl/TestRioPacketBuffer.vhd (nonexistent)
+++ singleSymbol/bench/vhdl/TestRioPacketBuffer.vhd (revision 21)
@@ -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;
singleSymbol/bench/vhdl/TestRioPacketBuffer.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: singleSymbol/bench/vhdl/TestRioSwitch.vhd
===================================================================
--- singleSymbol/bench/vhdl/TestRioSwitch.vhd (nonexistent)
+++ singleSymbol/bench/vhdl/TestRioSwitch.vhd (revision 21)
@@ -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;
singleSymbol/bench/vhdl/TestRioSwitch.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: singleSymbol/doc/rio.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: singleSymbol/doc/rio.pdf
===================================================================
--- singleSymbol/doc/rio.pdf (nonexistent)
+++ singleSymbol/doc/rio.pdf (revision 21)
singleSymbol/doc/rio.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: singleSymbol/doc/rio.odt
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: singleSymbol/doc/rio.odt
===================================================================
--- singleSymbol/doc/rio.odt (nonexistent)
+++ singleSymbol/doc/rio.odt (revision 21)
singleSymbol/doc/rio.odt
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property