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

Subversion Repositories rio

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /rio
    from Rev 40 to Rev 41
    Reverse comparison

Rev 40 → Rev 41

/branches/2.0.0-development/bench/vhdl/TestRioSerial.vhd
0,0 → 1,3017
-------------------------------------------------------------------------------
--
-- 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
--
-------------------------------------------------------------------------------
-- REMARK: Add testcase to check that no packets are sent when the linkpartner
-- has no buffers left.
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.rio_common.all;
 
package TestRioSerialPackage is
type MessageSymbol is record
symbolType : std_logic_vector(1 downto 0);
symbolContent : std_logic_vector(31 downto 0);
ignoreIdle : boolean;
end record;
type MessageFrame is record
frame : RioFrame;
willAbort : boolean;
end record;
end package;
 
package body TestRioSerialPackage is
 
end package body;
 
 
 
-------------------------------------------------------------------------------
-- 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;
use work.TestRioSerialPackage.all;
 
 
-------------------------------------------------------------------------------
-- Entity for TestRioSerial.
-------------------------------------------------------------------------------
entity TestRioSerial is
end entity;
 
 
-------------------------------------------------------------------------------
-- Architecture for TestUart.
-------------------------------------------------------------------------------
architecture TestRioSerialImpl of TestRioSerial is
component TestSwitchPort is
port(
clk : in std_logic;
areset_n : in std_logic;
 
outboundWriteEmpty_o : out std_logic;
outboundWrite_i : in std_logic;
outboundWriteMessage_i : in MessageFrame;
outboundWriteAck_o : out std_logic;
inboundWriteEmpty_o : out std_logic;
inboundWrite_i : in std_logic;
inboundWriteMessage_i : in MessageFrame;
inboundWriteAck_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);
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;
SYMBOL_COUNTER_WIDTH : natural := 8;
TICKS_SEND_STATUS_STARTUP : natural := 15;
TICKS_SEND_STATUS_OPERATIONAL : natural := 255);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
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;
outboundControlValid_o : out std_logic;
outboundControlSymbol_o : out std_logic_vector(23 downto 0);
outboundDataValid_o : out std_logic;
outboundDataSymbol_o : out std_logic_vector(31 downto 0);
inboundControlValid_i : in std_logic;
inboundControlSymbol_i : in std_logic_vector(23 downto 0);
inboundDataValid_i : in std_logic;
inboundDataSymbol_i : in std_logic_vector(31 downto 0));
end component;
 
component TestSymbolPort is
port(
clk : in std_logic;
areset_n : in std_logic;
 
portInitialized_i : in std_logic;
outboundControlValid_i : in std_logic;
outboundControlSymbol_i : in std_logic_vector(23 downto 0);
outboundDataValid_i : in std_logic;
outboundDataSymbol_i : in std_logic_vector(31 downto 0);
inboundControlValid_o : out std_logic;
inboundControlSymbol_o : out std_logic_vector(23 downto 0);
inboundDataValid_o : out std_logic;
inboundDataSymbol_o : out std_logic_vector(31 downto 0);
 
outboundWriteEmpty_o : out std_logic;
outboundWrite_i : in std_logic;
outboundWriteMessage_i : in MessageSymbol;
outboundWriteAck_o : out std_logic;
inboundWriteEmpty_o : out std_logic;
inboundWrite_i : in std_logic;
inboundWriteMessage_i : in MessageSymbol;
inboundWriteAck_o : out std_logic);
end component;
 
signal clk : std_logic;
signal areset_n : std_logic;
signal enable : std_logic;
 
signal portLinkTimeout : std_logic_vector(10 downto 0);
signal linkInitialized, linkInitializedExpected : 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 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 writeFrame : std_logic;
signal writeFrameAbort : std_logic;
signal writeContent : std_logic;
signal writeContentData : std_logic_vector(31 downto 0);
 
signal portInitialized : std_logic;
signal outboundControlValid : std_logic;
signal outboundControlSymbol : std_logic_vector(23 downto 0);
signal outboundDataValid : std_logic;
signal outboundDataSymbol : std_logic_vector(31 downto 0);
signal inboundControlValid : std_logic;
signal inboundControlSymbol : std_logic_vector(23 downto 0);
signal inboundDataValid : std_logic;
signal inboundDataSymbol : std_logic_vector(31 downto 0);
 
signal outboundFrameWriteEmpty : std_logic;
signal outboundFrameWrite : std_logic;
signal outboundFrameWriteMessage : MessageFrame;
signal outboundFrameWriteAck : std_logic;
signal inboundFrameWriteEmpty : std_logic;
signal inboundFrameWrite : std_logic;
signal inboundFrameWriteMessage : MessageFrame;
signal inboundFrameWriteAck : std_logic;
signal inboundFrameFull : std_logic;
 
signal outboundSymbolWriteEmpty : std_logic;
signal outboundSymbolWrite : std_logic;
signal outboundSymbolWriteMessage : MessageSymbol;
signal outboundSymbolWriteAck : std_logic;
signal inboundSymbolWriteEmpty : std_logic;
signal inboundSymbolWrite : std_logic;
signal inboundSymbolWriteMessage : MessageSymbol;
signal inboundSymbolWriteAck : 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
 
---------------------------------------------------------------------------
-- Procedures to receive symbols.
---------------------------------------------------------------------------
procedure OutboundSymbolIdle is
begin
outboundSymbolWrite <= '1';
outboundSymbolWriteMessage.symbolType <= "00";
outboundSymbolWriteMessage.symbolContent <= (others=>'U');
outboundSymbolWriteMessage.ignoreIdle <= false;
wait until outboundSymbolWriteAck = '1';
outboundSymbolWrite <= '0';
wait until outboundSymbolWriteAck = '0';
end procedure;
 
procedure OutboundSymbolControl(constant symbolContent : in std_logic_vector(23 downto 0);
constant ignoreIdle : in boolean := false) is
begin
outboundSymbolWrite <= '1';
outboundSymbolWriteMessage.symbolType <= "01";
outboundSymbolWriteMessage.symbolContent <= x"00" & symbolContent;
outboundSymbolWriteMessage.ignoreIdle <= ignoreIdle;
wait until outboundSymbolWriteAck = '1';
outboundSymbolWrite <= '0';
wait until outboundSymbolWriteAck = '0';
end procedure;
 
procedure OutboundSymbolData(constant symbolContent : in std_logic_vector(31 downto 0);
constant ignoreIdle : in boolean := false) is
begin
outboundSymbolWrite <= '1';
outboundSymbolWriteMessage.symbolType <= "10";
outboundSymbolWriteMessage.symbolContent <= symbolContent;
outboundSymbolWriteMessage.ignoreIdle <= ignoreIdle;
wait until outboundSymbolWriteAck = '1';
outboundSymbolWrite <= '0';
wait until outboundSymbolWriteAck = '0';
end procedure;
 
---------------------------------------------------------------------------
-- Procedures to send symbols.
---------------------------------------------------------------------------
procedure InboundSymbolIdle is
begin
inboundSymbolWrite <= '1';
inboundSymbolWriteMessage.symbolType <= "00";
inboundSymbolWriteMessage.symbolContent <= (others=>'U');
inboundSymbolWriteMessage.ignoreIdle <= false;
wait until inboundSymbolWriteAck = '1';
inboundSymbolWrite <= '0';
wait until inboundSymbolWriteAck = '0';
end procedure;
 
procedure InboundSymbolControl(constant symbolContent : in std_logic_vector(23 downto 0);
constant ignoreIdle : in boolean := false) is
begin
inboundSymbolWrite <= '1';
inboundSymbolWriteMessage.symbolType <= "01";
inboundSymbolWriteMessage.symbolContent <= x"00" & symbolContent;
inboundSymbolWriteMessage.ignoreIdle <= ignoreIdle;
wait until inboundSymbolWriteAck = '1';
inboundSymbolWrite <= '0';
wait until inboundSymbolWriteAck = '0';
end procedure;
 
procedure InboundSymbolData(constant symbolContent : in std_logic_vector(31 downto 0);
constant ignoreIdle : in boolean := false) is
begin
inboundSymbolWrite <= '1';
inboundSymbolWriteMessage.symbolType <= "10";
inboundSymbolWriteMessage.symbolContent <= symbolContent;
inboundSymbolWriteMessage.ignoreIdle <= ignoreIdle;
wait until inboundSymbolWriteAck = '1';
inboundSymbolWrite <= '0';
wait until inboundSymbolWriteAck = '0';
end procedure;
 
---------------------------------------------------------------------------
--
---------------------------------------------------------------------------
procedure OutboundFrame(constant frame : in RioFrame;
constant willAbort : boolean := false) is
begin
outboundFrameWrite <= '1';
outboundFrameWriteMessage.frame <= frame;
outboundFrameWriteMessage.willAbort <= willAbort;
wait until outboundFrameWriteAck = '1';
outboundFrameWrite <= '0';
wait until outboundFrameWriteAck = '0';
end procedure;
procedure InboundFrame(constant frame : in RioFrame;
constant willAbort : boolean := false) is
begin
inboundFrameWrite <= '1';
inboundFrameWriteMessage.frame <= frame;
inboundFrameWriteMessage.willAbort <= willAbort;
wait until inboundFrameWriteAck = '1';
inboundFrameWrite <= '0';
wait until inboundFrameWriteAck = '0';
end procedure;
 
---------------------------------------------------------------------------
-- Process variables.
---------------------------------------------------------------------------
variable seed1 : positive := 1;
variable seed2 : positive := 1;
variable payload : RioPayload;
variable frame : RioFrame;
variable frameOutbound : RioFrame;
variable frameInbound : RioFrame;
 
begin
---------------------------------------------------------------------------
-- Test case initialization.
---------------------------------------------------------------------------
 
portLinkTimeout <= (others=>'1');
inputPortEnable <= '1';
outputPortEnable <= '1';
portInitialized <= '0';
 
localAckIdWrite <= '0';
clrOutstandingAckId <= '0';
inboundAckIdWrite <= (others=>'0');
outstandingAckIdWrite <= (others=>'0');
outboundAckIdWrite <= (others=>'0');
 
enable <= '1';
 
linkInitializedExpected <= '0';
outboundSymbolWrite <= '0';
inboundSymbolWrite <= '0';
 
outboundFrameWrite <= '0';
inboundFrameWrite <= '0';
inboundFrameFull <= '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';
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
---------------------------------------------------------------------------
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 512 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
for i in 0 to 512 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
 
---------------------------------------------------------------------------
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 17 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
 
for i in 0 to 16 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
 
for i in 0 to 16 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
 
---------------------------------------------------------------------------
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 512 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
wait until outboundSymbolWriteEmpty = '1';
for i in 0 to 512 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
 
-- 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 17 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
 
for i in 0 to 16 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
 
for i in 0 to 16 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
---------------------------------------------------------------------------
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.
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_NOP, "000"));
for i in 0 to 15 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
 
-- The transmitter should send at least 15 additional statuses after
-- receiving an error free status.
for j in 0 to 14 loop
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
 
for i in 0 to 16 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
end loop;
 
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
 
OutboundSymbolIdle;
InboundSymbolIdle;
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
 
---------------------------------------------------------------------------
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 seven additional status symbols.");
PrintS("Result: The link should become fully initialized.");
---------------------------------------------------------------------------
PrintR("TG_RioSerial-TC2-Step5");
---------------------------------------------------------------------------
 
-- Make the link fully initialized by sending 7 additional statuses.
for i in 0 to 6 loop
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_NOP, "000"));
end loop;
 
-- Compensate for some ticks before the link becomes initialized.
for i in 0 to 3 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
 
linkInitializedExpected <= '1';
 
-- Receive a status-control-symbol.
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
---------------------------------------------------------------------------
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);
InboundFrame(frame);
-- Fill in the symbols that the packet will be fragmented into.
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
InboundSymbolData(frame.payload(i));
end loop;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_END_OF_PACKET, "000"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00000", "11111",
STYPE1_NOP, "000"), true);
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
TestCompare(inboundFrameWriteEmpty, '1', "Packet was received.");
---------------------------------------------------------------------------
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);
InboundFrame(frame);
-- Fill in the symbols that the packet will be fragmented into.
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
InboundSymbolData(frame.payload(i));
end loop;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_END_OF_PACKET, "000"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00001", "11111",
STYPE1_NOP, "000"), true);
 
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
TestCompare(inboundFrameWriteEmpty, '1', "Packet was received.");
 
---------------------------------------------------------------------------
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);
InboundFrame(frame);
-- Fill in the symbols that the packet will be fragmented into.
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
InboundSymbolData(frame.payload(i));
end loop;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_END_OF_PACKET, "000"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00010", "11111",
STYPE1_NOP, "000"), true);
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
TestCompare(inboundFrameWriteEmpty, '1', "Packet was received.");
 
---------------------------------------------------------------------------
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);
InboundFrame(frame);
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
InboundSymbolData(frame.payload(i));
end loop;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "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);
InboundFrame(frame);
for i in 0 to frame.length-1 loop
InboundSymbolData(frame.payload(i));
end loop;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_END_OF_PACKET, "000"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Add expected packet-accepted symbols.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00011", "11111",
STYPE1_NOP, "000"), true);
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00100", "11111",
STYPE1_NOP, "000"), true);
 
-- Wait for all symbols to be transfered and check that the packet was received.
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
TestCompare(inboundFrameWriteEmpty, '1', "Packet was received.");
 
---------------------------------------------------------------------------
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 a frame, send it and abort it with STOMP.
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);
InboundFrame(frame, true);
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
InboundSymbolData(frame.payload(i));
end loop;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_STOMP, "000"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
InboundSymbolControl(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);
InboundFrame(frame);
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
InboundSymbolData(frame.payload(i));
end loop;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_END_OF_PACKET, "000"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Receive acknowledge of the stomped packet.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_RETRY, "00101", "11111",
STYPE1_NOP, "000"), true);
-- Receive acknowledge for the transmitted frame.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00101", "11111",
STYPE1_NOP, "000"), true);
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
TestCompare(inboundFrameWriteEmpty, '1', "Packet was received.");
 
---------------------------------------------------------------------------
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 and abort it.
frame.length := 0;
InboundFrame(frame, true);
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_STOMP, "000"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Receive acknowledge for the transmitted frame.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_RETRY, "00110", "11111",
STYPE1_NOP, "000"), true);
 
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
-- Acknowledge the canceled packet.
InboundSymbolControl(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);
InboundFrame(frame);
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
InboundSymbolData(frame.payload(i));
end loop;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_END_OF_PACKET, "000"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Receive acknowledge for the transmitted frame.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00110", "11111",
STYPE1_NOP, "000"), true);
 
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
TestCompare(inboundFrameWriteEmpty, '1', "Packet was received.");
---------------------------------------------------------------------------
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 and abort it with a link-request/input-status to
-- abort the current packet.
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);
InboundFrame(frame, true);
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
InboundSymbolData(frame.payload(i));
end loop;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_LINK_REQUEST, "100"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Receive link-response indicating normal operation and expected ackId.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00111", "10000",
STYPE1_NOP, "000"), true);
 
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
TestCompare(inboundFrameWriteEmpty, '1', "Packet was received.");
 
-- 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);
InboundFrame(frame);
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
InboundSymbolData(frame.payload(i));
end loop;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_END_OF_PACKET, "000"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Receive acknowledge for the transmitted frame.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00111", "11111",
STYPE1_NOP, "000"), true);
 
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
TestCompare(inboundFrameWriteEmpty, '1', "Packet was received.");
 
---------------------------------------------------------------------------
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");
---------------------------------------------------------------------------
 
-- Start a frame then send link-request/input-status to abort it.
frame.length := 0;
InboundFrame(frame, true);
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_LINK_REQUEST, "100"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Receive link-response indicating normal operation and expected ackId.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01000", "10000",
STYPE1_NOP, "000"), true);
 
-- 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);
InboundFrame(frame);
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
InboundSymbolData(frame.payload(i));
end loop;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_END_OF_PACKET, "000"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Receive acknowledge for the transmitted frame.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01000", "11111",
STYPE1_NOP, "000"), true);
 
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
TestCompare(inboundFrameWriteEmpty, '1', "Packet was received.");
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 9:");
PrintS("Action: Send a packet when no buffers are 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");
---------------------------------------------------------------------------
 
-- Indicate the inbound frame queue is full.
inboundFrameFull <= '1';
-- Create a new frame and start sending it.
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);
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolData(frame.payload(0));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Receive notification about that the packet needs to be retried.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_RETRY, "01001", "11111",
STYPE1_NOP, "000"), true);
 
-- Check the status of the input port and verify the input-retry-stopped state.
-- This should also set the receiver into normal operation.
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_LINK_REQUEST, "100"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "00100",
STYPE1_NOP, "000"), true);
 
-- Check the status of the input port and verify the input-retry-stopped state.
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_LINK_REQUEST, "100"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "10000",
STYPE1_NOP, "000"), true);
 
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
TestCompare(inboundFrameWriteEmpty, '1', "Packet was received.");
 
-- Indicate the inbound frame queue is ready to accept new packets again.
inboundFrameFull <= '0';
---------------------------------------------------------------------------
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");
---------------------------------------------------------------------------
 
-- Indicate the inbound frame queue is full.
inboundFrameFull <= '1';
-- 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);
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolData(frame.payload(0));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Receive notification about that the packet needs to be retried.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_RETRY, "01001", "11111",
STYPE1_NOP, "000"), true);
 
-- Acknowledge the retried packet.
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_RESTART_FROM_RETRY, "000"));
 
-- Request the status of the input port.
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_LINK_REQUEST, "100"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Verify the input-retry-stopped state.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "10000",
STYPE1_NOP, "000"), true);
 
-- Always receive a status after a link response when leaving input-error-stopped.
-- OutboundSymbol(SYMBOL_CONTROL,
-- RioControlSymbolCreate(STYPE0_STATUS, "01001", "11111",
-- STYPE1_NOP, "000"));
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
TestCompare(inboundFrameWriteEmpty, '1', "Packet was received.");
-- Indicate the inbound frame queue is ready to accept new packets again.
inboundFrameFull <= '0';
 
---------------------------------------------------------------------------
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");
---------------------------------------------------------------------------
 
-- Indicate the inbound frame queue is full.
inboundFrameFull <= '1';
-- 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.
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolData(frame.payload(0));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Receive notification about that the packet needs to be retried.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_RETRY, "01001", "11111",
STYPE1_NOP, "000"), true);
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
 
-- Create a packet and send it. It should be silently 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);
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
OutboundSymbolIdle;
InboundSymbolData(frame.payload(i));
end loop;
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_END_OF_PACKET, "000"));
-- Acknowledge the retried packet.
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_RESTART_FROM_RETRY, "000"));
for i in 0 to 6 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
 
-- Indicate the inbound frame queue is ready to accept new packets again.
inboundFrameFull <= '0';
 
-- 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);
InboundFrame(frame);
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
InboundSymbolData(frame.payload(i));
end loop;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_END_OF_PACKET, "000"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Receive acknowledge for the transmitted frame.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01001", "11111",
STYPE1_NOP, "000"), true);
 
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
TestCompare(inboundFrameWriteEmpty, '1', "Packet was received.");
 
---------------------------------------------------------------------------
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.
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000") xor x"100000");
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Receive a packet-not-accepted indicating error in control-symbol crc.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_NOT_ACCEPTED, "00000", "00010",
STYPE1_NOP, "000"), true);
 
-- 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);
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
OutboundSymbolIdle;
InboundSymbolData(frame.payload(i));
end loop;
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_END_OF_PACKET, "000"));
-- Make the receiver go back to normal operation by sending a link-request.
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_LINK_REQUEST, "100"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01010", "00101",
STYPE1_NOP, "000"), true);
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
 
-- Always receive a status after a link response when leaving input-error-stopped.
-- OutboundSymbol(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);
InboundFrame(frame);
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
InboundSymbolData(frame.payload(i));
end loop;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_END_OF_PACKET, "000"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Receive acknowledge for the transmitted frame.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01010", "11111",
STYPE1_NOP, "000"), true);
 
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
TestCompare(inboundFrameWriteEmpty, '1', "Packet was received.");
---------------------------------------------------------------------------
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";
InboundFrame(frame, true);
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
InboundSymbolData(frame.payload(i));
end loop;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_END_OF_PACKET, "000"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
-- Receive a packet-not-accepted indicating error in control-symbol crc.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_NOT_ACCEPTED, "00000", "00100",
STYPE1_NOP, "000"), true);
 
-- Make the receiver go back to normal operation by sending a link-request.
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_LINK_REQUEST, "100"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01011", "00101",
STYPE1_NOP, "000"), true);
 
-- 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);
InboundFrame(frame);
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_START_OF_PACKET, "000"));
for i in 0 to frame.length-1 loop
InboundSymbolData(frame.payload(i));
end loop;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
STYPE1_END_OF_PACKET, "000"));
for i in 0 to 6 loop
InboundSymbolIdle;
end loop;
 
-- Receive acknowledge for the transmitted frame.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01011", "11111",
STYPE1_NOP, "000"), true);
 
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty.");
TestCompare(inboundFrameWriteEmpty, '1', "Packet was received.");
 
-- 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.
-- Make sure the transmitter fills in the correct ackId and dont use the
-- one in the input packet.
CreateRandomPayload(payload.data, seed1, seed2);
payload.length := 3;
frame := RioFrameCreate(ackId=>"UUUUU", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>"0000",
sourceId=>x"0000", destId=>x"0000",
payload=>payload);
OutboundFrame(frame);
frame.payload(0)(31 downto 27) := "00000";
 
-- Receive the frame.
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolIdle;
 
-- Send acknowledge that the frame was received.
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00000", "11111",
STYPE1_NOP, "000"));
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "Outbound symbol empty");
TestCompare(outboundFrameWriteEmpty, '1', "packet transmitted");
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 2:");
PrintS("Action: Send one more outbound packets than there are ackIds.");
PrintS("Result: The packets should be fragmented and received in symbols.");
PrintS(" The last packet should be delayed and sent once the first");
PrintS(" packet has been accepted.");
---------------------------------------------------------------------------
PrintR("TG_RioSerial-TC4-Step2");
---------------------------------------------------------------------------
-- REMARK: 32 packet should ideally be supported, not just 31...fix.
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
for i in 1 to 31 loop
-- Create a frame.
CreateRandomPayload(payload.data, seed1, seed2);
payload.length := 3+i;
frame := RioFrameCreate(ackId=>"UUUUU", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>"0000",
sourceId=>x"0000", destId=>x"0000",
payload=>payload);
OutboundFrame(frame);
frame.payload(0)(31 downto 27) := std_logic_vector(to_unsigned(i mod 32, 5));
 
-- Receive the frame.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolIdle;
-- Create a frame that cannot be sent since there are no available ackids left.
CreateRandomPayload(payload.data, seed1, seed2);
payload.length := 3+32;
frame := RioFrameCreate(ackId=>"UUUUU", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>"0000",
sourceId=>x"0000", destId=>x"0000",
payload=>payload);
OutboundFrame(frame);
frame.payload(0)(31 downto 27) := std_logic_vector(to_unsigned(0, 5));
-- Send acknowledge that the frames was received.
OutboundSymbolIdle;
InboundSymbolControl(
RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, std_logic_vector(to_unsigned(1, 5)), "11111",
STYPE1_NOP, "000"));
for i in 0 to 7 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
 
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolIdle;
 
for i in 2 to 32 loop
OutboundSymbolIdle;
InboundSymbolControl(
RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, std_logic_vector(to_unsigned(i mod 32, 5)), "11111",
STYPE1_NOP, "000"));
end loop;
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
TestCompare(outboundFrameWriteEmpty, '1', "packet pending");
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 3:");
PrintS("Action: Send an outbound packet with maximum length.");
PrintS("Result: The packet should be fragmented and received in symbols.");
---------------------------------------------------------------------------
PrintR("TG_RioSerial-TC4-Step3");
---------------------------------------------------------------------------
-- 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);
OutboundFrame(frame);
 
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
 
-- Receive the frame.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolIdle;
 
-- Send acknowledge that the frame was received.
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00001", "11111",
STYPE1_NOP, "000"));
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
 
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
TestCompare(outboundFrameWriteEmpty, '1', "packet pending");
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 4:");
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-Step4");
---------------------------------------------------------------------------
-- 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);
OutboundFrame(frame);
 
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
-- Send the frame and acknowledge it with packet-retry.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_RETRY, "00010", "11111",
STYPE1_NOP, "000"));
for i in 0 to 6 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
 
-- Receive the acknowledgement for the retransmission.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_RESTART_FROM_RETRY, "000"));
InboundSymbolIdle;
 
OutboundSymbolIdle;
InboundSymbolIdle;
-- Receive the retransmitted frame.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolIdle;
 
-- Send acknowledge that the frame was received.
InboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00010", "11111",
STYPE1_NOP, "000"));
OutboundSymbolIdle;
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
TestCompare(outboundFrameWriteEmpty, '1', "packet pending");
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 5:");
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-Step5");
---------------------------------------------------------------------------
-- 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);
OutboundFrame(frame);
 
-- Receive the frame.
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_NOT_ACCEPTED, "00000", "11111",
STYPE1_NOP, "000"));
 
-- Receive the link-request and answer back with a link-response.
for i in 0 to 6 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_LINK_REQUEST, "100"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00011", "11111",
STYPE1_NOP, "000"));
 
-- Receive the retransmitted frame.
-- Allow some ticks to pass to let the transmitter recover the error.
for i in 0 to 8 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolIdle;
 
-- Send acknowledge that the frame was received.
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00011", "11111",
STYPE1_NOP, "000"));
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
TestCompare(outboundFrameWriteEmpty, '1', "packet pending");
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 6:");
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-Step6");
---------------------------------------------------------------------------
-- 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);
OutboundFrame(frame);
 
-- Receive the frame.
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolIdle;
 
-- Wait a while to let the timer expire and receive the link-request.
for j in 1 to 7 loop
for i in 0 to 256 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
end loop;
for i in 0 to 242 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
-- Receive the link-request and answer back with a link-response.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_LINK_REQUEST, "100"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00100", "11111",
STYPE1_NOP, "000"));
-- Receive the retransmitted frame.
-- Allow some ticks to pass to let the transmitter recover the error.
for i in 0 to 8 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolIdle;
 
-- Send acknowledge that the frame was received.
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00100", "11111",
STYPE1_NOP, "000"));
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
TestCompare(outboundFrameWriteEmpty, '1', "packet pending");
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 7:");
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-Step7");
---------------------------------------------------------------------------
-- 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);
OutboundFrame(frame);
 
-- Receive the frame.
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolIdle;
 
-- Wait a while to let the timer expire and receive the link-request.
for j in 1 to 7 loop
for i in 0 to 256 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
end loop;
for i in 0 to 242 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
 
-- Receive the link-request and answer back with a link-response.
-- Send a link-response that indicates that the frame was received to make
-- the transmitter go back to normal mode.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_LINK_REQUEST, "100"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00110", "11111",
STYPE1_NOP, "000"));
for i in 0 to 8 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
TestCompare(outboundFrameWriteEmpty, '1', "packet pending");
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 8:");
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-Step8");
---------------------------------------------------------------------------
-- 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);
OutboundFrame(frame);
 
-- Receive the frame.
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolIdle;
 
-- Let 3 link-requests timeout.
for k in 1 to 3 loop
-- Wait a while to let the timer expire and receive the link-request.
for j in 1 to 7 loop
for i in 0 to 256 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
end loop;
for i in 0 to 242 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_LINK_REQUEST, "100"));
InboundSymbolIdle;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
end loop;
-- Wait for the third link-request to timeout.
for j in 1 to 7 loop
for i in 0 to 256 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
end loop;
for i in 0 to 240 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
linkInitializedExpected <= '0';
 
-- Reinitialize the transmitter.
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00110", "11111",
STYPE1_NOP, "000"));
for i in 0 to 14 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
for j in 0 to 13 loop
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
for i in 0 to 16 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
linkInitializedExpected <= '1';
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
 
-- Receive the frame.
for i in 0 to 2 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00110", "11111",
STYPE1_NOP, "000"));
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
 
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
TestCompare(outboundFrameWriteEmpty, '1', "packet pending");
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 9:");
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-Step9");
---------------------------------------------------------------------------
-- 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);
OutboundFrame(frame);
 
-- Receive the frame.
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolIdle;
 
-- Wait a while to let the timer expire and receive the link-request.
for j in 1 to 7 loop
for i in 0 to 256 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
end loop;
for i in 0 to 242 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
 
-- Receive the link-request and answer back with a link-response.
-- Send a link-response that indicates a totally unexpected ackId.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_LINK_REQUEST, "100"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "10000", "11111",
STYPE1_NOP, "000"));
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
linkInitializedExpected <= '0';
-- Reinitialize the transmitter.
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "00111", "11111",
STYPE1_NOP, "000"));
for i in 0 to 250 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
for j in 0 to 13 loop
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
for i in 0 to 16 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
linkInitializedExpected <= '1';
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
 
-- Receive the frame.
for i in 0 to 2 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00111", "11111",
STYPE1_NOP, "000"));
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
 
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
TestCompare(outboundFrameWriteEmpty, '1', "packet pending");
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 10:");
PrintS("Action: Send status with unexpected ackId in normal operation.");
PrintS("Result: The transmitter should disregard the error.");
---------------------------------------------------------------------------
PrintR("TG_RioSerial-TC4-Step10");
---------------------------------------------------------------------------
 
-- Send a status with unexpected ackId.
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "10000", "11111",
STYPE1_NOP, "000"));
 
-- Receive no change.
for i in 0 to 250 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
 
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
TestCompare(outboundFrameWriteEmpty, '1', "packet pending");
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 11:");
PrintS("Action: Send packet-retry with unexpected ackId in normal operation.");
PrintS("Result: The transmitter should enter output-error-stopped.");
---------------------------------------------------------------------------
PrintR("TG_RioSerial-TC4-Step11");
---------------------------------------------------------------------------
-- Send a packet-retry with unexpected ackId.
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_RETRY, "10000", "11111",
STYPE1_NOP, "000"));
for i in 0 to 6 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
 
-- Receive link-request.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_LINK_REQUEST, "100"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01000", "11111",
STYPE1_NOP, "000"));
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
-- Create a 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);
OutboundFrame(frame);
 
-- Wait for the transmitter to recover the previous error.
for i in 0 to 8 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
-- Receive the frame.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01000", "11111",
STYPE1_NOP, "000"));
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
TestCompare(outboundFrameWriteEmpty, '1', "packet pending");
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 12:");
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-Step12");
---------------------------------------------------------------------------
 
-- Send a packet-accepted with unexpected ackId.
OutboundSymbolIdle;
InboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "10000", "11111",
STYPE1_NOP, "000"));
for i in 0 to 6 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
 
-- Receive link-request.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_LINK_REQUEST, "100"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "11111",
STYPE1_NOP, "000"));
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
-- 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);
OutboundFrame(frame);
 
-- Wait for the transmitter to recover the previous error.
for i in 0 to 8 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
 
-- Receive the frame.
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01001", "11111",
STYPE1_NOP, "000"));
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
TestCompare(outboundFrameWriteEmpty, '1', "packet pending");
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 13:");
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-Step13");
---------------------------------------------------------------------------
-- 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);
OutboundFrame(frame);
 
-- Receive the frame.
-- Send unexpected ackId in packet-accepted.
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
for i in 0 to frame.length-1 loop
OutboundSymbolData(frame.payload(i));
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "10000", "11111",
STYPE1_NOP, "000"));
 
-- Receive link-request.
for i in 0 to 6 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_LINK_REQUEST, "100"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01011", "11111",
STYPE1_NOP, "000"));
 
-- Wait some additional ticks to let the transmitter recover the previous error.
for i in 0 to 6 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
TestCompare(outboundFrameWriteEmpty, '1', "packet pending");
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("TG_RioSerial-TC5");
PrintS("Description: Test mixed port transmission and reception.");
PrintS("Requirement: XXXXX");
PrintS("-----------------------------------------------------------------");
PrintS("Step 1:");
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-TC5-Step1");
---------------------------------------------------------------------------
 
-- Send a long outbound frame.
CreateRandomPayload(payload.data, seed1, seed2);
payload.length := 133;
frameOutbound := RioFrameCreate(ackId=>"01011", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>"0000",
sourceId=>x"0000", destId=>x"0000",
payload=>payload);
OutboundFrame(frameOutbound);
 
-- Receive a short inbound frame.
CreateRandomPayload(payload.data, seed1, seed2);
payload.length := 2;
frameInbound := RioFrameCreate(ackId=>"01100", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>"0000",
sourceId=>x"0000", destId=>x"0000",
payload=>payload);
InboundFrame(frameInbound);
 
-- Receive the outbound frame and start a short inbound frame at the same time.
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
 
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
STYPE1_START_OF_PACKET, "000"));
InboundSymbolIdle;
 
OutboundSymbolData(frameOutbound.payload(0));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "10000", "11111",
STYPE1_START_OF_PACKET, "000"));
 
OutboundSymbolData(frameOutbound.payload(1));
InboundSymbolData(frameInbound.payload(0));
OutboundSymbolData(frameOutbound.payload(2));
InboundSymbolData(frameInbound.payload(1));
OutboundSymbolData(frameOutbound.payload(3));
InboundSymbolData(frameInbound.payload(2));
OutboundSymbolData(frameOutbound.payload(4));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "10000", "11111",
STYPE1_END_OF_PACKET, "000"));
OutboundSymbolData(frameOutbound.payload(5));
InboundSymbolIdle;
OutboundSymbolData(frameOutbound.payload(6));
InboundSymbolIdle;
OutboundSymbolData(frameOutbound.payload(7));
InboundSymbolIdle;
 
OutboundSymbolData(frameOutbound.payload(8));
InboundSymbolIdle;
 
OutboundSymbolData(frameOutbound.payload(9));
InboundSymbolIdle;
 
OutboundSymbolData(frameOutbound.payload(10));
InboundSymbolIdle;
 
OutboundSymbolData(frameOutbound.payload(11));
InboundSymbolIdle;
 
OutboundSymbolData(frameOutbound.payload(12));
InboundSymbolIdle;
 
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01100", "11111",
STYPE1_NOP, "000"));
InboundSymbolIdle;
 
for i in 13 to frameOutbound.length-1 loop
OutboundSymbolData(frameOutbound.payload(i));
InboundSymbolIdle;
end loop;
 
OutboundSymbolControl(RioControlSymbolCreate(STYPE0_STATUS, "01101", "11111",
STYPE1_END_OF_PACKET, "000"));
InboundSymbolControl(RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01011", "11111",
STYPE1_NOP, "000"));
 
for i in 0 to 4 loop
OutboundSymbolIdle;
InboundSymbolIdle;
end loop;
TestWait(outboundSymbolWriteEmpty, '1', "symbols pending");
TestCompare(outboundFrameWriteEmpty, '1', "packet pending");
 
---------------------------------------------------------------------------
-- Test completed.
---------------------------------------------------------------------------
 
TestEnd;
end process;
 
-----------------------------------------------------------------------------
-- Instantiate interface simulator models.
-----------------------------------------------------------------------------
 
process
begin
wait until clk = '1';
TestCompare(linkInitialized, linkInitializedExpected, "link initialized");
end process;
SwitchPort: TestSwitchPort
port map(
clk=>clk, areset_n=>areset_n,
outboundWriteEmpty_o=>outboundFrameWriteEmpty,
outboundWrite_i=>outboundFrameWrite,
outboundWriteMessage_i=>outboundFrameWriteMessage,
outboundWriteAck_o=>outboundFrameWriteAck,
inboundWriteEmpty_o=>inboundFrameWriteEmpty,
inboundWrite_i=>inboundFrameWrite,
inboundWriteMessage_i=>inboundFrameWriteMessage,
inboundWriteAck_o=>inboundFrameWriteAck,
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,
writeFrame_i=>writeFrame, writeFrameAbort_i=>writeFrameAbort,
writeContent_i=>writeContent, writeContentData_i=>writeContentData);
 
PcsPort: TestSymbolPort
port map(
clk=>clk, areset_n=>areset_n,
portInitialized_i=>portInitialized,
outboundControlValid_i=>outboundControlValid,
outboundControlSymbol_i=>outboundControlSymbol,
outboundDataValid_i=>outboundDataValid,
outboundDataSymbol_i=>outboundDataSymbol,
inboundControlValid_o=>inboundControlValid,
inboundControlSymbol_o=>inboundControlSymbol,
inboundDataValid_o=>inboundDataValid,
inboundDataSymbol_o=>inboundDataSymbol,
outboundWriteEmpty_o=>outboundSymbolWriteEmpty,
outboundWrite_i=>outboundSymbolWrite,
outboundWriteMessage_i=>outboundSymbolWriteMessage,
outboundWriteAck_o=>outboundSymbolWriteAck,
inboundWriteEmpty_o=>inboundSymbolWriteEmpty,
inboundWrite_i=>inboundSymbolWrite,
inboundWriteMessage_i=>inboundSymbolWriteMessage,
inboundWriteAck_o=>inboundSymbolWriteAck);
-----------------------------------------------------------------------------
-- Instantiate the test object.
-----------------------------------------------------------------------------
TestObject: RioSerial
generic map(
TIMEOUT_WIDTH=>11, SYMBOL_COUNTER_WIDTH=>8,
TICKS_SEND_STATUS_STARTUP=>15, TICKS_SEND_STATUS_OPERATIONAL=>255)
port map(
clk=>clk, areset_n=>areset_n, enable=>enable,
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=>inboundFrameFull,
writeFrame_o=>writeFrame,
writeFrameAbort_o=>writeFrameAbort,
writeContent_o=>writeContent,
writeContentData_o=>writeContentData,
portInitialized_i=>portInitialized,
outboundControlValid_o=>outboundControlValid,
outboundControlSymbol_o=>outboundControlSymbol,
outboundDataValid_o=>outboundDataValid,
outboundDataSymbol_o=>outboundDataSymbol,
inboundControlValid_i=>inboundControlValid,
inboundControlSymbol_i=>inboundControlSymbol,
inboundDataValid_i=>inboundDataValid,
inboundDataSymbol_i=>inboundDataSymbol);
 
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;
use work.TestRioSerialPackage.all;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
entity TestSwitchPort is
port(
clk : in std_logic;
areset_n : in std_logic;
 
outboundWriteEmpty_o : out std_logic;
outboundWrite_i : in std_logic;
outboundWriteMessage_i : in MessageFrame;
outboundWriteAck_o : out std_logic;
inboundWriteEmpty_o : out std_logic;
inboundWrite_i : in std_logic;
inboundWriteMessage_i : in MessageFrame;
inboundWriteAck_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);
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
constant QUEUE_SIZE : natural := 63;
type QueueArray is array (natural range <>) of MessageFrame;
function QueueIndexInc(constant i : natural) return natural is
variable returnValue : natural;
begin
if(i = QUEUE_SIZE) then
returnValue := 0;
else
returnValue := i + 1;
end if;
return returnValue;
end function;
begin
-----------------------------------------------------------------------------
--
-----------------------------------------------------------------------------
Outbound: process
variable frameQueue : QueueArray(0 to QUEUE_SIZE);
variable front, back, window : natural range 0 to QUEUE_SIZE;
variable frameIndex : natural;
begin
wait until areset_n = '1';
readFrameEmpty_o <= '1';
readFrameAborted_o <= '0';
readWindowEmpty_o <= '1';
readContentEmpty_o <= '1';
readContentEnd_o <= '0';
readContentData_o <= (others=>'0');
 
front := 0;
back := 0;
window := 0;
frameIndex := 0;
outboundWriteEmpty_o <= '1';
outboundWriteAck_o <= '0';
 
loop
wait until clk = '1' or outboundWrite_i = '1';
 
if (clk'event) then
if (readFrame_i = '1') then
if (back /= front) then
back := QueueIndexInc(back);
else
TestError("OUTBOUND:BACK:reading when no frame is present");
end if;
end if;
 
if (readFrameRestart_i = '1') then
frameIndex := 0;
end if;
if (readWindowReset_i = '1') then
window := back;
frameIndex := 0;
end if;
 
if (readWindowNext_i = '1') then
if (window /= front) then
window := QueueIndexInc(window);
frameIndex := 0;
else
TestError("OUTBOUND:WINDOW:reading when no frame is present");
end if;
end if;
if (readContent_i = '1') then
if (back /= front) then
if (frameIndex < frameQueue(window).frame.length) then
readContentData_o <= frameQueue(window).frame.payload(frameIndex);
frameIndex := frameIndex + 1;
if (frameIndex = frameQueue(window).frame.length) then
readContentEnd_o <= '1';
else
readContentEnd_o <= '0';
end if;
else
TestError("OUTBOUND:CONTENT:reading when frame has ended");
end if;
else
TestError("OUTBOUND:CONTENT:reading when no frame is present");
end if;
end if;
 
if (front = back) then
readFrameEmpty_o <= '1';
else
readFrameEmpty_o <= '0';
end if;
if (front = window) then
readWindowEmpty_o <= '1';
readContentEmpty_o <= '1';
else
readWindowEmpty_o <= '0';
if (frameIndex /= frameQueue(window).frame.length) then
readContentEmpty_o <= '0';
else
readContentEmpty_o <= '1';
end if;
end if;
if (front = back) then
outboundWriteEmpty_o <= '1';
else
outboundWriteEmpty_o <= '0';
end if;
elsif (outboundWrite_i'event) then
frameQueue(front) := outboundWriteMessage_i;
front := QueueIndexInc(front);
 
outboundWriteEmpty_o <= '0';
outboundWriteAck_o <= '1';
wait until outboundWrite_i = '0';
outboundWriteAck_o <= '0';
end if;
end loop;
end process;
 
-----------------------------------------------------------------------------
--
-----------------------------------------------------------------------------
Inbound: process
variable frameQueue : QueueArray(0 to QUEUE_SIZE);
variable front, back : natural range 0 to QUEUE_SIZE;
variable frameIndex : natural range 0 to 69;
begin
wait until areset_n = '1';
 
inboundWriteEmpty_o <= '1';
inboundWriteAck_o <= '0';
 
front := 0;
back := 0;
frameIndex := 0;
 
loop
wait until clk = '1' or inboundWrite_i = '1';
 
if (clk'event) then
 
if (writeFrame_i = '1') then
if (frameIndex = 0) then
TestError("INBOUND:Empty frame written.");
end if;
if (frameIndex /= frameQueue(back).frame.length) then
TestError("INBOUND:Frame with unmatching length was written.");
end if;
if (back /= front) then
back := QueueIndexInc(back);
else
TestError("INBOUND:Unexpected frame written.");
end if;
frameIndex := 0;
end if;
 
if (writeFrameAbort_i = '1') then
if (back /= front) then
if (frameQueue(back).willAbort) then
if (frameIndex /= frameQueue(back).frame.length) then
TestError("INBOUND:Frame with unmatching length was aborted.");
end if;
back := QueueIndexInc(back);
else
TestError("INBOUND:Not expecting this frame to abort.");
end if;
end if;
frameIndex := 0;
end if;
 
if (writeContent_i = '1') then
if (frameIndex < frameQueue(back).frame.length) then
if (frameQueue(back).frame.payload(frameIndex) /= writeContentData_i) then
TestError("INBOUND:Unexpected frame content written.");
end if;
frameIndex := frameIndex + 1;
else
TestError("INBOUND:Receiving more frame content than expected.");
end if;
end if;
if (front = back) then
inboundWriteEmpty_o <= '1';
else
inboundWriteEmpty_o <= '0';
end if;
elsif (inboundWrite_i'event) then
frameQueue(front) := inboundWriteMessage_i;
front := QueueIndexInc(front);
 
inboundWriteEmpty_o <= '0';
inboundWriteAck_o <= '1';
wait until inboundWrite_i = '0';
inboundWriteAck_o <= '0';
end if;
end loop;
end process;
 
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;
use work.TestRioSerialPackage.all;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
entity TestSymbolPort is
port(
clk : in std_logic;
areset_n : in std_logic;
 
portInitialized_i : in std_logic;
outboundControlValid_i : in std_logic;
outboundControlSymbol_i : in std_logic_vector(23 downto 0);
outboundDataValid_i : in std_logic;
outboundDataSymbol_i : in std_logic_vector(31 downto 0);
inboundControlValid_o : out std_logic;
inboundControlSymbol_o : out std_logic_vector(23 downto 0);
inboundDataValid_o : out std_logic;
inboundDataSymbol_o : out std_logic_vector(31 downto 0);
 
outboundWriteEmpty_o : out std_logic;
outboundWrite_i : in std_logic;
outboundWriteMessage_i : in MessageSymbol;
outboundWriteAck_o : out std_logic;
 
inboundWriteEmpty_o : out std_logic;
inboundWrite_i : in std_logic;
inboundWriteMessage_i : in MessageSymbol;
inboundWriteAck_o : out std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture TestSymbolPortImpl of TestSymbolPort is
constant QUEUE_SIZE : natural := 2047;
type QueueArray is array (natural range <>) of MessageSymbol;
 
function QueueIndexInc(constant i : natural) return natural is
variable returnValue : natural;
begin
if(i = QUEUE_SIZE) then
returnValue := 0;
else
returnValue := i + 1;
end if;
return returnValue;
end function;
 
begin
-----------------------------------------------------------------------------
--
-----------------------------------------------------------------------------
Outbound: process
variable front, back : natural range 0 to QUEUE_SIZE;
variable symbolQueue : QueueArray(0 to QUEUE_SIZE);
begin
wait until areset_n = '1';
 
front := 0;
back := 0;
outboundWriteEmpty_o <= '1';
outboundWriteAck_o <= '0';
 
loop
wait until clk = '1' or outboundWrite_i = '1';
 
if (clk'event) then
if (back /= front) then
if (symbolQueue(back).symbolType = "01") then
if (not ((symbolQueue(back).ignoreIdle) and
(outboundControlValid_i = '0') and
(outboundDataValid_i = '0'))) then
TestCompare(outboundControlValid_i, '1', "OUTBOUND:control symbol");
TestCompare(outboundControlSymbol_i(23 downto 21), symbolQueue(back).symbolContent(23 downto 21),
"OUTBOUND:stype0=" & to_string(symbolQueue(back).symbolContent(23 downto 21)));
TestCompare(outboundControlSymbol_i(20 downto 16), symbolQueue(back).symbolContent(20 downto 16),
"OUTBOUND:parameter0=" & to_string(symbolQueue(back).symbolContent(20 downto 16)));
TestCompare(outboundControlSymbol_i(15 downto 11), symbolQueue(back).symbolContent(15 downto 11),
"OUTBOUND:parameter1=" & to_string(symbolQueue(back).symbolContent(15 downto 11)));
TestCompare(outboundControlSymbol_i(10 downto 8), symbolQueue(back).symbolContent(10 downto 8),
"OUTBOUND:stype1=" & to_string(symbolQueue(back).symbolContent(10 downto 8)));
TestCompare(outboundControlSymbol_i(7 downto 5), symbolQueue(back).symbolContent(7 downto 5),
"OUTBOUND:cmd=" & to_string(symbolQueue(back).symbolContent(7 downto 5)));
TestCompare(outboundControlSymbol_i(4 downto 0), symbolQueue(back).symbolContent(4 downto 0),
"OUTBOUND:crc5=" & to_string(symbolQueue(back).symbolContent(4 downto 0)));
TestCompare(outboundDataValid_i, '0', "OUTBOUND:no data symbol");
back := QueueIndexInc(back);
end if;
elsif (symbolQueue(back).symbolType = "10") then
if (not ((symbolQueue(back).ignoreIdle) and
(outboundControlValid_i = '0') and
(outboundDataValid_i = '0'))) then
TestCompare(outboundDataValid_i, '1', "OUTBOUND:valid data symbol");
TestCompare(outboundDataSymbol_i, symbolQueue(back).symbolContent(31 downto 0),
"OUTBOUND:data symbol content");
TestCompare(outboundControlValid_i, '0', "OUTBOUND:valid control symbol");
back := QueueIndexInc(back);
end if;
elsif (symbolQueue(back).symbolType = "00") then
TestCompare(outboundControlValid_i, '0', "OUTBOUND:valid control symbol");
TestCompare(outboundDataValid_i, '0', "OUTBOUND:valid data symbol");
back := QueueIndexInc(back);
else
TestCompare(outboundControlValid_i, '1', "OUTBOUND:valid control symbol");
TestCompare(outboundDataValid_i, '1', "OUTBOUND:valid data symbol");
back := QueueIndexInc(back);
end if;
 
if (front = back) then
outboundWriteEmpty_o <= '1';
else
outboundWriteEmpty_o <= '0';
end if;
else
TestError("OUTBOUND:empty symbol queue");
end if;
elsif (outboundWrite_i'event) then
symbolQueue(front) := outboundWriteMessage_i;
front := QueueIndexInc(front);
 
outboundWriteEmpty_o <= '0';
outboundWriteAck_o <= '1';
wait until outboundWrite_i = '0';
outboundWriteAck_o <= '0';
end if;
end loop;
end process;
 
-----------------------------------------------------------------------------
--
-----------------------------------------------------------------------------
Inbound: process
variable front, back : natural range 0 to QUEUE_SIZE;
variable symbolQueue : QueueArray(0 to QUEUE_SIZE);
begin
wait until areset_n = '1';
 
front := 0;
back := 0;
inboundWriteEmpty_o <= '1';
inboundWriteAck_o <= '0';
 
inboundControlValid_o <= '0';
inboundControlSymbol_o <= (others=>'U');
inboundDataValid_o <= '0';
inboundDataSymbol_o <= (others=>'U');
loop
wait until clk = '1' or inboundWrite_i = '1';
 
if (clk'event) then
if (back /= front) then
if (symbolQueue(back).symbolType = "00") then
inboundControlValid_o <= '0';
inboundDataValid_o <= '0';
elsif (symbolQueue(back).symbolType = "01") then
inboundControlValid_o <= '1';
inboundControlSymbol_o <= symbolQueue(back).symbolContent(23 downto 0);
inboundDataValid_o <= '0';
elsif (symbolQueue(back).symbolType = "10") then
inboundControlValid_o <= '0';
inboundDataValid_o <= '1';
inboundDataSymbol_o <= symbolQueue(back).symbolContent(31 downto 0);
else
inboundControlValid_o <= '1';
inboundDataValid_o <= '1';
end if;
 
back := QueueIndexInc(back);
 
if (front = back) then
inboundWriteEmpty_o <= '1';
else
inboundWriteEmpty_o <= '0';
end if;
else
TestError("INBOUND:empty symbol queue");
end if;
elsif (inboundWrite_i'event) then
symbolQueue(front) := inboundWriteMessage_i;
front := QueueIndexInc(front);
 
inboundWriteEmpty_o <= '0';
inboundWriteAck_o <= '1';
wait until inboundWrite_i = '0';
inboundWriteAck_o <= '0';
end if;
end loop;
end process;
 
end architecture;
branches/2.0.0-development/bench/vhdl/TestRioSerial.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: branches/2.0.0-development/bench/vhdl/TestRioLogicalCommon.vhd =================================================================== --- branches/2.0.0-development/bench/vhdl/TestRioLogicalCommon.vhd (nonexistent) +++ branches/2.0.0-development/bench/vhdl/TestRioLogicalCommon.vhd (revision 41) @@ -0,0 +1,1520 @@ +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- Description +-- Contains automatic test code to verify a RioLogicalCommon 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 +-- +------------------------------------------------------------------------------- + + +------------------------------------------------------------------------------- +-- TestRioLogicalCommon. +------------------------------------------------------------------------------- + +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 TestRioLogicalCommon. +------------------------------------------------------------------------------- +entity TestRioLogicalCommon is +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for TestRioLogicalCommon. +------------------------------------------------------------------------------- +architecture TestRioLogicalCommonImpl of TestRioLogicalCommon is + + component RioLogicalCommon is + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + 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); + + configStb_o : out std_logic; + configWe_o : out std_logic; + configAdr_o : out std_logic_vector(21 downto 0); + configDat_o : out std_logic_vector(31 downto 0); + configDat_i : in std_logic_vector(31 downto 0); + configAck_i : in std_logic); + 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; + + signal clk : std_logic; + signal areset_n : std_logic; + signal enable : std_logic; + + signal frameValid : std_logic; + signal frameWrite : RioFrame; + signal frameComplete : std_logic; + + signal frameExpected : std_logic; + signal frameRead : RioFrame; + signal frameReceived : std_logic; + + 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 readFrameEmpty : std_logic; + signal readFrame : std_logic; + signal readFrameRestart : std_logic; + signal readFrameAborted : std_logic; + signal readContentEmpty : std_logic; + signal readContent : std_logic; + signal readContentEnd : std_logic; + signal readContentData : std_logic_vector(31 downto 0); + + signal configStb, configStbExpected : std_logic; + signal configWe : std_logic; + signal configAddr : std_logic_vector(21 downto 0); + signal configDataWrite : std_logic_vector(31 downto 0); + signal configDataRead : std_logic_vector(31 downto 0); + signal configAck : std_logic; + +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 frame : RioFrame) is + begin + frameValid <= '1'; + frameWrite <= frame; + wait until frameComplete = '1'; + frameValid <= '0'; + end procedure; + + --------------------------------------------------------------------------- + -- + --------------------------------------------------------------------------- + procedure ReceiveFrame(constant frame : RioFrame) is + begin + frameExpected <= '1'; + frameRead <= frame; + wait until frameReceived = '1'; + frameExpected <= '0'; + end procedure; + + variable seed1 : positive := 1; + variable seed2: positive := 1; + + variable maintData : DoubleWordArray(0 to 7); + variable frame : RioFrame; + + begin + areset_n <= '0'; + enable <= '1'; + + frameValid <= '0'; + frameExpected <= '0'; + + configStbExpected <= '0'; + configAck <= '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_RioLogicalCommon"); + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioLogicalCommon-TC1"); + PrintS("Description: Test maintenance read requests."); + PrintS("Requirement: XXXXX"); + PrintS("-----------------------------------------------------------------"); + PrintS("Step 1:"); + PrintS("Action: Send maintenance read request for one word on even offset."); + PrintS("Result: Check the accesses on the external configuration port."); + PrintS("-----------------------------------------------------------------"); + --------------------------------------------------------------------------- + PrintR("TG_RioLogicalCommon-TC1-Step1"); + --------------------------------------------------------------------------- + + SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"dead", destId=>x"beef", + payload=>RioMaintenance(transaction=>"0000", + size=>"1000", + tid=>x"aa", + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'0', + dataLength=>0, + data=>maintData))); + + wait until configStb = '1'; + configStbExpected <= '1'; + wait until clk = '1'; + assert configWe = '0'; + assert configAddr = "0000000000000000000000"; + wait until clk = '1'; + configDataRead <= x"deadbeef"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + configStbExpected <= '0'; + maintData(0) := x"deadbeef00000000"; + + ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"beef", destId=>x"dead", + payload=>RioMaintenance(transaction=>"0010", + size=>"0000", + tid=>x"aa", + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'0', + dataLength=>1, + data=>maintData))); + + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 2:"); + PrintS("Action: Send maintenance read request for one word on odd offset."); + PrintS("Result: Check the accesses on the external configuration port."); + PrintS("-----------------------------------------------------------------"); + --------------------------------------------------------------------------- + PrintR("TG_RioLogicalCommon-TC1-Step2"); + --------------------------------------------------------------------------- + + SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"dead", destId=>x"beef", + payload=>RioMaintenance(transaction=>"0000", + size=>"1000", + tid=>x"aa", + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'1', + dataLength=>0, + data=>maintData))); + + wait until configStb = '1'; + configStbExpected <= '1'; + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000001" report "Unexpected config address." severity error; + configDataRead <= x"c0debabe"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + configStbExpected <= '0'; + maintData(0) := x"00000000c0debabe"; + + ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"beef", destId=>x"dead", + payload=>RioMaintenance(transaction=>"0010", + size=>"0000", + tid=>x"aa", + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'0', + dataLength=>1, + data=>maintData))); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 3:"); + PrintS("Action: Send maintenance read request for two words."); + PrintS("Result: Check the accesses on the external configuration port."); + PrintS("-----------------------------------------------------------------"); + --------------------------------------------------------------------------- + PrintR("TG_RioLogicalCommon-TC1-Step3"); + --------------------------------------------------------------------------- + + SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"dead", destId=>x"beef", + payload=>RioMaintenance(transaction=>"0000", + size=>"1011", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"000000000000000000001", + wdptr=>'0', + dataLength=>0, + data=>maintData))); + + wait until configStb = '1'; + configStbExpected <= '1'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000010" report "Unexpected config address." severity error; + configDataRead <= x"11111111"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000011" report "Unexpected config address." severity error; + configDataRead <= x"22222222"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + configStbExpected <= '0'; + maintData(0) := x"1111111122222222"; + + ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"beef", destId=>x"dead", + payload=>RioMaintenance(transaction=>"0010", + size=>"0000", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'0', + dataLength=>1, + data=>maintData))); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 4:"); + PrintS("Action: Send maintenance read request for four words."); + PrintS("Result: Check the accesses on the external configuration port."); + PrintS("-----------------------------------------------------------------"); + --------------------------------------------------------------------------- + PrintR("TG_RioLogicalCommon-TC1-Step4"); + --------------------------------------------------------------------------- + + SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"dead", destId=>x"beef", + payload=>RioMaintenance(transaction=>"0000", + size=>"1011", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"000000000000000000001", + wdptr=>'1', + dataLength=>0, + data=>maintData))); + + wait until configStb = '1'; + configStbExpected <= '1'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000010" report "Unexpected config address." severity error; + configDataRead <= x"11111111"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000011" report "Unexpected config address." severity error; + configDataRead <= x"22222222"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000100" report "Unexpected config address." severity error; + configDataRead <= x"33333333"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000101" report "Unexpected config address." severity error; + configDataRead <= x"44444444"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + configStbExpected <= '0'; + maintData(0) := x"1111111122222222"; + maintData(1) := x"3333333344444444"; + + ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"beef", destId=>x"dead", + payload=>RioMaintenance(transaction=>"0010", + size=>"0000", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'0', + dataLength=>2, + data=>maintData))); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 5:"); + PrintS("Action: Send maintenance read request for eight words."); + PrintS("Result: Check the accesses on the external configuration port."); + PrintS("-----------------------------------------------------------------"); + --------------------------------------------------------------------------- + PrintR("TG_RioLogicalCommon-TC1-Step5"); + --------------------------------------------------------------------------- + + SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"dead", destId=>x"beef", + payload=>RioMaintenance(transaction=>"0000", + size=>"1100", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"000000000000000000001", + wdptr=>'0', + dataLength=>0, + data=>maintData))); + + wait until configStb = '1'; + configStbExpected <= '1'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000010" report "Unexpected config address." severity error; + configDataRead <= x"11111111"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000011" report "Unexpected config address." severity error; + configDataRead <= x"22222222"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000100" report "Unexpected config address." severity error; + configDataRead <= x"33333333"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000101" report "Unexpected config address." severity error; + configDataRead <= x"44444444"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000110" report "Unexpected config address." severity error; + configDataRead <= x"55555555"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000111" report "Unexpected config address." severity error; + configDataRead <= x"66666666"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001000" report "Unexpected config address." severity error; + configDataRead <= x"77777777"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001001" report "Unexpected config address." severity error; + configDataRead <= x"88888888"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + configStbExpected <= '0'; + maintData(0) := x"1111111122222222"; + maintData(1) := x"3333333344444444"; + maintData(2) := x"5555555566666666"; + maintData(3) := x"7777777788888888"; + + ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"beef", destId=>x"dead", + payload=>RioMaintenance(transaction=>"0010", + size=>"0000", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'0', + dataLength=>4, + data=>maintData))); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 6:"); + PrintS("Action: Send maintenance read request for sixteen words."); + PrintS("Result: Check the accesses on the external configuration port."); + PrintS("-----------------------------------------------------------------"); + --------------------------------------------------------------------------- + PrintR("TG_RioLogicalCommon-TC1-Step6"); + --------------------------------------------------------------------------- + + SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"dead", destId=>x"beef", + payload=>RioMaintenance(transaction=>"0000", + size=>"1100", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"000000000000000000001", + wdptr=>'1', + dataLength=>0, + data=>maintData))); + + wait until configStb = '1'; + configStbExpected <= '1'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000010" report "Unexpected config address." severity error; + configDataRead <= x"11111111"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000011" report "Unexpected config address." severity error; + configDataRead <= x"22222222"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000100" report "Unexpected config address." severity error; + configDataRead <= x"33333333"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000101" report "Unexpected config address." severity error; + configDataRead <= x"44444444"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000110" report "Unexpected config address." severity error; + configDataRead <= x"55555555"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000111" report "Unexpected config address." severity error; + configDataRead <= x"66666666"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001000" report "Unexpected config address." severity error; + configDataRead <= x"77777777"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001001" report "Unexpected config address." severity error; + configDataRead <= x"88888888"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001010" report "Unexpected config address." severity error; + configDataRead <= x"99999999"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001011" report "Unexpected config address." severity error; + configDataRead <= x"aaaaaaaa"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001100" report "Unexpected config address." severity error; + configDataRead <= x"bbbbbbbb"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001101" report "Unexpected config address." severity error; + configDataRead <= x"cccccccc"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001110" report "Unexpected config address." severity error; + configDataRead <= x"dddddddd"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001111" report "Unexpected config address." severity error; + configDataRead <= x"eeeeeeee"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000010000" report "Unexpected config address." severity error; + configDataRead <= x"ffffffff"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '0' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000010001" report "Unexpected config address." severity error; + configDataRead <= x"10101010"; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + configStbExpected <= '0'; + maintData(0) := x"1111111122222222"; + maintData(1) := x"3333333344444444"; + maintData(2) := x"5555555566666666"; + maintData(3) := x"7777777788888888"; + maintData(4) := x"99999999aaaaaaaa"; + maintData(5) := x"bbbbbbbbcccccccc"; + maintData(6) := x"ddddddddeeeeeeee"; + maintData(7) := x"ffffffff10101010"; + + ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"beef", destId=>x"dead", + payload=>RioMaintenance(transaction=>"0010", + size=>"0000", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'0', + dataLength=>8, + data=>maintData))); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("TG_RioLogicalCommon-TC2"); + PrintS("Description: Test maintenance write requests."); + PrintS("Requirement: XXXXX"); + PrintS("-----------------------------------------------------------------"); + PrintS("Step 1:"); + PrintS("Action: Send maintenance write request for one word on even offset."); + PrintS("Result: Check the accesses on the external configuration port."); + PrintS("-----------------------------------------------------------------"); + --------------------------------------------------------------------------- + PrintR("TG_RioLogicalCommon-TC2-Step1"); + --------------------------------------------------------------------------- + + maintData(0) := x"deadbeef00000000"; + SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"dead", destId=>x"beef", + payload=>RioMaintenance(transaction=>"0001", + size=>"1000", + tid=>x"aa", + hopCount=>x"ff", + configOffset=>"100000000000000000000", + wdptr=>'0', + dataLength=>1, + data=>maintData))); + + wait until configStb = '1'; + configStbExpected <= '1'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected configWe." severity error; + assert configAddr = "1000000000000000000000" report "Unexpected configAddr." severity error; + assert configDataWrite = x"deadbeef" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + configStbExpected <= '0'; + + ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"beef", destId=>x"dead", + payload=>RioMaintenance(transaction=>"0011", + size=>"0000", + tid=>x"aa", + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'0', + dataLength=>0, + data=>maintData))); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 2:"); + PrintS("Action: Send maintenance write request for one word on odd offset."); + PrintS("Result: Check the accesses on the external configuration port."); + PrintS("-----------------------------------------------------------------"); + --------------------------------------------------------------------------- + PrintR("TG_RioLogicalCommon-TC2-Step2"); + --------------------------------------------------------------------------- + + maintData(0) := x"00000000c0debabe"; + SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"dead", destId=>x"beef", + payload=>RioMaintenance(transaction=>"0001", + size=>"1000", + tid=>x"aa", + hopCount=>x"ff", + configOffset=>"100000000000000000000", + wdptr=>'1', + dataLength=>1, + data=>maintData))); + + wait until configStb = '1'; + configStbExpected <= '1'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "1000000000000000000001" report "Unexpected config address." severity error; + assert configDataWrite = x"c0debabe" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + configStbExpected <= '0'; + + ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"beef", destId=>x"dead", + payload=>RioMaintenance(transaction=>"0011", + size=>"0000", + tid=>x"aa", + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'0', + dataLength=>0, + data=>maintData))); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 3:"); + PrintS("Action: Send maintenance write request for two words."); + PrintS("Result: Check the accesses on the external configuration port."); + PrintS("-----------------------------------------------------------------"); + --------------------------------------------------------------------------- + PrintR("TG_RioLogicalCommon-TC2-Step3"); + --------------------------------------------------------------------------- + + maintData(0) := x"1111111122222222"; + SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"dead", destId=>x"beef", + payload=>RioMaintenance(transaction=>"0001", + size=>"1011", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"100000000000000000001", + wdptr=>'0', + dataLength=>1, + data=>maintData))); + + wait until configStb = '1'; + configStbExpected <= '1'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "1000000000000000000010" report "Unexpected config address." severity error; + assert configDataWrite = x"11111111" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "1000000000000000000011" report "Unexpected config address." severity error; + assert configDataWrite = x"22222222" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + configStbExpected <= '0'; + + ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"beef", destId=>x"dead", + payload=>RioMaintenance(transaction=>"0011", + size=>"0000", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'0', + dataLength=>0, + data=>maintData))); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 4:"); + PrintS("Action: Send maintenance write request for four words."); + PrintS("Result: Check the accesses on the external configuration port."); + PrintS("-----------------------------------------------------------------"); + --------------------------------------------------------------------------- + PrintR("TG_RioLogicalCommon-TC2-Step4"); + --------------------------------------------------------------------------- + + maintData(0) := x"1111111122222222"; + maintData(1) := x"3333333344444444"; + SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"dead", destId=>x"beef", + payload=>RioMaintenance(transaction=>"0001", + size=>"1011", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"000000000000000000001", + wdptr=>'1', + dataLength=>2, + data=>maintData))); + + wait until configStb = '1'; + configStbExpected <= '1'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000010" report "Unexpected config address." severity error; + assert configDataWrite = x"11111111" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000011" report "Unexpected config address." severity error; + assert configDataWrite = x"22222222" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000100" report "Unexpected config address." severity error; + assert configDataWrite = x"33333333" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000101" report "Unexpected config address." severity error; + assert configDataWrite = x"44444444" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + configStbExpected <= '0'; + + ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"beef", destId=>x"dead", + payload=>RioMaintenance(transaction=>"0011", + size=>"0000", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'0', + dataLength=>0, + data=>maintData))); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 5:"); + PrintS("Action: Send maintenance write request for eight words."); + PrintS("Result: Check the accesses on the external configuration port."); + PrintS("-----------------------------------------------------------------"); + --------------------------------------------------------------------------- + PrintR("TG_RioLogicalCommon-TC2-Step5"); + --------------------------------------------------------------------------- + + maintData(0) := x"1111111122222222"; + maintData(1) := x"3333333344444444"; + maintData(2) := x"5555555566666666"; + maintData(3) := x"7777777788888888"; + SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"dead", destId=>x"beef", + payload=>RioMaintenance(transaction=>"0001", + size=>"1100", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"000000000000000000001", + wdptr=>'0', + dataLength=>4, + data=>maintData))); + + wait until configStb = '1'; + configStbExpected <= '1'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000010" report "Unexpected config address." severity error; + assert configDataWrite = x"11111111" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000011" report "Unexpected config address." severity error; + assert configDataWrite = x"22222222" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000100" report "Unexpected config address." severity error; + assert configDataWrite = x"33333333" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000101" report "Unexpected config address." severity error; + assert configDataWrite = x"44444444" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000110" report "Unexpected config address." severity error; + assert configDataWrite = x"55555555" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000111" report "Unexpected config address." severity error; + assert configDataWrite = x"66666666" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001000" report "Unexpected config address." severity error; + assert configDataWrite = x"77777777" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001001" report "Unexpected config address." severity error; + assert configDataWrite = x"88888888" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + configStbExpected <= '0'; + + ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"beef", destId=>x"dead", + payload=>RioMaintenance(transaction=>"0011", + size=>"0000", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'0', + dataLength=>0, + data=>maintData))); + + --------------------------------------------------------------------------- + PrintS("-----------------------------------------------------------------"); + PrintS("Step 6:"); + PrintS("Action: Send maintenance write request for sixteen words."); + PrintS("Result: Check the accesses on the external configuration port."); + PrintS("-----------------------------------------------------------------"); + --------------------------------------------------------------------------- + PrintR("TG_RioLogicalCommon-TC2-Step6"); + --------------------------------------------------------------------------- + + maintData(0) := x"1111111122222222"; + maintData(1) := x"3333333344444444"; + maintData(2) := x"5555555566666666"; + maintData(3) := x"7777777788888888"; + maintData(4) := x"99999999aaaaaaaa"; + maintData(5) := x"bbbbbbbbcccccccc"; + maintData(6) := x"ddddddddeeeeeeee"; + maintData(7) := x"ffffffff10101010"; + SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"dead", destId=>x"beef", + payload=>RioMaintenance(transaction=>"0001", + size=>"1100", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"000000000000000000001", + wdptr=>'1', + dataLength=>8, + data=>maintData))); + + wait until configStb = '1'; + configStbExpected <= '1'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000010" report "Unexpected config address." severity error; + assert configDataWrite = x"11111111" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000011" report "Unexpected config address." severity error; + assert configDataWrite = x"22222222" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000100" report "Unexpected config address." severity error; + assert configDataWrite = x"33333333" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000101" report "Unexpected config address." severity error; + assert configDataWrite = x"44444444" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000110" report "Unexpected config address." severity error; + assert configDataWrite = x"55555555" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000000111" report "Unexpected config address." severity error; + assert configDataWrite = x"66666666" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001000" report "Unexpected config address." severity error; + assert configDataWrite = x"77777777" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001001" report "Unexpected config address." severity error; + assert configDataWrite = x"88888888" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001010" report "Unexpected config address." severity error; + assert configDataWrite = x"99999999" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001011" report "Unexpected config address." severity error; + assert configDataWrite = x"aaaaaaaa" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001100" report "Unexpected config address." severity error; + assert configDataWrite = x"bbbbbbbb" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001101" report "Unexpected config address." severity error; + assert configDataWrite = x"cccccccc" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001110" report "Unexpected config address." severity error; + assert configDataWrite = x"dddddddd" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000001111" report "Unexpected config address." severity error; + assert configDataWrite = x"eeeeeeee" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000010000" report "Unexpected config address." severity error; + assert configDataWrite = x"ffffffff" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + wait until clk = '1'; + assert configWe = '1' report "Unexpected config write." severity error; + assert configAddr = "0000000000000000010001" report "Unexpected config address." severity error; + assert configDataWrite = x"10101010" report "Unexpected configDataWrite." severity error; + configAck <= '1'; + wait until clk = '1'; + configAck <= '0'; + + configStbExpected <= '0'; + + ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", + tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, + sourceId=>x"beef", destId=>x"dead", + payload=>RioMaintenance(transaction=>"0011", + size=>"0000", + tid=>x"cc", + hopCount=>x"ff", + configOffset=>"000000000000000000000", + wdptr=>'0', + dataLength=>0, + data=>maintData))); + + + --------------------------------------------------------------------------- + -- Test completed. + --------------------------------------------------------------------------- + + TestEnd; + end process; + + ----------------------------------------------------------------------------- + -- Instantiate a process receiving the configuration accesses to the + -- implementation defined space. + ----------------------------------------------------------------------------- + process + begin + loop + wait until clk'event and clk = '1'; + assert configStbExpected = configStb report "Unexpected config-space access." severity error; + end loop; + end process; + + ----------------------------------------------------------------------------- + -- Instantiate the test port array. + ----------------------------------------------------------------------------- + + readFrameRestart <= '0'; + TestPortInst: TestPort + 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, + 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); + + ----------------------------------------------------------------------------- + -- Instantiate the switch. + ----------------------------------------------------------------------------- + + TestObject: RioLogicalCommon + port map( + clk=>clk, areset_n=>areset_n, enable=>enable, + writeFrameFull_i=>writeFrameFull, + writeFrame_o=>writeFrame, + writeFrameAbort_o=>writeFrameAbort, + writeContent_o=>writeContent, + writeContentData_o=>writeContentData, + readFrameEmpty_i=>readFrameEmpty, + readFrame_o=>readFrame, + readContent_o=>readContent, + readContentEnd_i=>readContentEnd, + readContentData_i=>readContentData, + configStb_o=>configStb, + configWe_o=>configWe, + configAdr_o=>configAddr, + configDat_o=>configDataWrite, + configDat_i=>configDataRead, + configAck_i=>configAck); + + +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 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; Index: branches/2.0.0-development/bench/vhdl/TestRioPacketBuffer.vhd =================================================================== --- branches/2.0.0-development/bench/vhdl/TestRioPacketBuffer.vhd (nonexistent) +++ branches/2.0.0-development/bench/vhdl/TestRioPacketBuffer.vhd (revision 41) @@ -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;
branches/2.0.0-development/bench/vhdl/TestRioPacketBuffer.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: branches/2.0.0-development/bench/vhdl/TestRioSwitch.vhd =================================================================== --- branches/2.0.0-development/bench/vhdl/TestRioSwitch.vhd (nonexistent) +++ branches/2.0.0-development/bench/vhdl/TestRioSwitch.vhd (revision 41) @@ -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;
branches/2.0.0-development/bench/vhdl/TestRioSwitch.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: branches/2.0.0-development/rtl/vhdl/RioCommon.vhd =================================================================== --- branches/2.0.0-development/rtl/vhdl/RioCommon.vhd (nonexistent) +++ branches/2.0.0-development/rtl/vhdl/RioCommon.vhd (revision 41) @@ -0,0 +1,1357 @@ +------------------------------------------------------------------------------- +-- +-- 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. + ----------------------------------------------------------------------------- + + -- 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; + + ----------------------------------------------------------------------------- + -- Function to print a std_logic_vector. + ----------------------------------------------------------------------------- + function to_string(constant value : std_logic_vector) + 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 ); + + --------------------------------------------------------------------------- + -- Procedures for test control. + --------------------------------------------------------------------------- + + procedure TestWarning(constant tag : in string); + procedure TestError(constant tag : in string; + constant stopAtError : in boolean := true); + procedure TestCompare(constant expression : in boolean; + constant tag : in string := ""; + constant stopAtError : in boolean := true); + procedure TestCompare(constant got : in std_logic; + constant expected : in std_logic; + constant tag : in string := ""; + constant stopAtError : in boolean := true); + procedure TestCompare(constant got : in std_logic_vector; + constant expected : in std_logic_vector; + constant tag : in string := ""; + constant stopAtError : in boolean := true); + procedure TestCompare(constant got : in natural; + constant expected : in natural; + constant tag : in string := ""; + constant stopAtError : in boolean := true); + procedure TestCompare(constant got : in time; + constant expected : in time; + constant tag : in string := ""; + constant stopAtError : in boolean := true); + + procedure TestWait(signal waitSignal : in std_logic; + constant waitValue : in std_logic; + constant tag : in string := ""; + constant waitTime : in time := 1 ms; + constant stopAtError : in boolean := true); + procedure TestWait(signal waitSignal : in std_logic; + constant waitValue : in std_logic; + signal ackSignal : inout std_logic; + constant tag : in string := ""; + constant waitTime : in time := 1 ms; + constant stopAtError : in boolean := true); + + 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(23 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(23 downto 5) := symbolData; + returnValue(4 downto 0) := Crc5(symbolData, "11111"); + + 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; + + ----------------------------------------------------------------------------- + -- Function to print std_logic_vector. + ----------------------------------------------------------------------------- + function to_string(constant value : std_logic) return string is + variable s : string(1 to 1); + begin + if (value = '0') then + s(1) := '0'; + elsif (value = '1') then + s(1) := '1'; + elsif (value = 'U') then + s(1) := 'U'; + elsif (value = 'X') then + s(1) := 'X'; + else + s(1) := '?'; + end if; + return s; + end function; + function to_string(constant value : std_logic_vector) return string is + variable s : string(1 to value'length); + variable index : positive; + variable i : natural; + begin + index := 1; + for i in value'range loop + if (value(i) = '0') then + s(index) := '0'; + elsif (value(i) = '1') then + s(index) := '1'; + elsif (value(i) = 'U') then + s(index) := 'U'; + elsif (value(i) = 'X') then + s(index) := 'X'; + else + s(index) := '?'; + end if; + index := index + 1; + end loop; + return s; + 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; + + --------------------------------------------------------------------------- + -- Procedures to handle tests. + --------------------------------------------------------------------------- + + procedure TestWarning(constant tag : in string) is + variable writeBuffer : line; + begin + write(writeBuffer, now); + write(writeBuffer, string'(":WARNING:")); + write(writeBuffer, tag); + writeline(OUTPUT, writeBuffer); + end procedure; + + procedure TestError(constant tag : in string; + constant stopAtError : in boolean := true) is + variable writeBuffer : line; + begin + write(writeBuffer, now); + write(writeBuffer, string'(":FAILED:")); + write(writeBuffer, tag); + writeline(OUTPUT, writeBuffer); + + if (stopAtError) then + std.env.stop(0); + end if; + end procedure; + + procedure TestCompare(constant expression : in boolean; + constant tag : in string := ""; + constant stopAtError : in boolean := true) is + variable writeBuffer : line; + begin + write(writeBuffer, now); + if (not expression) then + write(writeBuffer, string'(":FAILED:")); + else + write(writeBuffer, string'(":PASSED:")); + end if; + write(writeBuffer, tag); + writeline(OUTPUT, writeBuffer); + + if (stopAtError) and (not expression) then + std.env.stop(0); + end if; + end procedure; + + procedure TestCompare(constant got : in std_logic; + constant expected : in std_logic; + constant tag : in string := ""; + constant stopAtError : in boolean := true) is + variable writeBuffer : line; + begin + write(writeBuffer, now); + if (expected /= got) then + write(writeBuffer, string'(":FAILED:")); + write(writeBuffer, tag); + write(writeBuffer, ":got=" & to_string(got)); + write(writeBuffer, ":expected=" & to_string(expected)); + else + write(writeBuffer, string'(":PASSED:")); + write(writeBuffer, tag); + end if; + writeline(OUTPUT, writeBuffer); + + if (stopAtError) and (expected /= got) then + std.env.stop(0); + end if; + end procedure; + + procedure TestCompare(constant got : in std_logic_vector; + constant expected : in std_logic_vector; + constant tag : in string := ""; + constant stopAtError : in boolean := true) is + variable writeBuffer : line; + begin + write(writeBuffer, now); + if (expected /= got) then + write(writeBuffer, string'(":FAILED:")); + write(writeBuffer, tag); + write(writeBuffer, ":got=" & to_string(got)); + write(writeBuffer, ":expected=" & to_string(expected)); + else + write(writeBuffer, string'(":PASSED:")); + write(writeBuffer, tag); + end if; + writeline(OUTPUT, writeBuffer); + + if (stopAtError) and (expected /= got) then + std.env.stop(0); + end if; + end procedure; + + procedure TestCompare(constant got : in natural; + constant expected : in natural; + constant tag : in string := ""; + constant stopAtError : in boolean := true) is + variable writeBuffer : line; + begin + write(writeBuffer, now); + if (expected /= got) then + write(writeBuffer, string'(":FAILED:")); + write(writeBuffer, tag); + write(writeBuffer, ":got=" & integer'image(got)); + write(writeBuffer, ":expected=" & integer'image(expected)); + else + write(writeBuffer, string'(":PASSED:")); + write(writeBuffer, tag); + end if; + writeline(OUTPUT, writeBuffer); + + if (stopAtError) and (expected /= got) then + std.env.stop(0); + end if; + end procedure; + + procedure TestCompare(constant got : in time; + constant expected : in time; + constant tag : in string := ""; + constant stopAtError : in boolean := true) is + variable writeBuffer : line; + begin + write(writeBuffer, now); + if (expected /= got) then + write(writeBuffer, string'(":FAILED:")); + write(writeBuffer, tag); + write(writeBuffer, string'(":got=")); + write(writeBuffer, got); + write(writeBuffer, string'(":expected=")); + write(writeBuffer, expected); + else + write(writeBuffer, string'(":PASSED:")); + write(writeBuffer, tag); + end if; + writeline(OUTPUT, writeBuffer); + + if (stopAtError) and (expected /= got) then + std.env.stop(0); + end if; + end procedure; + + procedure TestWait(signal waitSignal : in std_logic; + constant waitValue : in std_logic; + constant tag : in string := ""; + constant waitTime : in time := 1 ms; + constant stopAtError : in boolean := true) is + variable writeBuffer : line; + begin + if (waitSignal /= waitValue) then + wait until waitSignal = waitValue for waitTime; + if (waitSignal /= waitValue) then + write(writeBuffer, now); + write(writeBuffer, string'(":FAILED:")); + write(writeBuffer, tag); + writeline(OUTPUT, writeBuffer); + + if (stopAtError) then + std.env.stop(0); + end if; + end if; + end if; + end procedure; + + procedure TestWait(signal waitSignal : in std_logic; + constant waitValue : in std_logic; + signal ackSignal : inout std_logic; + constant tag : in string := ""; + constant waitTime : in time := 1 ms; + constant stopAtError : in boolean := true) is + variable writeBuffer : line; + begin + if (waitSignal /= waitValue) then + + wait until waitSignal = waitValue for waitTime; + + if (waitSignal /= waitValue) then + write(writeBuffer, now); + write(writeBuffer, string'(":FAILED:")); + write(writeBuffer, tag); + writeline(OUTPUT, writeBuffer); + + if (stopAtError) then + std.env.stop(0); + end if; + end if; + end if; + + ackSignal <= not ackSignal; + + wait until waitSignal /= waitValue for waitTime; + + if (waitSignal = waitValue) then + write(writeBuffer, now); + write(writeBuffer, string'(":FAILED:")); + write(writeBuffer, tag); + writeline(OUTPUT, writeBuffer); + + if (stopAtError) then + std.env.stop(0); + end if; + end if; + end procedure; + + procedure TestEnd is + variable writeBuffer : line; + begin + write(writeBuffer, now); + write(writeBuffer, string'(":COMPLETED")); + writeline(OUTPUT, writeBuffer); + std.env.stop(0); + 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; + + + + +
branches/2.0.0-development/rtl/vhdl/RioCommon.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: branches/2.0.0-development/rtl/vhdl/RioSerial.vhd =================================================================== --- branches/2.0.0-development/rtl/vhdl/RioSerial.vhd (nonexistent) +++ branches/2.0.0-development/rtl/vhdl/RioSerial.vhd (revision 41) @@ -0,0 +1,2980 @@ +------------------------------------------------------------------------------- +-- +-- 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. +-- +-- 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: Remove multi-symbol support to make the code more readable... +-- REMARK: Make more signals synchronous... +-- REMARK: Add support for the change of ackIds... +-- REMARK: Update all comments... +-- REMARK: Make sure that RioPacketBuffer can handle simultanous accesses at +-- the window-pins and the normal-pins... Add another singlememory... +-- REMARK: Make the pipe-line stages into block-statements to make the code more readable... +-- REMARK: Be consistent, tx->outbound and rx->inbound or egress/ingress... +-- REMARK: Always send status after a link-response? + +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; + SYMBOL_COUNTER_WIDTH : natural := 8; + TICKS_SEND_STATUS_STARTUP : natural := 15; + TICKS_SEND_STATUS_OPERATIONAL : natural := 255); + port( + -- System signals. + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + -- Status signals for maintenance operations. + portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0); + 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; + outboundControlValid_o : out std_logic; + outboundControlSymbol_o : out std_logic_vector(23 downto 0); + outboundDataValid_o : out std_logic; + outboundDataSymbol_o : out std_logic_vector(31 downto 0); + inboundControlValid_i : in std_logic; + inboundControlSymbol_i : in std_logic_vector(23 downto 0); + inboundDataValid_i : in std_logic; + inboundDataSymbol_i : in std_logic_vector(31 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- 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; + enable : 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_SYMBOLS : natural range 1 to 1 := 1; + SYMBOL_COUNTER_WIDTH : natural; + TICKS_SEND_STATUS_STARTUP : natural; + TICKS_SEND_STATUS_OPERATIONAL : natural); + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0); + portEnable_i : in std_logic; + + localAckIdWrite_i : in std_logic; + clrOutstandingAckId_i : in std_logic; + outstandingAckId_i : in std_logic_vector(4 downto 0); + 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; + outboundControlValid_o : out std_logic; + outboundControlSymbol_o : out std_logic_vector(23 downto 0); + outboundDataValid_o : out std_logic; + outboundDataSymbol_o : out std_logic_vector(31 downto 0); + + txControlEmpty_i : in std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + txControlSymbol_i : in std_logic_vector(12*NUMBER_SYMBOLS downto 0); + txControlUpdate_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + + rxControlEmpty_i : in std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + rxControlSymbol_i : in std_logic_vector(12*NUMBER_SYMBOLS downto 0); + rxControlUpdate_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + + linkInitialized_o : out std_logic; + linkInitialized_i : in std_logic; + 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; + readContentData_i : in std_logic_vector(32*NUMBER_SYMBOLS-1 downto 0)); + end component; + + component RioReceiver is + generic( + NUMBER_SYMBOLS : natural range 1 to 1 := 1); + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + portEnable_i : in std_logic; + + 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; + inboundControlValid_i : in std_logic; + inboundControlSymbol_i : in std_logic_vector(23 downto 0); + inboundDataValid_i : in std_logic; + inboundDataSymbol_i : in std_logic_vector(31 downto 0); + + txControlWrite_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + txControlSymbol_o : out std_logic_vector(12*NUMBER_SYMBOLS downto 0); + rxControlWrite_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + rxControlSymbol_o : out std_logic_vector(12*NUMBER_SYMBOLS downto 0); + + ackIdStatus_o : out std_logic_vector(4 downto 0); + linkInitialized_o : out std_logic; + + 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(32*NUMBER_SYMBOLS-1 downto 0)); + end component; + + constant NUMBER_SYMBOLS : natural := 1; + + signal linkInitializedRx : std_logic; + signal linkInitializedTx : std_logic; + signal ackIdStatus : std_logic_vector(4 downto 0); + + signal txControlWrite : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal txControlWriteSymbol : std_logic_vector(12*NUMBER_SYMBOLS downto 0); + signal txControlReadEmpty : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal txControlRead : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal txControlReadSymbol : std_logic_vector(12*NUMBER_SYMBOLS downto 0); + + signal rxControlWrite : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal rxControlWriteSymbol : std_logic_vector(12*NUMBER_SYMBOLS downto 0); + signal rxControlReadEmpty : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal rxControlRead : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal rxControlReadSymbol : std_logic_vector(12*NUMBER_SYMBOLS downto 0); + +begin + + linkInitialized_o <= + '1' when ((linkInitializedRx = '1') and (linkInitializedTx = '1')) else '0'; + + ----------------------------------------------------------------------------- + -- Serial layer modules. + ----------------------------------------------------------------------------- + + Transmitter: RioTransmitter + generic map( + TIMEOUT_WIDTH=>TIMEOUT_WIDTH, + NUMBER_SYMBOLS=>NUMBER_SYMBOLS, + SYMBOL_COUNTER_WIDTH=>SYMBOL_COUNTER_WIDTH, + TICKS_SEND_STATUS_STARTUP=>TICKS_SEND_STATUS_STARTUP, + TICKS_SEND_STATUS_OPERATIONAL=>TICKS_SEND_STATUS_OPERATIONAL) + port map( + clk=>clk, areset_n=>areset_n, enable=>enable, + 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, + outboundControlValid_o=>outboundControlValid_o, + outboundControlSymbol_o=>outboundControlSymbol_o, + outboundDataValid_o=>outboundDataValid_o, + outboundDataSymbol_o=>outboundDataSymbol_o, + 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, + readContentData_i=>readContentData_i(32*NUMBER_SYMBOLS-1 downto 0)); + + SymbolFifo: for i in 0 to NUMBER_SYMBOLS-1 generate + TxSymbolFifo: RioFifo + generic map(DEPTH_WIDTH=>5, DATA_WIDTH=>13) + port map( + clk=>clk, areset_n=>areset_n, enable=>enable, + 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, enable=>enable, + 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; + + Receiver: RioReceiver + generic map(NUMBER_SYMBOLS=>NUMBER_SYMBOLS) + port map( + clk=>clk, areset_n=>areset_n, enable=>enable, + portEnable_i=>inputPortEnable_i, + localAckIdWrite_i=>localAckIdWrite_i, + inboundAckId_i=>inboundAckId_i, + inboundAckId_o=>inboundAckId_o, + portInitialized_i=>portInitialized_i, + inboundControlValid_i=>inboundControlValid_i, + inboundControlSymbol_i=>inboundControlSymbol_i, + inboundDataValid_i=>inboundDataValid_i, + inboundDataSymbol_i=>inboundDataSymbol_i, + 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, + writeContentData_o=>writeContentData_o(32*NUMBER_SYMBOLS-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_SYMBOLS : natural range 1 to 1 := 1; + SYMBOL_COUNTER_WIDTH : natural; + TICKS_SEND_STATUS_STARTUP : natural; + TICKS_SEND_STATUS_OPERATIONAL : natural); + port( + -- System signals. + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + -- Status signals used for maintenance. + portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0); + 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; + outboundControlValid_o : out std_logic; + outboundControlSymbol_o : out std_logic_vector(23 downto 0); + outboundDataValid_o : out std_logic; + outboundDataSymbol_o : out std_logic_vector(31 downto 0); + + -- Control symbols aimed to the transmitter. + txControlEmpty_i : in std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + txControlSymbol_i : in std_logic_vector(12*NUMBER_SYMBOLS downto 0); + txControlUpdate_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + + -- Control symbols from the receiver to send. + rxControlEmpty_i : in std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + rxControlSymbol_i : in std_logic_vector(12*NUMBER_SYMBOLS downto 0); + rxControlUpdate_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + + -- Internal signalling from the receiver part. + linkInitialized_o : out std_logic; + 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; + readContentData_i : in std_logic_vector(32*NUMBER_SYMBOLS-1 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for RioTransmitter. +------------------------------------------------------------------------------- +architecture RioTransmitterImpl of RioTransmitter is + + component RioTransmitterCore is + generic( + SYMBOL_COUNTER_WIDTH : natural; + TICKS_SEND_STATUS_STARTUP : natural; + TICKS_SEND_STATUS_OPERATIONAL : natural); + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + portEnable_i : in std_logic; + + portInitialized_i : in std_logic; + outboundControlValid_o : out std_logic; + outboundControlSymbol_o : out std_logic_vector(23 downto 0); + outboundDataValid_o : out std_logic; + outboundDataSymbol_o : out std_logic_vector(31 downto 0); + + txControlEmpty_i : in std_logic; + txControlSymbol_i : in std_logic_vector(12 downto 0); + txControlUpdate_o : out std_logic; + + rxControlEmpty_i : in std_logic; + rxControlSymbol_i : in std_logic_vector(12 downto 0); + rxControlUpdate_o : out std_logic; + + linkInitialized_o : out std_logic; + linkInitialized_i : in std_logic; + ackIdStatus_i : in std_logic_vector(4 downto 0); + + 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); + frameContent_i : in std_logic_vector(31 downto 0); + frameContent_o : out std_logic_vector(31 downto 0); + statusCounter_i : in std_logic_vector(3 downto 0); + statusCounter_o : out std_logic_vector(3 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)); + 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_SYMBOLS-1 downto 0); + signal ackIdCurrent, ackIdNext : std_logic_vector(5*NUMBER_SYMBOLS-1 downto 0); + signal bufferStatusCurrent, bufferStatusNext : std_logic_vector(5*NUMBER_SYMBOLS-1 downto 0); + signal statusReceivedCurrent, statusReceivedNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal numberSentLinkRequestsCurrent, numberSentLinkRequestsNext : std_logic_vector(2*NUMBER_SYMBOLS-1 downto 0); + signal outputErrorStoppedCurrent, outputErrorStoppedNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal fatalErrorCurrent, fatalErrorNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal recoverActiveCurrent, recoverActiveNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal recoverCounterCurrent, recoverCounterNext : std_logic_vector(5*NUMBER_SYMBOLS-1 downto 0); + signal ackIdWindowCurrent, ackIdWindowNext : std_logic_vector(5*NUMBER_SYMBOLS-1 downto 0); + signal frameStateCurrent, frameStateNext : std_logic_vector(4*NUMBER_SYMBOLS-1 downto 0); + signal frameContentCurrent, frameContentNext : std_logic_vector(32*NUMBER_SYMBOLS-1 downto 0); + signal statusCounterCurrent, statusCounterNext : std_logic_vector(4*NUMBER_SYMBOLS-1 downto 0); + + signal readFrame : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal readFrameRestart : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal readWindowReset : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal readWindowNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal readContent : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); +begin + + ----------------------------------------------------------------------------- + -- 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_SYMBOLS-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 (enable = '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 if; + end process; + + timeSentExpired <= timeSentDelta(TIMEOUT_WIDTH); + + timeSentEnable <= enable 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'); + frameContentCurrent <= (others=>'0'); + statusCounterCurrent <= (others=>'0'); + elsif (clk'event and clk = '1') then + if (enable = '1') then + operationalCurrent <= operationalNext; + ackIdCurrent <= ackIdNext; + bufferStatusCurrent <= bufferStatusNext; + statusReceivedCurrent <= statusReceivedNext; + numberSentLinkRequestsCurrent <= numberSentLinkRequestsNext; + outputErrorStoppedCurrent <= outputErrorStoppedNext; + fatalErrorCurrent <= fatalErrorNext; + recoverActiveCurrent <= recoverActiveNext; + recoverCounterCurrent <= recoverCounterNext; + ackIdWindowCurrent <= ackIdWindowNext; + frameStateCurrent <= frameStateNext; + frameContentCurrent <= frameContentNext; + statusCounterCurrent <= statusCounterNext; + end if; + end if; + end process; + + CoreGeneration: for i in 0 to NUMBER_SYMBOLS-1 generate + TxCore: RioTransmitterCore + generic map(SYMBOL_COUNTER_WIDTH=>SYMBOL_COUNTER_WIDTH, + TICKS_SEND_STATUS_STARTUP=>TICKS_SEND_STATUS_STARTUP, + TICKS_SEND_STATUS_OPERATIONAL=>TICKS_SEND_STATUS_OPERATIONAL) + port map( + clk=>clk, areset_n=>areset_n, enable=>enable, + portEnable_i=>portEnable_i, + portInitialized_i=>portInitialized_i, + outboundControlValid_o=>outboundControlValid_o, + outboundControlSymbol_o=>outboundControlSymbol_o, + outboundDataValid_o=>outboundDataValid_o, + outboundDataSymbol_o=>outboundDataSymbol_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), + frameContent_i=>frameContentCurrent(32*(i+1)-1 downto 32*i), + frameContent_o=>frameContentNext(32*(i+1)-1 downto 32*i), + statusCounter_i=>statusCounterCurrent(4*(i+1)-1 downto 4*i), + statusCounter_o=>statusCounterNext(4*(i+1)-1 downto 4*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, + readContentData_i=>readContentData_i); + end generate; + +end architecture; + + + +------------------------------------------------------------------------------- +-- RioTransmitterCore +-- This module generate control- and data-symbols each clock tick. A +-- tick when nothing is generated it is assumed that an idle sequence is +-- generated. +-- +-- TICKS_SEND_STATUS - The number of consequtive ticks sending nothing to wait +-- before a status-control-symbol is transmitted. +-- +-- outboundControlValid_o='0' and outboundDataValid_o='0': nothing to send. +-- outboundControlValid_o='0' and outboundDataValid_o='1': outboundDataSymbol_o contains a data-symbol. +-- outboundControlValid_o='1' and outboundDataValid_o='0': outboundControlSymbol_o contains a control-symbol. +-- outboundControlValid_o='1' and outboundDataValid_o='1': an error has occurred. +------------------------------------------------------------------------------- +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( + SYMBOL_COUNTER_WIDTH : natural; + TICKS_SEND_STATUS_STARTUP : natural; + TICKS_SEND_STATUS_OPERATIONAL : natural); + port( + -- System signals. + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + -- Status signals used for maintenance. + portEnable_i : in std_logic; + + -- Port output interface. + portInitialized_i : in std_logic; + outboundControlValid_o : out std_logic; + outboundControlSymbol_o : out std_logic_vector(23 downto 0); + outboundDataValid_o : out std_logic; + outboundDataSymbol_o : out std_logic_vector(31 downto 0); + + -- Control symbols aimed to the transmitter. + txControlEmpty_i : in std_logic; + txControlSymbol_i : in std_logic_vector(12 downto 0); + txControlUpdate_o : out std_logic; + + -- Control symbols from the receiver to send. + rxControlEmpty_i : in std_logic; + rxControlSymbol_i : in std_logic_vector(12 downto 0); + rxControlUpdate_o : out std_logic; + + -- Internal signalling from the receiver part. + linkInitialized_o : out std_logic; + linkInitialized_i : in std_logic; + ackIdStatus_i : in std_logic_vector(4 downto 0); + + -- 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); + frameContent_i : in std_logic_vector(31 downto 0); + frameContent_o : out std_logic_vector(31 downto 0); + statusCounter_i : in std_logic_vector(3 downto 0); + statusCounter_o : out std_logic_vector(3 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; + readContentData_i : in std_logic_vector(31 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for RioTransmitterCore. +------------------------------------------------------------------------------- +architecture RioTransmitterCoreImpl of RioTransmitterCore is + + -- The number of statuses to transmit at link initialization before starting + -- to send packets. + constant NUMBER_STATUS_TRANSMIT : std_logic_vector(3 downto 0) := "1111"; + + -- The number of retries to make when a link-request has not been answered. + constant NUMBER_LINK_RESPONSE_RETRIES : std_logic_vector(1 downto 0) := "10"; + + -- States for frame transmission. + constant FRAME_IDLE : std_logic_vector(3 downto 0) := "0000"; + constant FRAME_BUFFER : std_logic_vector(3 downto 0) := "0001"; + constant FRAME_START : std_logic_vector(3 downto 0) := "0010"; + constant FRAME_FIRST : std_logic_vector(3 downto 0) := "0011"; + constant FRAME_MIDDLE : std_logic_vector(3 downto 0) := "0100"; + constant FRAME_INSERT_IDLE : std_logic_vector(3 downto 0) := "0101"; + constant FRAME_INSERT_WAIT : std_logic_vector(3 downto 0) := "0110"; + constant FRAME_LAST : std_logic_vector(3 downto 0) := "0111"; + constant FRAME_START_CONTINUE : std_logic_vector(3 downto 0) := "1000"; + constant FRAME_END : std_logic_vector(3 downto 0) := "1001"; + constant FRAME_DISCARD : std_logic_vector(3 downto 0) := "1010"; + + -- CRC-5 calculation unit for control-symbol generation. + component Crc5ITU is + port( + d_i : in std_logic_vector(18 downto 0); + crc_o : out std_logic_vector(4 downto 0)); + end component; + + -- Stage-1 signals. + alias txControlStype0 : std_logic_vector(2 downto 0) is txControlSymbol_i(12 downto 10); + alias txControlParameter0 : std_logic_vector(4 downto 0) is txControlSymbol_i(9 downto 5); + alias txControlParameter1 : std_logic_vector(4 downto 0) is txControlSymbol_i(4 downto 0); + signal txControlUpdateOut : std_logic; + signal sendRestartFromRetry, sendRestartFromRetryOut : std_logic; + signal sendLinkRequest, sendLinkRequestOut : std_logic; + + -- Stage-2 signals. + signal readFrameOut : std_logic; + signal readFrameRestartOut : std_logic; + signal readWindowResetOut : std_logic; + signal readWindowNextOut : std_logic; + signal readContentOut : std_logic; + signal discardFrameOut : 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); + + -- Stage-3 signals. + alias rxControlStype0 : std_logic_vector(2 downto 0) is rxControlSymbol_i(12 downto 10); + alias rxControlParameter0 : std_logic_vector(4 downto 0) is rxControlSymbol_i(9 downto 5); + alias rxControlParameter1 : std_logic_vector(4 downto 0) is rxControlSymbol_i(4 downto 0); + signal rxControlUpdateOut : std_logic; + signal symbolControlStype1 : std_logic; + signal controlValidOut, controlValid : std_logic; + 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); + + -- Stage-4 signals. + signal symbolCounter : std_logic_vector(SYMBOL_COUNTER_WIDTH-1 downto 0); + signal sendStatusRequired : std_logic; + signal controlContent : std_logic_vector(23 downto 0); + signal crc5 : std_logic_vector(4 downto 0); + + +begin + + linkInitialized_o <= operational_i; + + ----------------------------------------------------------------------------- + -- First pipeline stage. + -- Receive control-symbols from our link-partner and supervise timeouts. + -- Input: ackId, ackIdWindow, timeoutExpired + -- Output: sendLinkRequest, sendRestartFromRetry, ackId + ----------------------------------------------------------------------------- + -- REMARK: Update the comment above... + + txControlUpdate_o <= txControlUpdateOut and enable; + + 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'; + + -- Check the current state of the transmitter. + if (fatalError_i = '1') then + -- Fatal error has been encountered. + outputErrorStopped_o <= '0'; + fatalError_o <= '0'; + elsif (recoverActive_i = '1') then + -- Controlled recovering due to an earlier error is ongoing. + 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 + -- No fatal error or recovering active. + + -- Check if operational. + 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 => + -- The link partner has rejected a packet. + + 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; + + process(clk, areset_n) + begin + if (areset_n = '0') then + readFrame_o <= '0'; + + sendRestartFromRetry <= '0'; + sendLinkRequest <= '0'; + elsif (clk'event and clk = '1') then + readFrame_o <= '0'; + + if (enable = '1') then + readFrame_o <= readFrameOut or discardFrameOut; + + sendRestartFromRetry <= sendRestartFromRetryOut; + sendLinkRequest <= sendLinkRequestOut; + end if; + end if; + end process; + + ----------------------------------------------------------------------------- + -- Second pipeline stage. + -- Create stype1-part of symbols and data symbols. Save the time when a + -- packet was fully sent. + -- Input: sendRestartFromRetry, sendLinkRequest + -- Output: ackIdWindow, frameState, timeout(0 to 31), + -- symbolControlStart, symbolControlEnd, symbolControlRestart, + -- symbolControlLinkRequest, symbolData2, symbolData2Content. + ----------------------------------------------------------------------------- + + readFrameRestart_o <= readFrameRestartOut and enable; + readWindowReset_o <= readWindowResetOut and enable; + readWindowNext_o <= readWindowNextOut and enable; + readContent_o <= readContentOut and enable; + + -- This process decide which stype1-part of a control symbols to send as well + -- as all data symbols. + process(readWindowEmpty_i, bufferStatus_i, + readContentData_i, readContentEnd_i, + recoverActive_i, ackId_i, operational_i, outputErrorStopped_i, portEnable_i, + frameState_i, frameContent_i, + ackIdWindow_i, + sendRestartFromRetry, sendLinkRequest, + rxControlEmpty_i, + fatalError_i) + begin + readFrameRestartOut <= '0'; + readWindowResetOut <= '0'; + readWindowNextOut <= '0'; + readContentOut <= '0'; + + frameState_o <= frameState_i; + frameContent_o <= frameContent_i; + ackIdWindow_o <= ackIdWindow_i; + + timeSentSet_o <= '0'; + + symbolControlRestartOut <= '0'; + symbolControlLinkRequestOut <= '0'; + symbolControlStartOut <= '0'; + symbolControlEndOut <= '0'; + symbolDataOut <= '0'; + symbolDataContentOut <= (others => '0'); + + discardFrameOut <= '0'; + + -- Check if allowed to send anything. + if ((fatalError_i = '1') or (recoverActive_i = '1') or + (operational_i = '0')) then + ----------------------------------------------------------------------- + -- This state is entered at startup or if any error has occurred. + -- A port that is not initialized or in an error state should not + -- transmit any packets. + ----------------------------------------------------------------------- + + -- Initialize framing before entering the operational state. + readWindowResetOut <= '1'; + frameState_o <= FRAME_IDLE; + ackIdWindow_o <= ackId_i; + else + ------------------------------------------------------------------- + -- This state is the operational state. It relays frames and handle + -- flow control. + ------------------------------------------------------------------- + + if (sendRestartFromRetry = '1') then + -- Required to send a restart-from-retry. + + -- 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. + -- Since the transmission-window is reset, it is ok to go to the + -- FRAME_IDLE-state even if the present state was FRAME_DISCARD since + -- we will end up in the discard state anyway after the frames has + -- been resent. + ackIdWindow_o <= ackId_i; + frameState_o <= FRAME_IDLE; + readWindowResetOut <= '1'; + elsif (sendLinkRequest = '1') then + -- Required to send a link-request. + -- There is no need to restart the packet transmission since we do + -- not yet know which packets that was successfully received by our + -- link partner. Wait for the reply before anything is discarded. + + -- Send a link-request symbol. + symbolControlLinkRequestOut <= '1'; + + -- Write the current timer value. + timeSentSet_o <= '1'; + elsif ((sendRestartFromRetry = '0') and (sendLinkRequest = '0') and + (outputErrorStopped_i = '0')) then + -- No control-symbol is required to be sent to the link-partner. + -- Proceed to send a pending packet. + + -- Check the current state of the frame transfer. + 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'; + frameState_o <= FRAME_START; + end if; + + when FRAME_START | FRAME_START_CONTINUE => + ------------------------------------------------------- + -- 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. + -- This state should result in a start-of-frame if possible or + -- end-of-frame if a frame has not been ended properly yet. + + -- Check if the packet is allowed. + if ((portEnable_i = '1') or + (readContentData_i(19 downto 16) = FTYPE_MAINTENANCE_CLASS)) then + -- Packet is allowed. + + -- Check if the link is able to accept the new frame. + if ((bufferStatus_i /= "00000") and + ((unsigned(ackIdWindow_i)+1) /= unsigned(ackId_i))) then + -- There are buffers ready to receive the new packet at the other + -- side and there are ackIds left to tag it. + -- The packet may be transmitted. + + -- Read the next packet content and buffer the current output. + readContentOut <= '1'; + frameContent_o <= readContentData_i; + + -- Send a control symbol to start the packet and a status to + -- complete the symbol. + symbolControlStartOut <= '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_START_CONTINUE) 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_START_CONTINUE) then + symbolControlEndOut <= '1'; + end if; + 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(25 downto 0); + + -- Read the next frame content and go to next state to send it. + readContentOut <= '1'; + frameContent_o <= readContentData_i; + frameState_o <= FRAME_MIDDLE; + + when FRAME_MIDDLE | FRAME_INSERT_WAIT => + --------------------------------------------------------------- + -- 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; + frameContent_o <= readContentData_i; + + -- Check if the packet is ending. + if (readContentEnd_i = '1') then + -- The packet is ending. + readWindowNextOut <= '1'; + frameState_o <= FRAME_LAST; + elsif ((frameState_i = FRAME_MIDDLE) and (rxControlEmpty_i = '0')) then + -- There is a pending control-symbol from the receiver. + -- This must only be entered if the previous state was a data + -- symbol, not if an idle symbol was inserted. + frameState_o <= FRAME_INSERT_IDLE; + else + -- The packet is not ending. + readContentOut <= '1'; + frameState_o <= FRAME_MIDDLE; + end if; + + when FRAME_INSERT_IDLE => + ----------------------------------------------------------------- + -- Dont send a data-symbol this tick to allow for a pending + -- control-symbol from the receiver to be inserted into the stream. + ----------------------------------------------------------------- + + symbolDataOut <= '0'; + readContentOut <= '1'; + frameState_o <= FRAME_INSERT_WAIT; + + when FRAME_LAST => + ----------------------------------------------------------------- + -- Sending the last data symbol of a packet. + -- If there are pending packets, they can be started immediatly, + -- otherwise, the current packet should be ended. + ----------------------------------------------------------------- + + -- Send the last data symbol of the packet. + symbolDataOut <= '1'; + symbolDataContentOut <= frameContent_i; + + -- Check if there are pending packets. + if (readWindowEmpty_i = '0') then + -- Pending packet exist. + readContentOut <= '1'; + frameState_o <= FRAME_START_CONTINUE; + else + -- No pending packets. + frameState_o <= FRAME_END; + end if; + + -- Update the window ackId. + ackIdWindow_o <= std_logic_vector(unsigned(ackIdWindow_i) + 1); + + -- Start timeout supervision for the transmitted frame. + timeSentSet_o <= '1'; + + when FRAME_END => + ----------------------------------------------------------------- + -- There are no packets to directly follow the one that is ending. + -- Mark the current packet as ended. + ----------------------------------------------------------------- + + -- Send a control symbol to end the frame. + symbolControlEndOut <= '1'; + frameState_o <= FRAME_IDLE; + + when FRAME_DISCARD => + --------------------------------------------------------------- + -- The packet should be discarded. + -- Hold any pending packets until there are no outstanding ones. + --------------------------------------------------------------- + + -- Check that there are no outstanding packets. + if(unsigned(ackIdWindow_i) = unsigned(ackId_i)) then + -- No unacknowledged packets. + -- It is now safe to remove the unallowed packet. + discardFrameOut <= '1'; + + -- Go back and send a new frame. + frameState_o <= FRAME_IDLE; + else + -- Still outstanding packets. + -- Dont do anything. + end if; + + when others => + --------------------------------------------------------------- + -- + --------------------------------------------------------------- + null; + + end case; + end if; + end if; + end process; + + process(clk, areset_n) + begin + if (areset_n = '0') then + symbolControlRestart <= '0'; + symbolControlLinkRequest <= '0'; + symbolControlStart <= '0'; + symbolControlEnd <= '0'; + symbolData <= '0'; + symbolDataContent <= (others => '0'); + elsif (clk'event and clk = '1') then + if (enable = '1') then + symbolControlRestart <= symbolControlRestartOut; + symbolControlLinkRequest <= symbolControlLinkRequestOut; + symbolControlStart <= symbolControlStartOut; + symbolControlEnd <= symbolControlEndOut; + symbolData <= symbolDataOut; + symbolDataContent <= symbolDataContentOut; + end if; + end if; + end process; + + ----------------------------------------------------------------------------- + -- Third pipeline stage. + -- Create the stype0 and stype1 part of a control symbol. + -- 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: operational_o, + -- symbolControl, stype0, parameter0, parameter1, stype1, cmd + ----------------------------------------------------------------------------- + + rxControlUpdate_o <= rxControlUpdateOut and enable; + + symbolControlStype1 <= + symbolControlRestart or symbolControlLinkRequest or + symbolControlStart or symbolControlEnd; + + process(linkInitialized_i, ackIdStatus_i, portInitialized_i, + operational_i, statusCounter_i, statusReceived_i, + rxControlEmpty_i, + sendStatusRequired, + symbolControlStype1, symbolData, + rxControlStype0, rxControlParameter0, rxControlParameter1, + fatalError_i) + begin + operational_o <= operational_i; + statusCounter_o <= statusCounter_i; + + rxControlUpdateOut <= '0'; + + controlValidOut <= '0'; + stype0Out <= STYPE0_STATUS; + parameter0Out <= ackIdStatus_i; + parameter1Out <= "11111"; + + if (fatalError_i = '1') then + -- Reset when a fatal error occurrs. + operational_o <= '0'; + statusCounter_o <= NUMBER_STATUS_TRANSMIT; + 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(statusCounter_i) = 0)) then + -- Receiver has received enough error free status symbols and we + -- have transmitted enough. + + -- Considder ourselfs operational. + operational_o <= '1'; + end if; + + -- Check if a status symbol should be transmitted. + if (sendStatusRequired = '1') then + -- A status symbol should be transmitted. + + -- Send a status control symbol to the link partner. + controlValidOut <= '1'; + + -- Check if the number of transmitted statuses should be updated. + if (statusReceived_i = '1') and (unsigned(statusCounter_i) /= 0) then + statusCounter_o <= std_logic_vector(unsigned(statusCounter_i) - 1); + end if; + end if; + else + -- The port is not initialized. + -- Reset initialization variables. + operational_o <= '0'; + statusCounter_o <= NUMBER_STATUS_TRANSMIT; + 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 any dataSymbol is about to be sent. + if (symbolData = '0') then + -- No pending data symbol. + + -- Check if there is a pending control-symbol from the receiver. + if (rxControlEmpty_i = '1') then + -- No pending control-symbol from the receiver. + + -- Check if there is a pending control-symbol from ourselfs. + if (symbolControlStype1 = '0') then + -- No pending control-symbol from ourselfs. + + -- Check if we need to send a status-control-symbol. + if (sendStatusRequired = '0') then + -- Not required to send a status-control-symbol. + -- Don't send anything. + else + -- Required to send a status-control-symbol. + -- Indicate a status-control-symbol is ready. + controlValidOut <= '1'; + end if; + else + -- Pending control-symbol from ourselfs. + -- Send it and reset the counter since a status-control-symbol + -- will be combined with it. + controlValidOut <= '1'; + end if; + else + -- Pending control-symbol from the receiver. + -- If there is a pending control-symbol from ourselfs they will be + -- combined. + + -- Remove the control-symbol from the fifo. + rxControlUpdateOut <= '1'; + + -- Send the receiver symbol. + controlValidOut <= '1'; + stype0Out <= rxControlStype0; + parameter0Out <= rxControlParameter0; + parameter1Out <= rxControlParameter1; + end if; + else + -- Pending data symbol. + -- Send the data symbol. + end if; + else + -- The port is not initialized anymore. + -- Change the operational state. + operational_o <= '0'; + statusCounter_o <= NUMBER_STATUS_TRANSMIT; + end if; + end if; + end if; + end process; + + process(clk, areset_n) + begin + if (areset_n = '0') then + dataValid <= '0'; + dataContent <= (others=>'0'); + + controlValid <= '0'; + stype0 <= (others=>'0'); + parameter0 <= (others=>'0'); + parameter1 <= (others=>'0'); + stype1 <= (others=>'0'); + cmd <= (others=>'0'); + elsif (clk'event and clk = '1') then + if (enable = '1') then + dataValid <= symbolData; + dataContent <= symbolDataContent; + + controlValid <= controlValidOut; + stype0 <= stype0Out; + parameter0 <= parameter0Out; + parameter1 <= parameter1Out; + if (symbolControlStart = '1') then + stype1 <= STYPE1_START_OF_PACKET; + cmd <= "000"; + elsif (symbolControlEnd = '1') then + stype1 <= STYPE1_END_OF_PACKET; + cmd <= "000"; + elsif (symbolControlRestart = '1') then + stype1 <= STYPE1_RESTART_FROM_RETRY; + cmd <= "000"; + elsif (symbolControlLinkRequest = '1') then + stype1 <= STYPE1_LINK_REQUEST; + cmd <= LINK_REQUEST_CMD_INPUT_STATUS; + else + stype1 <= STYPE1_NOP; + cmd <= "000"; + end if; + end if; + end if; + end process; + + ----------------------------------------------------------------------------- + -- Fourth pipeline stage. + -- Make all symbols ready for transmission, i.e. calculate the CRC5 on + -- control symbols and choose which symbol to send. + -- Inputs: controlValid, stype0, parameter0, parameter1, stype1, cmd + ----------------------------------------------------------------------------- + + process(clk, areset_n) + begin + if (areset_n = '0') then + sendStatusRequired <= '0'; + symbolCounter <= (others=>'0'); + elsif (clk'event and clk = '1') then + if (enable = '1') then + if (portInitialized_i = '0') then + sendStatusRequired <= '0'; + symbolCounter <= + std_logic_vector(to_unsigned(TICKS_SEND_STATUS_STARTUP, + SYMBOL_COUNTER_WIDTH)); + elsif (enable = '1') then + -- REMARK: Rewrite this, the status-control-symbols are output with a + -- slightly longer period than required... + if ((controlValid = '1') and + ((stype0 = STYPE0_STATUS) or + (stype0 = STYPE0_PACKET_ACCEPTED) or + (stype0 = STYPE0_PACKET_RETRY))) then + if (operational_i = '0') then + symbolCounter <= + std_logic_vector(to_unsigned(TICKS_SEND_STATUS_STARTUP, + SYMBOL_COUNTER_WIDTH)); + else + symbolCounter <= + std_logic_vector(to_unsigned(TICKS_SEND_STATUS_OPERATIONAL, + SYMBOL_COUNTER_WIDTH)); + end if; + else + if (unsigned(symbolCounter) = 0) then + sendStatusRequired <= '1'; + symbolCounter <= std_logic_vector(unsigned(symbolCounter) - 1); + else + sendStatusRequired <= '0'; + symbolCounter <= std_logic_vector(unsigned(symbolCounter) - 1); + end if; + end if; + end if; + end if; + end if; + end process; + + controlContent(23 downto 21) <= stype0; + controlContent(20 downto 16) <= parameter0; + controlContent(15 downto 11) <= parameter1; + controlContent(10 downto 8) <= stype1; + controlContent(7 downto 5) <= cmd; + controlContent(4 downto 0) <= crc5; + + Crc5Calculator: Crc5ITU + port map( + d_i=>controlContent(23 downto 5), crc_o=>crc5); + + process(clk, areset_n) + begin + if (areset_n = '0') then + outboundControlValid_o <= '0'; + outboundControlSymbol_o <= (others=>'0'); + outboundDataValid_o <= '0'; + outboundDataSymbol_o <= (others=>'0'); + elsif (clk'event and clk = '1') then + if (enable = '1') then + outboundControlValid_o <= controlValid; + outboundControlSymbol_o <= controlContent; + outboundDataValid_o <= dataValid; + outboundDataSymbol_o <= dataContent; + end if; + end if; + end process; + +end architecture; + + + +------------------------------------------------------------------------------- +-- RioReciever. +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- Entity for RioReceiver. +------------------------------------------------------------------------------- +entity RioReceiver is + generic( + NUMBER_SYMBOLS : natural range 1 to 1 := 1); + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + portEnable_i : in std_logic; + + 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; + inboundControlValid_i : in std_logic; + inboundControlSymbol_i : in std_logic_vector(23 downto 0); + inboundDataValid_i : in std_logic; + inboundDataSymbol_i : in std_logic_vector(31 downto 0); + + txControlWrite_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + txControlSymbol_o : out std_logic_vector(12*NUMBER_SYMBOLS downto 0); + rxControlWrite_o : out std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + rxControlSymbol_o : out std_logic_vector(12*NUMBER_SYMBOLS downto 0); + + ackIdStatus_o : out std_logic_vector(4 downto 0); + linkInitialized_o : out std_logic; + + 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(32*NUMBER_SYMBOLS-1 downto 0)); +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for RioReceiver. +------------------------------------------------------------------------------- +architecture RioReceiverImpl of RioReceiver is + + component RioReceiverCore is + generic( + NUMBER_SYMBOLS : natural range 1 to 1 := 1); + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + -- Status signals used for maintenance. + portEnable_i : in std_logic; + + -- 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; + inboundControlValid_i : in std_logic; + inboundControlSymbol_i : in std_logic_vector(23 downto 0); + inboundDataValid_i : in std_logic; + inboundDataSymbol_i : in std_logic_vector(31 downto 0); + + -- 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); + + -- Receiver wants to signal the link partner: + -- a new frame has been accepted => packet-accepted(rxAckId, bufferStatus) + -- a frame needs to be retransmitted due to buffering => + -- packet-retry(rxAckId, bufferStatus) + -- 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. + 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); + 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; + writeContentData_o : out std_logic_vector(32*NUMBER_SYMBOLS-1 downto 0)); + end component; + + signal operationalCurrent, operationalNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal inputRetryStoppedCurrent, inputRetryStoppedNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal inputErrorStoppedCurrent, inputErrorStoppedNext : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal ackIdCurrent, ackIdNext : unsigned(5*NUMBER_SYMBOLS-1 downto 0); + signal frameIndexCurrent, frameIndexNext : std_logic_vector(7*NUMBER_SYMBOLS-1 downto 0); + signal crcCurrent, crcNext : std_logic_vector(16*NUMBER_SYMBOLS-1 downto 0); + + signal txControlWrite : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + signal rxControlWrite : std_logic_vector(NUMBER_SYMBOLS-1 downto 0); + +begin + + ----------------------------------------------------------------------------- + -- 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'); + crcCurrent <= (others=>'0'); + elsif (clk'event and clk = '1') then + if (enable = '1') then + operationalCurrent <= operationalNext; + inputRetryStoppedCurrent <= inputRetryStoppedNext; + inputErrorStoppedCurrent <= inputErrorStoppedNext; + ackIdCurrent <= ackIdNext; + frameIndexCurrent <= frameIndexNext; + crcCurrent <= crcNext; + end if; + end if; + end process; + + CoreGeneration: for i in 0 to NUMBER_SYMBOLS-1 generate + txControlWrite_o(i) <= txControlWrite(i); + rxControlWrite_o(i) <= rxControlWrite(i); + + ReceiverCore: RioReceiverCore + generic map(NUMBER_SYMBOLS=>NUMBER_SYMBOLS) + port map( + clk=>clk, + areset_n=>areset_n, + enable=>enable, + portEnable_i=>portEnable_i, + localAckIdWrite_i=>localAckIdWrite_i, + inboundAckId_i=>inboundAckId_i, + inboundAckId_o=>inboundAckId_o, + portInitialized_i=>portInitialized_i, + inboundControlValid_i=>inboundControlValid_i, + inboundControlSymbol_i=>inboundControlSymbol_i, + inboundDataValid_i=>inboundDataValid_i, + inboundDataSymbol_i=>inboundDataSymbol_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, + 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), + 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_o, + writeFrameAbort_o=>writeFrameAbort_o, + writeContent_o=>writeContent_o, + writeContentData_o=>writeContentData_o(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_SYMBOLS : natural range 1 to 1 := 1); + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + -- Status signals used for maintenance. + portEnable_i : in std_logic; + + -- 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; + inboundControlValid_i : in std_logic; + inboundControlSymbol_i : in std_logic_vector(23 downto 0); + inboundDataValid_i : in std_logic; + inboundDataSymbol_i : in std_logic_vector(31 downto 0); + + -- 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. + 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); + 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; + writeContentData_o : out std_logic_vector(32*NUMBER_SYMBOLS-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 crc5 : std_logic_vector(4 downto 0); + signal crc5Valid : std_logic; + signal symbolErrorValid0 : std_logic; + signal symbolControlValid0 : std_logic; + signal symbolControlContent0 : std_logic_vector(23 downto 0); + signal symbolDataValid0 : std_logic; + signal symbolDataContent0 : std_logic_vector(31 downto 0); + + signal symbolErrorValid1 : std_logic; + signal symbolControlCrcValid1 : std_logic; + signal symbolControlValid1 : std_logic; + signal symbolControlContent1 : std_logic_vector(23 downto 0); + signal symbolDataValid1 : std_logic; + signal symbolDataContent1 : std_logic_vector(31 downto 0); + signal stype0Status : std_logic; + signal stype1Start : std_logic; + signal stype1End : std_logic; + signal stype1Stomp : std_logic; + signal stype1RestartFromRetry : std_logic; + signal stype1LinkRequest : std_logic; + + signal writeFrameOut : std_logic; + signal writeFrameAbortOut : std_logic; + signal writeContentOut : std_logic; + signal crc16Data : std_logic_vector(31 downto 0); + signal crc16Current : std_logic_vector(15 downto 0); + signal crc16Temp : std_logic_vector(15 downto 0); + signal crc16Next : std_logic_vector(15 downto 0); + signal crc16Valid : std_logic; + signal rxControlWriteOut : std_logic; + signal rxControlSymbolOut : 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. + ----------------------------------------------------------------------------- + + Crc5Calculator: Crc5ITU + port map(d_i=>inboundControlSymbol_i(23 downto 5), crc_o=>crc5); + + process(clk, areset_n) + begin + if (areset_n = '0') then + crc5Valid <= '0'; + symbolErrorValid0 <= '0'; + symbolControlValid0 <= '0'; + symbolControlContent0 <= (others=>'0'); + symbolDataValid0 <= '0'; + symbolDataContent0 <= (others=>'0'); + elsif (clk'event and clk = '1') then + if (enable = '1') then + if (crc5 = inboundControlSymbol_i(4 downto 0)) then + crc5Valid <= '1'; + else + crc5Valid <= '0'; + end if; + if (inboundControlValid_i = '1') and (inboundDataValid_i = '1') then + symbolErrorValid0 <= '1'; + symbolControlValid0 <= '0'; + symbolDataValid0 <= '0'; + else + symbolErrorValid0 <= '0'; + symbolControlValid0 <= inboundControlValid_i; + symbolControlContent0 <= inboundControlSymbol_i; + symbolDataValid0 <= inboundDataValid_i; + symbolDataContent0 <= inboundDataSymbol_i; + end if; + 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'); + + symbolErrorValid1 <= '0'; + + symbolControlCrcValid1 <= '0'; + symbolControlValid1 <= '0'; + symbolControlContent1 <= (others => '0'); + symbolDataValid1 <= '0'; + symbolDataContent1 <= (others=>'0'); + + stype0Status <= '0'; + stype1Start <= '0'; + stype1End <= '0'; + stype1Stomp <= '0'; + stype1RestartFromRetry <= '0'; + stype1LinkRequest <= '0'; + elsif (clk'event and clk = '1') then + if (enable = '1') then + symbolErrorValid1 <= symbolErrorValid0; + + symbolControlCrcValid1 <= crc5Valid; + symbolControlValid1 <= symbolControlValid0; + symbolControlContent1 <= symbolControlContent0; + symbolDataValid1 <= symbolDataValid0; + symbolDataContent1 <= symbolDataContent0; + + txControlWrite_o <= '0'; + txControlSymbol_o <= symbolControlContent0(23 downto 11); + + if (symbolControlValid0 = '1') then + if (crc5Valid = '1') then + -- Forward the part of the control-symbol that are targeted to the + -- transmitter. + txControlWrite_o <= '1'; + end if; + + if (symbolControlContent0(23 downto 21) = STYPE0_STATUS) then + stype0Status <= '1'; + else + stype0Status <= '0'; + end if; + if (symbolControlContent0(10 downto 8) = STYPE1_START_OF_PACKET) then + stype1Start <= '1'; + else + stype1Start <= '0'; + end if; + if (symbolControlContent0(10 downto 8) = STYPE1_END_OF_PACKET) then + stype1End <= '1'; + else + stype1End <= '0'; + end if; + if (symbolControlContent0(10 downto 8) = STYPE1_STOMP) then + stype1Stomp <= '1'; + else + stype1Stomp <= '0'; + end if; + if (symbolControlContent0(10 downto 8) = STYPE1_RESTART_FROM_RETRY) then + stype1RestartFromRetry <= '1'; + else + stype1RestartFromRetry <= '0'; + end if; + if (symbolControlContent0(10 downto 8) = STYPE1_LINK_REQUEST) then + stype1LinkRequest <= '1'; + else + stype1LinkRequest <= '0'; + end if; + else + txControlWrite_o <= '0'; + stype0Status <= '0'; + stype1Start <= '0'; + stype1End <= '0'; + stype1Stomp <= '0'; + stype1RestartFromRetry <= '0'; + stype1LinkRequest <= '0'; + end if; + 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. + ----------------------------------------------------------------------------- + + -- Create the new input depending on the current frame position. + crc16Data(31 downto 26) <= "000000" when (unsigned(frameIndex_i) = 1) else + symbolDataContent1(31 downto 26); + crc16Data(25 downto 0) <= symbolDataContent1(25 downto 0); + + -- Initialize the crc at frame start. + crc16Current <= crc_i when (unsigned(frameIndex_i) /= 1) else (others => '1'); + + -- Crc calculation units. + Crc16Msb: Crc16CITT + port map( + d_i=>crc16Data(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp); + Crc16Lsb: Crc16CITT + port map( + d_i=>crc16Data(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next); + + -- Save the new CRC value when a dataSymbol was received. + crc_o <= crc_i when (symbolDataValid1 = '0') else crc16Next; + + -- Check if the CRC is ok. + crc16Valid <= '1' when (crc_i = x"0000") else '0'; + + -- The main protocol handling process. + process(portInitialized_i, portEnable_i, writeFrameFull_i, + operational_i, ackId_i, frameIndex_i, + inputRetryStopped_i, inputErrorStopped_i, + symbolControlValid1, symbolControlCrcValid1, symbolControlContent1, + stype0Status, + stype1Start, stype1End, stype1Stomp, stype1RestartFromRetry, stype1LinkRequest, + symbolDataValid1, + crc16Valid) + begin + operational_o <= operational_i; + frameIndex_o <= frameIndex_i; + inputRetryStopped_o <= inputRetryStopped_i; + inputErrorStopped_o <= inputErrorStopped_i; + ackId_o <= ackId_i; + + rxControlWriteOut <= '0'; + rxControlSymbolOut <= (others => '0'); + + writeFrameOut <= '0'; + writeFrameAbortOut <= '0'; + writeContentOut <= '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 (symbolControlCrcValid1 = '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. + + -- Go to operational state and make sure all variables are + -- reset. + operational_o <= '1'; + frameIndex_o <= (others => '0'); + inputRetryStopped_o <= '0'; + inputErrorStopped_o <= '0'; + + -- Reset all packets. + writeFrameAbortOut <= '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 an error has been detected by the PCS. + if (symbolErrorValid1 = '1') then + -- An error-symbol from the PCS has been received. + -- Send a packet-not-accepted and indicate the error. + rxControlWriteOut <= '1'; + rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED & + "00000" & + PACKET_NOT_ACCEPTED_CAUSE_INVALID_CHARACTER; + inputErrorStopped_o <= '1'; + end if; + + -- Check if the control symbol has a valid CRC-5. + if (symbolControlCrcValid1 = '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. + + -- Check if the frame is large enough. + if (unsigned(frameIndex_i) > 3) then + -- The frame is large enough. + + -- Check the CRC-16 and the length of the received frame. + if (crc16Valid = '1') then + -- The CRC-16 is ok. + + -- Update the frame buffer to indicate that the frame has + -- been completly received. + writeFrameOut <= '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. + rxControlWriteOut <= '1'; + rxControlSymbolOut <= STYPE0_PACKET_ACCEPTED & + std_logic_vector(ackId_i) & + "11111"; + else + -- The CRC-16 is not ok. + + -- Make the transmitter send a packet-not-accepted to indicate + -- that the received packet contained a CRC error. + rxControlWriteOut <= '1'; + rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED & + "00000" & + PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC; + inputErrorStopped_o <= '1'; + end if; + else + -- This packet is too small. + -- Make the transmitter send a packet-not-accepted to indicated + -- that the received packet was too small. + rxControlWriteOut <= '1'; + rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED & + "00000" & + PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR; + inputErrorStopped_o <= '1'; + end if; + end if; + + -- Reset the frame index to indicate the frame is started. + frameIndex_o <= "0000001"; + 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. + + -- Check the CRC-16 and the length of the received frame. + if (crc16Valid = '1') then + -- The CRC-16 is ok. + + -- Update the frame buffer to indicate that the frame has + -- been completly received. + writeFrameOut <= '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. + rxControlWriteOut <= '1'; + rxControlSymbolOut <= STYPE0_PACKET_ACCEPTED & + std_logic_vector(ackId_i) & + "11111"; + else + -- The CRC-16 is not ok. + + -- Make the transmitter send a packet-not-accepted to indicate + -- that the received packet contained a CRC error. + rxControlWriteOut <= '1'; + rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED & + "00000" & + PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC; + inputErrorStopped_o <= '1'; + end if; + else + -- This packet is too small. + -- Make the transmitter send a packet-not-accepted to indicate + -- that the received packet was too small. + rxControlWriteOut <= '1'; + rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED & + "00000" & + PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR; + inputErrorStopped_o <= '1'; + end if; + + -- Reset frame reception to indicate that no frame is ongoing. + frameIndex_o <= "0000000"; + 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 2.2 standard. + + -- Make the transmitter send a packet-retry to indicate + -- that the packet cannot be accepted. + rxControlWriteOut <= '1'; + rxControlSymbolOut <= STYPE0_PACKET_RETRY & + std_logic_vector(ackId_i) & + "11111"; + + -- Enter the input retry-stopped state. + inputRetryStopped_o <= '1'; + end if; + + if (stype1RestartFromRetry = '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'); + writeFrameAbortOut <= '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 2.2 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. + rxControlWriteOut <= '1'; + rxControlSymbolOut <= 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 (symbolControlContent1(7 downto 5) = "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 + rxControlWriteOut <= '1'; + rxControlSymbolOut <= STYPE0_LINK_RESPONSE & + std_logic_vector(ackId_i) & + "00101"; + elsif (inputRetryStopped_i = '1') then + rxControlWriteOut <= '1'; + rxControlSymbolOut <= STYPE0_LINK_RESPONSE & + std_logic_vector(ackId_i) & + "00100"; + else + -- Send a link response containing an ok reply. + rxControlWriteOut <= '1'; + rxControlSymbolOut <= 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'); + writeFrameAbortOut <= '1'; + 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. + rxControlWriteOut <= '1'; + rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED & + "00000" & + PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC; + inputErrorStopped_o <= '1'; + end if; + + if ((symbolDataValid1 = '1') and + (inputRetryStopped_i = '0') and (inputErrorStopped_i = '0')) then + ------------------------------------------------------------- + -- This is a data symbol. + ------------------------------------------------------------- + -- REMARK: Add check for in-the-middle-crc here... + + case frameIndex_i is + when "0000000" | "1000110" => + -- A frame has not been started or is too long. + -- Send packet-not-accepted. + rxControlWriteOut <= '1'; + rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED & + "00000" & + PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR; + inputErrorStopped_o <= '1'; + when "0000001" => + -- Check if the packet contains the correct ackId. + if (unsigned(symbolDataContent1(31 downto 27)) = ackId_i) then + -- The packet has a correct ackId. + + -- Check if the packet is allowed. + if ((portEnable_i = '1') or + (symbolDataContent1(19 downto 16) = FTYPE_MAINTENANCE_CLASS)) then + -- The packet is allowed. + + -- Check if there are buffers available to store the new + -- packet. + if (writeFrameFull_i = '0') then + -- There are buffering space available to store the new + -- data. + + -- Write the symbol content and increment the number of + -- received data symbols. + writeContentOut <= '1'; + frameIndex_o <= std_logic_vector(unsigned(frameIndex_i) + 1); + else + -- The packet buffer is full. + -- Let the link-partner resend the packet. + rxControlWriteOut <= '1'; + rxControlSymbolOut <= STYPE0_PACKET_RETRY & + std_logic_vector(ackId_i) & + "11111"; + inputRetryStopped_o <= '1'; + end if; + else + -- A non-maintenance packet is not allowed. + -- Send packet-not-accepted. + rxControlWriteOut <= '1'; + rxControlSymbolOut <= 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. + rxControlWriteOut <= '1'; + rxControlSymbolOut <= STYPE0_PACKET_NOT_ACCEPTED & + "00000" & + PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID; + inputErrorStopped_o <= '1'; + end if; + when others => + -- A frame has been started and is not too long. + -- Check if the buffer entry is ready to be written + -- into the packet buffer. + writeContentOut <= '1'; + + -- Increment the number of received data symbols. + frameIndex_o <= std_logic_vector(unsigned(frameIndex_i) + 1); + end case; + end if; + else + -- The port has become uninitialized. + -- Go back to the uninitialized state. + operational_o <= '0'; + end if; + end if; + end process; + + process(clk, areset_n) + begin + if (areset_n = '0') then + rxControlWrite_o <= '0'; + rxControlSymbol_o <= (others=>'0'); + writeFrame_o <= '0'; + writeFrameAbort_o <= '0'; + writeContent_o <= '0'; + writeContentData_o <= (others=>'0'); + elsif (clk'event and clk = '1') then + if (enable = '1') then + rxControlWrite_o <= rxControlWriteOut and (symbolControlValid1 or symbolDataValid1); + rxControlSymbol_o <= rxControlSymbolOut; + writeFrame_o <= writeFrameOut; + writeFrameAbort_o <= writeFrameAbortOut; + writeContent_o <= writeContentOut; + writeContentData_o <= symbolDataContent1; + 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 RioFifo is + generic( + DEPTH_WIDTH : natural; + DATA_WIDTH : natural); + port( + clk : in std_logic; + areset_n : in std_logic; + enable : 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 writeEnable : 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 (enable = '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 if; + end process; + + writeEnable <= enable and write_i; + + Memory: MemorySimpleDualPortAsync + generic map(ADDRESS_WIDTH=>DEPTH_WIDTH, + DATA_WIDTH=>DATA_WIDTH, + INIT_VALUE=>'0') + port map( + clkA_i=>clk, enableA_i=>writeEnable, + 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;
branches/2.0.0-development/rtl/vhdl/RioSerial.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: branches/2.0.0-development/rtl/vhdl/RioWbBridge.vhd =================================================================== --- branches/2.0.0-development/rtl/vhdl/RioWbBridge.vhd (nonexistent) +++ branches/2.0.0-development/rtl/vhdl/RioWbBridge.vhd (revision 41) @@ -0,0 +1,1394 @@ +------------------------------------------------------------------------------- +-- +-- 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, NWRITER and NREAD are currently supported. +-- +-- 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 +-- +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- RioWbBridge. +------------------------------------------------------------------------------- +-- REMARK: Add support for EXTENDED_ADDRESS... +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( + EXTENDED_ADDRESS : natural range 0 to 2 := 0; + 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; + + 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); + + cyc_o : out std_logic; + stb_o : out std_logic; + we_o : out std_logic; + adr_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0); + sel_o : out std_logic_vector(7 downto 0); + dat_o : out std_logic_vector(63 downto 0); + dat_i : in std_logic_vector(63 downto 0); + err_i : in std_logic; + ack_i : in std_logic); +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for RioWbBridge. +------------------------------------------------------------------------------- +architecture RioWbBridgeImpl of RioWbBridge is + + component RequestClassInbound is + generic( + EXTENDED_ADDRESS : natural range 0 to 2 := 0); + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + ready_o : out std_logic; + vc_o : out std_logic; + crf_o : out std_logic; + prio_o : out std_logic_vector(1 downto 0); + tt_o : out std_logic_vector(1 downto 0); + dstId_o : out std_logic_vector(31 downto 0); + srcId_o : out std_logic_vector(31 downto 0); + tid_o : out std_logic_vector(7 downto 0); + address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0); + length_o : out std_logic_vector(3 downto 0); + select_o : out std_logic_vector(7 downto 0); + done_i : in std_logic; + + slaveCyc_i : in std_logic; + slaveStb_i : in std_logic; + slaveAdr_i : in std_logic_vector(7 downto 0); + slaveDat_i : in std_logic_vector(31 downto 0); + slaveAck_o : out std_logic); + end component; + + component WriteClassInbound is + generic( + EXTENDED_ADDRESS : natural range 0 to 2 := 0); + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + ready_o : out std_logic; + vc_o : out std_logic; + crf_o : out std_logic; + prio_o : out std_logic_vector(1 downto 0); + tt_o : out std_logic_vector(1 downto 0); + dstId_o : out std_logic_vector(31 downto 0); + srcId_o : out std_logic_vector(31 downto 0); + tid_o : out std_logic_vector(7 downto 0); + address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0); + length_o : out std_logic_vector(3 downto 0); + select_o : out std_logic_vector(7 downto 0); + payloadSetFirst_i : in std_logic; + payloadSetNext_i : in std_logic; + payload_o : out std_logic_vector(31 downto 0); + done_i : in std_logic; + + slaveCyc_i : in std_logic; + slaveStb_i : in std_logic; + slaveAdr_i : in std_logic_vector(7 downto 0); + slaveDat_i : in std_logic_vector(31 downto 0); + slaveAck_o : out std_logic); + end component; + + component ResponseClassOutbound is + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + ready_i : in std_logic; + vc_i : in std_logic; + crf_i : in std_logic; + prio_i : in std_logic_vector(1 downto 0); + tt_i : in std_logic_vector(1 downto 0); + dstid_i : in std_logic_vector(31 downto 0); + srcid_i : in std_logic_vector(31 downto 0); + tid_i : in std_logic_vector(7 downto 0); + error_i : in std_logic; + payloadPresent_i : in std_logic; + payloadLength_i : in std_logic_vector(3 downto 0); + payloadWrite_i : in std_logic; + payloadIndex_i : in std_logic_vector(3 downto 0); + payload_i : in std_logic_vector(31 downto 0); + done_o : out std_logic; + + masterCyc_o : out std_logic; + masterStb_o : out std_logic; + masterDat_o : out std_logic_vector(31 downto 0); + masterAck_i : in std_logic); + end component; + + component RioLogicalCommon is + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + 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); + + masterCyc_o : out std_logic; + masterStb_o : out std_logic; + masterAdr_o : out std_logic_vector(7 downto 0); + masterDat_o : out std_logic_vector(31 downto 0); + masterAck_i : in std_logic; + + slaveCyc_i : in std_logic; + slaveStb_i : in std_logic; + slaveDat_i : in std_logic_vector(31 downto 0); + slaveAck_o : out std_logic); + end component; + +-- signal configStb : std_logic; +-- signal configWe : std_logic; +-- signal configAdr : std_logic_vector(23 downto 0); +-- signal configDatWrite : std_logic_vector(31 downto 0); +-- signal configDatRead : std_logic_vector(31 downto 0); +-- signal configAck : std_logic; + +-- 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 + + ----------------------------------------------------------------------------- + -- + ----------------------------------------------------------------------------- + adr_o <= adr; + dat_o <= datOut; + + Bridge: process(clk, areset_n) + begin + if (areset_n = '0') then + cyc_o <= '0'; + stb_o <= '0'; + we_o <= '0'; + adr <= (others=>'0'); + datOut <= (others=>'0'); + + responseReadReady <= '0'; + responseWriteReady <= '0'; + responsePayloadWrite <= '0'; + + requestDone <= '0'; + + requestPayloadIndex <= (others=>'0'); + elsif (clk'event and clk = '1') then + requestDone <= '0'; + responsePayloadWrite <= '0'; + + if (responsePayloadWrite = '1') then + responsePayloadIndex <= std_logic_vector(unsigned(responsePayloadIndex) + 1); + end if; + + case state is + when IDLE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (requestReady = '1') then + cyc_o <= '1'; + stb_o <= '1'; + we_o <= '0'; + adr <= requestAddress; + responsePayloadPresent <= '1'; + state <= REQUEST_CLASS; + elsif (writeReady = '1') then + cyc_o <= '1'; + stb_o <= '1'; + we_o <= '1'; + adr <= writeAddress; + datOut <= writePayload; + writePayloadNext <= '1'; + responsePayloadPresent <= '0'; + state <= WRITE_CLASS; + end if; + + when REQUEST_CLASS => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (ack_i = '1') then + responsePayloadWrite <= '1'; + + if (responsePayloadIndex /= requestPayloadLength) then + adr <= std_logic_vector(unsigned(adr) + 1); + else + requestDone <= '1'; + cyc_o <= '0'; + stb_o <= '0'; + state <= NREAD_RESPONSE; + end if; +-- elsif(err_i = '1') then +-- REMARK: Implement error indication from wb-bus... + end if; + + when REQUEST_CLASS_RESPONSE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (responseDone = '1') then + responseReadReady <= '0'; + state <= IDLE; + else + responseReadReady <= '1'; + end if; + + when WRITE_CLASS => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (ack_i = '1') then + responsePayloadWrite <= '1'; + + if (responsePayloadIndex /= requestPayloadLength) then + adr <= std_logic_vector(unsigned(configAdr) + 1); + datOut <= writePayload; + requestPayloadIndex <= std_logic_vector(unsigned(requestPayloadIndex) + 1); + else + writeDone <= '1'; + cyc_o <= '0'; + stb_o <= '0'; + state <= WRITE_CLASS_RESPONSE; + end if; + end if; + + when WRITE_CLASS_RESPONSE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (responseDone = '1') then + responseWriteReady <= '0'; + state <= IDLE; + else + responseWriteReady <= '1'; + end if; + + when others => + + end case; + end if; + end process; + + ----------------------------------------------------------------------------- + -- + ----------------------------------------------------------------------------- + + RequestClassInboundInst: RequestClassInbound + generic map( + EXTENDED_ADDRESS=>EXTENDED_ADDRESS) + port map( + clk=>clk, + areset_n=>areset_n, + enable=>enable, + ready_o=>requestReady, + vc_o=>requestVc, + crf_o=>requestCrf, + prio_o=>requestPrio, + tt_o=>requestTt, + dstId_o=>requestDstId, + srcId_o=>requestSrcId, + tid_o=>requestTid, + address_o=>requestAddress, + length_o=>requestPayloadLength, + select_o=>requestSelect, + done_i=>requestDone, + slaveCyc_i=>inboundCyc, + slaveStb_i=>inboundStb, + slaveAdr_i=>inboundAdr, + slaveDat_i=>inboundDat, + slaveAck_o=>inboundAck); + + WriteClassInboundInst: WriteClassInbound + generic map( + EXTENDED_ADDRESS=>EXTENDED_ADDRESS) + port map( + clk=>clk, + areset_n=>areset_n, + enable=>enable, + ready_o=>writeReady, + vc_o=>writeVc, + crf_o=>writeCrf, + prio_o=>writePrio, + tt_o=>writeTt, + dstId_o=>writeDstId, + srcId_o=>writeSrcId, + tid_o=>writeTid, + address_o=>writeAddress, + length_o=>writeLength, + select_o=>writeSelect, + payloadSetFirst_i=>writePayloadFirst, + payloadSetNext_i=>writePayloadNext, + payload_o=>writePayload, + done_i=>writeDone, + slaveCyc_i=>inboundCyc_i, + slaveStb_i=>inboundStb_i, + slaveAdr_i=>inboundAdr_i, + slaveDat_i=>inboundDat_i, + slaveAck_o=>inboundAck_o); + + ResponseClassOutboundInst: ResponseClassOutbound + port map( + clk=>clk, + areset_n=>areset_n, + enable=>enable, + ready_i=>responseReady, + vc_i=>vc, + crf_i=>crf, + prio_i=>prio, + tt_i=>tt, + dstid_i=>srcid, + srcid_i=>dstid, + tid_i=>tid, + error_i=>responseError, + payloadPresent_i=>responsePayloadPresent, + payloadLength_i=>responsePayloadLength, + payloadWrite_i=>responsePayloadWrite, + payloadIndex_i=>responsePayloadIndex, + payload_i=>responsePayload, + done_o=>responseDone, + masterCyc_o=>outboundCyc, + masterStb_o=>outboundStb, + masterDat_o=>outboundDat, + masterAck_i=>outboundAck); + + RioLogicalCommonInst: RioLogicalCommon + port map( + clk=>clk, + areset_n=>areset_n, + enable=>enable, + readFrameEmpty_i=>readFrameEmpty_i, + readFrame_o=>readFrame_o, + readContent_o=>readContent_o, + readContentEnd_i=>readContentEnd_i, + readContentData_i=>readContentData_i, + writeFrameFull_i=>writeFrameFull_i, + writeFrame_o=>writeFrame_o, + writeFrameAbort_o=>writeFrameAbort_o, + writeContent_o=>writeContent_o, + writeContentData_o=>writeContentData_o, + masterCyc_o=>inboundCyc, + masterStb_o=>inboundStb, + masterAdr_o=>inboundAdr, + masterDat_o=>inboundDat, + masterAck_i=>inboundAck, + slaveCyc_i=>outboundCyc, + slaveStb_i=>outboundStb, + slaveDat_i=>outboundDat, + slaveAck_o=>outboundAck); + + ----------------------------------------------------------------------------- + -- 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; + +end architecture; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +-- REMARK: Extended addresses are not supported yet... +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +entity RequestClassInbound is + generic( + EXTENDED_ADDRESS : natural range 0 to 2 := 0); + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + ready_o : out std_logic; + vc_o : out std_logic; + crf_o : out std_logic; + prio_o : out std_logic_vector(1 downto 0); + tt_o : out std_logic_vector(1 downto 0); + dstId_o : out std_logic_vector(31 downto 0); + srcId_o : out std_logic_vector(31 downto 0); + tid_o : out std_logic_vector(7 downto 0); + address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0); + length_o : out std_logic_vector(3 downto 0); + select_o : out std_logic_vector(7 downto 0); + done_i : in std_logic; + + slaveCyc_i : in std_logic; + slaveStb_i : in std_logic; + slaveAdr_i : in std_logic_vector(7 downto 0); + slaveDat_i : in std_logic_vector(31 downto 0); + slaveAck_o : out std_logic); +end entity; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +architecture RequestClassInbound of RequestClassInbound is + type StateType is (RECEIVE_PACKET, READY); + signal state : StateType; + + signal rdsize : std_logic_vector(3 downto 0); + signal wdptr : std_logic; + + signal slaveAck : std_logic; + signal complete : std_logic; + + signal packetIndex : natural range 0 to 68; + +begin + + slaveAck_o <= slaveAck; + + ready_o <= complete when (state = READY) else '0'; + + RequestClass: process(clk, areset_n) + begin + if (areset_n = '0') then + slaveAck <= '0'; + + complete <= '0'; + + vc_o <= '0'; + crf_o <= '0'; + prio_o <= "00"; + tt_o <= "00"; + address_o <= (others=>'0'); + + rdsize <= (others=>'0'); + wdptr <= '0'; + + packetIndex <= 0; + elsif (clk'event and clk = '1') then + case state is + when RECEIVE_PACKET => + --------------------------------------------------------------------- + -- This state waits for a new REQUEST class packet, receives it + -- and parses it. + --------------------------------------------------------------------- + if (slaveCyc_i = '1') then + if (slaveAck = '0') then + if (slaveStb_i = '1') then + if (slaveAdr_i = x"24") then + ------------------------------------------------------------- + -- NREAD packet parser. + ------------------------------------------------------------- + case (packetIndex) is + when 0 => + -- x"0000" & ackid & vc & crf & prio & tt & ftype + vc_o <= slaveDat_i(9); + crf_o <= slaveDat_i(8); + prio_o <= slaveDat_i(7 downto 6); + tt_o <= slaveDat_i(5 downto 4); + packetIndex <= packetIndex + 1; + when 1 => + -- dstid + dstId_o <= slaveDat_i; + packetIndex <= packetIndex + 1; + when 2 => + -- srcid + srcId_o <= slaveDat_i; + packetIndex <= packetIndex + 1; + when 3 => + -- transaction(3:0) & rdsize(3:0) & srcTID(7:0) & address(28:13) + -- REMARK: Add support for extended addresses here... + rdsize <= slaveDat_i(27 downto 24); + tid_o <= slaveDat_i(23 downto 16); + address_o(28 downto 13) <= slaveDat_i(15 downto 0); + packetIndex <= packetIndex + 1; + when 4 => + -- address(12:0) & wdptr & xamsbs(1:0) & crc(15:0) + address_o(12 downto 0) <= slaveDat_i(31 downto 19); + wdptr <= slaveDat_i(18); + address_o(30 downto 29) <= slaveDat_i(17 downto 16); + packetIndex <= packetIndex + 1; + complete <= '1'; + when others => + -- There should be no more content in an NREAD. + -- Discard. + end case; + end if; + slaveAck <= '1'; + end if; + else + slaveAck <= '0'; + end if; + else + if (complete = '1') then + state <= READY; + end if; + packetIndex <= 0; + end if; + + when READY => + --------------------------------------------------------------------- + -- Wait for the handler of the packet to signal that it has been + -- processed. + --------------------------------------------------------------------- + if (done_i = '1') then + complete <= '0'; + state <= RECEIVE_PACKET; + end if; + + when others => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + + end case; + end if; + end process; + + ----------------------------------------------------------------------------- + -- Transformation of rdsize and wdptr into length of access and byte lanes. + ----------------------------------------------------------------------------- + + process(clk, areset_n) + begin + if (areset_n = '0') then + length_o <= 0; + select_o <= (others=>'0'); + elsif (clk'event and clk = '1') then + if (complete = '1') then + if (wdptr = '0') then + case rdsize is + when "0000" => + length_o <= 0; + select_o <= "10000000"; + when "0001" => + length_o <= 0; + select_o <= "01000000"; + when "0010" => + length_o <= 0; + select_o <= "00100000"; + when "0011" => + length_o <= 0; + select_o <= "00010000"; + when "0100" => + length_o <= 0; + select_o <= "11000000"; + when "0101" => + length_o <= 0; + select_o <= "11100000"; + when "0110" => + length_o <= 0; + select_o <= "00110000"; + when "0111" => + length_o <= 0; + select_o <= "11111000"; + when "1000" => + length_o <= 0; + select_o <= "11110000"; + when "1001" => + length_o <= 0; + select_o <= "11111100"; + when "1010" => + length_o <= 0; + select_o <= "11111110"; + when "1011" => + length_o <= 0; + select_o <= "11111111"; + when "1100" => + length_o <= 3; + select_o <= "11111111"; + when "1101" => + length_o <= 11; + select_o <= "11111111"; + when "1110" => + length_o <= 19; + select_o <= "11111111"; + when others => + length_o <= 27; + select_o <= "11111111"; + end case; + else + case rdsize is + when "0000" => + length_o <= 0; + select_o <= "00001000"; + when "0001" => + length_o <= 0; + select_o <= "00000100"; + when "0010" => + length_o <= 0; + select_o <= "00000010"; + when "0011" => + length_o <= 0; + select_o <= "00000001"; + when "0100" => + length_o <= 0; + select_o <= "00001100"; + when "0101" => + length_o <= 0; + select_o <= "00000111"; + when "0110" => + length_o <= 0; + select_o <= "00000011"; + when "0111" => + length_o <= 0; + select_o <= "00011111"; + when "1000" => + length_o <= 0; + select_o <= "00001111"; + when "1001" => + length_o <= 0; + select_o <= "00111111"; + when "1010" => + length_o <= 0; + select_o <= "01111111"; + when "1011" => + length_o <= 1; + select_o <= "11111111"; + when "1100" => + length_o <= 7; + select_o <= "11111111"; + when "1101" => + length_o <= 15; + select_o <= "11111111"; + when "1110" => + length_o <= 23; + select_o <= "11111111"; + when others => + length_o <= 31; + select_o <= "11111111"; + end case; + end if; + end if; + end if; + end process; + +end architecture; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +-- REMARK: Support inbound data with full bandwidth, not just half... +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +entity WriteClassInbound is + generic( + EXTENDED_ADDRESS : natural range 0 to 2 := 0); + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + ready_o : out std_logic; + vc_o : out std_logic; + crf_o : out std_logic; + prio_o : out std_logic_vector(1 downto 0); + tt_o : out std_logic_vector(1 downto 0); + dstId_o : out std_logic_vector(31 downto 0); + srcId_o : out std_logic_vector(31 downto 0); + tid_o : out std_logic_vector(7 downto 0); + address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0); + length_o : out std_logic_vector(3 downto 0); + select_o : out std_logic_vector(7 downto 0); + payloadSetFirst_i : in std_logic; + payloadSetNext_i : in std_logic; + payload_o : out std_logic_vector(31 downto 0); + done_i : in std_logic; + + slaveCyc_i : in std_logic; + slaveStb_i : in std_logic; + slaveAdr_i : in std_logic_vector(7 downto 0); + slaveDat_i : in std_logic_vector(31 downto 0); + slaveAck_o : out std_logic); +end entity; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +architecture WriteClassInbound of WriteClassInbound is + component MemorySimpleDualPort + 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; + + type StateType is (RECEIVE_PACKET, READY); + signal state : StateType; + + signal wdptr : std_logic; + signal wrsize : std_logic_vector(3 downto 0); + + signal slaveAck : std_logic; + signal complete : std_logic; + + signal packetIndex : natural range 0 to 68; + signal requestData : std_logic_vector(31 downto 0); + + signal payloadIndex : std_logic_vector(4 downto 0); + signal memoryWrite : std_logic; + signal memoryAddress : std_logic_vector(4 downto 0); + signal memoryDataIn : std_logic_vector(63 downto 0); + +begin + + slaveAck_o <= slaveAck; + + ready_o <= complete when (state = READY) else '0'; + + WriteClass: process(clk, areset_n) + begin + if (areset_n = '0') then + slaveAck <= '0'; + + complete <= '0'; + + vc_o <= '0'; + crf_o <= '0'; + prio_o <= "00"; + tt_o <= "00"; + tid_o <= (others=>'0'); + + address_o <= (others=>'0'); + + wdptr <= '0'; + wrsize <= (others=>'0'); + + packetIndex <= 0; + + memoryWrite <= '0'; + memoryAddress <= (others=>'0'); + memoryDataIn <= (others=>'0'); + elsif (clk'event and clk = '1') then + case state is + when RECEIVE_PACKET => + --------------------------------------------------------------------- + -- This state waits for a new WRITE class packet, receives it + -- and parses it. + --------------------------------------------------------------------- + if (slaveCyc_i = '1') then + if (slaveAck = '0') then + if (slaveStb_i = '1') then + if (slaveAdr_i = x"55") then + ------------------------------------------------------------- + -- NWRITER packet parser. + ------------------------------------------------------------- + -- REMARK: Add support for NWRITE without response... + case (packetIndex) is + when 0 => + -- x"0000" & ackid & vc & crf & prio & tt & ftype + vc_o <= slaveDat_i(9); + crf_o <= slaveDat_i(8); + prio_o <= slaveDat_i(7 downto 6); + tt_o <= slaveDat_i(5 downto 4); + packetIndex <= packetIndex + 1; + when 1 => + -- destId + dstId_o <= slaveDat_i; + packetIndex <= packetIndex + 1; + when 2 => + -- srcId + srcId_o <= slaveDat_i; + packetIndex <= packetIndex + 1; + when 3 => + -- transaction & wrsize & srcTID & address(28:13) + -- REMARK: Add support for extended addresses here... + wrsize <= slaveDat_i(27 downto 24); + tid_o <= slaveDat_i(23 downto 16); + address_o(28 downto 13) <= slaveDat_i(15 downto 0); + packetIndex <= packetIndex + 1; + when 4 => + -- address(12:0) & wdptr & xamsbs(1:0) & double-word(63:48) + address_o(12 downto 0) <= slaveDat_i(31 downto 19); + wdptr <= slaveDat_i(18); + doubleWord(63 downto 48) <= slaveDat_i(15 downto 0); + packetIndex <= packetIndex + 1; + when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 33 | 35 | + 37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 59 | 61 | 63 | 65 | 67 => + -- double-word(47:16) + doubleWord(31 downto 16) <= slaveDat_i(15 downto 0); + packetIndex <= packetIndex + 1; + when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 | + 36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 => + -- double-word(15:0) & double-word(63:48) + doubleWord(63 downto 48) <= slaveDat_i(15 downto 0); + packetIndex <= packetIndex + 1; + + memoryWrite <= '1'; + memoryDataIn <= doubleWord(63 downto 16) & slaveDat_i(31 downto 16); + complete <= '1'; + when others => + -- There should be no more content in an NWRITE request. + -- Discard. + end case; + end if; + slaveAck <= '1'; + end if; + else + if (memoryWrite = '1') then + memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); + end if; + + memoryWrite <= '0'; + slaveAck <= '0'; + end if; + else + if (complete = '1') then + state <= READY; + end if; + packetIndex <= 0; + memoryAddress <= (others=>'0'); + end if; + + when READY => + --------------------------------------------------------------------- + -- Wait for the handler of the packet to signal that it has been + -- processed. + --------------------------------------------------------------------- + if (done_i = '1') then + complete <= '0'; + state <= RECEIVE_PACKET; + end if; + + when others => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + + end case; + end if; + end process; + + ----------------------------------------------------------------------------- + -- Transformation of wrsize and wdptr into length of access and byte lanes. + ----------------------------------------------------------------------------- + + process(clk, areset_n) + begin + if (areset_n = '0') then + length_o <= 0; + select_o <= (others=>'0'); + elsif (clk'event and clk = '1') then + if (complete = '1') then + if (wdptr = '0') then + case wrsize is + when "0000" => + length_o <= 0; + select_o <= "10000000"; + when "0001" => + length_o <= 0; + select_o <= "01000000"; + when "0010" => + length_o <= 0; + select_o <= "00100000"; + when "0011" => + length_o <= 0; + select_o <= "00010000"; + when "0100" => + length_o <= 0; + select_o <= "11000000"; + when "0101" => + length_o <= 0; + select_o <= "11100000"; + when "0110" => + length_o <= 0; + select_o <= "00110000"; + when "0111" => + length_o <= 0; + select_o <= "11111000"; + when "1000" => + length_o <= 0; + select_o <= "11110000"; + when "1001" => + length_o <= 0; + select_o <= "11111100"; + when "1010" => + length_o <= 0; + select_o <= "11111110"; + when "1011" => + length_o <= 0; + select_o <= "11111111"; + when others => + length_o <= memoryAddress; + select_o <= "11111111"; + end case; + else + case wrsize is + when "0000" => + length_o <= 0; + select_o <= "00001000"; + when "0001" => + length_o <= 0; + select_o <= "00000100"; + when "0010" => + length_o <= 0; + select_o <= "00000010"; + when "0011" => + length_o <= 0; + select_o <= "00000001"; + when "0100" => + length_o <= 0; + select_o <= "00001100"; + when "0101" => + length_o <= 0; + select_o <= "00000111"; + when "0110" => + length_o <= 0; + select_o <= "00000011"; + when "0111" => + length_o <= 0; + select_o <= "00011111"; + when "1000" => + length_o <= 0; + select_o <= "00001111"; + when "1001" => + length_o <= 0; + select_o <= "00111111"; + when "1010" => + length_o <= 0; + select_o <= "01111111"; + when others => + length_o <= memoryAddress; + select_o <= "11111111"; + end case; + end if; + end if; + end if; + end process; + + ----------------------------------------------------------------------------- + -- Payload content memory. + ----------------------------------------------------------------------------- + process(clk, areset_n) + begin + if (areset_n = '0') then + payloadIndex <= (others=>'0'); + elsif (clk'event and clk = '1') then + if (payloadSetFirst_i = '1') then + payloadIndex <= (others=>'0'); + elsif (payloadSetNext_i = '1') then + payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1); + end if; + end if; + end process; + + PayloadMemory: MemorySimpleDualPort + generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>64) + port map(clkA_i=>clk, + enableA_i=>memoryWrite, + addressA_i=>memoryAddress, + dataA_i=>memoryDataIn, + clkB_i=>clk, + enableB_i=>enable, + addressB_i=>payloadIndex, + dataB_o=>payload_o); + +end architecture; + + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +entity ResponseClassOutbound is + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + ready_i : in std_logic; + vc_i : in std_logic; + crf_i : in std_logic; + prio_i : in std_logic_vector(1 downto 0); + tt_i : in std_logic_vector(1 downto 0); + dstid_i : in std_logic_vector(31 downto 0); + srcid_i : in std_logic_vector(31 downto 0); + tid_i : in std_logic_vector(7 downto 0); + error_i : in std_logic; + payloadPresent_i : in std_logic; + payloadLength_i : in std_logic_vector(3 downto 0); + payloadWrite_i : in std_logic; + payloadIndex_i : in std_logic_vector(3 downto 0); + payload_i : in std_logic_vector(31 downto 0); + done_o : out std_logic; + + masterCyc_o : out std_logic; + masterStb_o : out std_logic; + masterDat_o : out std_logic_vector(31 downto 0); + masterAck_i : in std_logic); +end entity; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +architecture ResponseClassOutbound of ResponseClassOutbound is + component MemorySimpleDualPort + 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; + + type StateType is (WAIT_PACKET, + READ_RESPONSE, WRITE_RESPONSE, + WAIT_COMPLETE, RESPONSE_DONE); + signal state : StateType; + + signal packetIndex : natural range 0 to 65; + signal header : std_logic_vector(31 downto 0); + signal payload : std_logic_vector(63 downto 0); + signal payloadIndex : std_logic_vector(4 downto 0); + + signal memoryEnable : std_logic; + signal memoryAddress : std_logic_vector(4 downto 0); + signal memoryDataRead : std_logic_vector(63 downto 0); + +begin + + header <= x"0000" & "000000" & vc_i & crf_i & prio_i & tt_i & x"d"; + + Response: process(clk, areset_n) + begin + if (areset_n = '0') then + masterCyc_o <= '0'; + masterStb_o <= '0'; + + memoryEnable <= '0'; + memoryAddress <= (others=>'0'); + + payloadIndex <= (others=>'0'); + done_o <= '0'; + + state <= WAIT_PACKET; + elsif (clk'event and clk = '1') then + if (enable = '1') then + case state is + when WAIT_PACKET => + ------------------------------------------------------------------- + -- + ------------------------------------------------------------------- + if (ready_i = '1') then + masterCyc_o <= '1'; + masterStb_o <= '1'; + masterDat_o <= responseHeader; + + packetIndex <= 1; + + memoryEnable <= '1'; + memoryAddress <= (others=>'0'); + + payloadIndex <= (others=>'0'); + state <= SEND_RESPONSE; + end if; + + when SEND_RESPONSE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (masterAck_i = '1') then + case (packetIndex) is + when 1 => + -- destination + masterDat_o <= dstId_i; + packetIndex <= packetIndex + 1; + when 2 => + -- source + masterDat_o <= srcId_i; + packetIndex <= packetIndex + 1; + when 3 => + -- transaction & status & targetTID & double-word0(63:48) + if (error_i = '0') then + if (payloadPresent_i = '0') then + masterDat_o <= "0000" & "0000" & tid_i & x"0000"; + state <= WAIT_COMPLETE; + else + masterDat_o <= "1000" & "0000" & tid_i & memoryDataRead(63 downto 48);; + end if; + else + masterDat_o <= "0000" & "0111" & tid_i & x"0000"; + state <= WAIT_COMPLETE; + end if; + packetIndex <= packetIndex + 1; + when 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 | + 36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 => + -- double-wordN(47:16) + masterDat_o <= memoryDataRead(47 downto 16); + responsePayload <= memoryDataRead(15 downto 0); + memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); + packetIndex <= packetIndex + 1; + when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 33 | 35 | + 37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 59 | 61 | 63 | 65 | 67 => + -- double-wordN(15:0) & double-wordN(63:48) + masterDat_o <= responsePayload & memoryDataRead(31 downto 16); + packetIndex <= packetIndex + 1; + + responsePayloadIndex <= + std_logic_vector(unsigned(responsePayloadIndex) + 1); + + if (responsePayloadIndex = responsePayloadLength_i) then + state <= WAIT_COMPLETE; + else + packetIndex <= packetIndex + 1; + end if; + when others => + -- Unallowed response length. + -- Dont do anything. + end case; + end if; + + when WAIT_COMPLETE => + ------------------------------------------------------------------- + -- + ------------------------------------------------------------------- + if (masterAck_i = '1') then + masterCyc_o <= '0'; + masterStb_o <= '0'; + state <= RESPONSE_DONE; + end if; + + when RESPONSE_DONE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + memoryEnable <= '0'; + if (ready_i = '0') then + state <= WAIT_PACKET; + done_o <= '0'; + else + done_o <= '1'; + end if; + + when others => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + state <= WAIT_PACKET; + + end case; + end if; + end if; + end process; + + ----------------------------------------------------------------------------- + -- Payload content memory. + ----------------------------------------------------------------------------- + PayloadMemory: MemorySimpleDualPort + generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>64) + port map(clkA_i=>clk, + enableA_i=>payloadWrite_i, + addressA_i=>payloadIndex_i, + dataA_i=>payload_i, + clkB_i=>clk, + enableB_i=>memoryEnable, + addressB_i=>memoryAddress, + dataB_o=>memoryDataRead); + +end architecture;
branches/2.0.0-development/rtl/vhdl/RioWbBridge.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: branches/2.0.0-development/rtl/vhdl/RioLogicalMaintenance.vhd =================================================================== --- branches/2.0.0-development/rtl/vhdl/RioLogicalMaintenance.vhd (nonexistent) +++ branches/2.0.0-development/rtl/vhdl/RioLogicalMaintenance.vhd (revision 41) @@ -0,0 +1,944 @@ +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- Description +-- Contains a platform to build endpoints on. +-- +-- 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 +-- +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- RioLogicalMaintenance +-- This logical layer module handles ingress maintenance requests and converts +-- them into accesses on a Wishbone compatible bus accessing the configuration +-- space. +-- Addresses: 0x80 (maint read request) and 0x81 (maint write request). +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- Entity for RioLogicalMaintenance. +------------------------------------------------------------------------------- +entity RioLogicalMaintenance is + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + configStb_o : out std_logic; + configWe_o : out std_logic; + configAdr_o : out std_logic_vector(21 downto 0); + configDat_o : out std_logic_vector(31 downto 0); + configDat_i : in std_logic_vector(31 downto 0); + configAck_i : in std_logic; + + slaveCyc_i : in std_logic; + slaveStb_i : in std_logic; + slaveAdr_i : in std_logic_vector(7 downto 0); + slaveDat_i : in std_logic_vector(31 downto 0); + slaveAck_o : out std_logic; + + masterCyc_o : out std_logic; + masterStb_o : out std_logic; + masterDat_o : out std_logic_vector(31 downto 0); + masterAck_i : in std_logic); +end entity; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +architecture RioLogicalMaintenance of RioLogicalMaintenance is + + component MaintenanceRequestInbound is + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + requestReadReady_o : out std_logic; + requestWriteReady_o : out std_logic; + requestVc_o : out std_logic; + requestCrf_o : out std_logic; + requestPrio_o : out std_logic_vector(1 downto 0); + requestTt_o : out std_logic_vector(1 downto 0); + requestDstId_o : out std_logic_vector(31 downto 0); + requestSrcId_o : out std_logic_vector(31 downto 0); + requestTid_o : out std_logic_vector(7 downto 0); + requestOffset_o : out std_logic_vector(20 downto 0); + requestWdptr_o : out std_logic; + requestPayloadLength_o : out std_logic_vector(3 downto 0); + requestPayloadIndex_i : in std_logic_vector(3 downto 0); + requestPayload_o : out std_logic_vector(31 downto 0); + requestDone_i : in std_logic; + + slaveCyc_i : in std_logic; + slaveStb_i : in std_logic; + slaveAdr_i : in std_logic_vector(7 downto 0); + slaveDat_i : in std_logic_vector(31 downto 0); + slaveAck_o : out std_logic); + end component; + + component MaintenanceResponseOutbound is + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + responseReadReady_i : in std_logic; + responseWriteReady_i : in std_logic; + responseVc_i : in std_logic; + responseCrf_i : in std_logic; + responsePrio_i : in std_logic_vector(1 downto 0); + responseTt_i : in std_logic_vector(1 downto 0); + responseDstId_i : in std_logic_vector(31 downto 0); + responseSrcId_i : in std_logic_vector(31 downto 0); + responseTid_i : in std_logic_vector(7 downto 0); + responseWdptr_i : in std_logic; + responsePayloadLength_i : in std_logic_vector(3 downto 0); + responsePayloadWrite_i : in std_logic; + responsePayloadIndex_i : in std_logic_vector(3 downto 0); + responsePayload_i : in std_logic_vector(31 downto 0); + responseDone_o : out std_logic; + + masterCyc_o : out std_logic; + masterStb_o : out std_logic; + masterDat_o : out std_logic_vector(31 downto 0); + masterAck_i : in std_logic); + end component; + + type StateType is (IDLE, + CONFIG_READ, CONFIG_READ_RESPONSE, + CONFIG_WRITE, CONFIG_WRITE_RESPONSE); + signal state : StateType; + + 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 dstId : std_logic_vector(31 downto 0); + signal srcId : std_logic_vector(31 downto 0); + signal tid : std_logic_vector(7 downto 0); + signal wdptr : std_logic; + + signal configAdr : std_logic_vector(21 downto 0); + signal configDat : std_logic_vector(31 downto 0); + + signal requestReadReady : std_logic; + signal requestWriteReady : std_logic; + signal requestOffset : std_logic_vector(20 downto 0); + signal requestPayloadLength : std_logic_vector(3 downto 0); + signal requestPayloadIndex : std_logic_vector(3 downto 0); + signal requestPayload : std_logic_vector(31 downto 0); + signal requestDone : std_logic; + + signal responseReadReady : std_logic; + signal responseWriteReady : std_logic; + signal responsePayloadWrite : std_logic; + signal responsePayloadIndex : std_logic_vector(3 downto 0); + signal responseDone : std_logic; + +begin + + configAdr_o <= configAdr; + configDat_o <= configDat; + + ----------------------------------------------------------------------------- + -- + ----------------------------------------------------------------------------- + Maintenance: process(clk, areset_n) + begin + if (areset_n = '0') then + configStb_o <= '0'; + configWe_o <= '0'; + configAdr <= (others=>'0'); + configDat <= (others=>'0'); + + responseReadReady <= '0'; + responseWriteReady <= '0'; + responsePayloadWrite <= '0'; + + requestDone <= '0'; + + requestPayloadIndex <= (others=>'0'); + elsif (clk'event and clk = '1') then + requestDone <= '0'; + responsePayloadWrite <= '0'; + + if (responsePayloadWrite = '1') then + responsePayloadIndex <= std_logic_vector(unsigned(responsePayloadIndex) + 1); + end if; + + case state is + when IDLE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + responsePayloadIndex <= (others=>'0'); + if (requestReadReady = '1') then + configStb_o <= '1'; + configWe_o <= '0'; + configAdr <= requestOffset & wdptr; + state <= CONFIG_READ; + elsif (requestWriteReady = '1') then + configStb_o <= '1'; + configWe_o <= '1'; + configAdr <= requestOffset & wdptr; + configDat <= requestPayload; + requestPayloadIndex <= std_logic_vector(unsigned(requestPayloadIndex) + 1); + state <= CONFIG_WRITE; + else + responsePayloadIndex <= (others=>'0'); + requestPayloadIndex <= (others=>'0'); + end if; + + when CONFIG_READ => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (configAck_i = '1') then + responsePayloadWrite <= '1'; + + if (responsePayloadIndex /= requestPayloadLength) then + configAdr <= std_logic_vector(unsigned(configAdr) + 1); + else + requestDone <= '1'; + configStb_o <= '0'; + state <= CONFIG_READ_RESPONSE; + end if; + end if; + + when CONFIG_READ_RESPONSE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (responseDone = '1') then + responseReadReady <= '0'; + state <= IDLE; + else + responseReadReady <= '1'; + end if; + + when CONFIG_WRITE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (configAck_i = '1') then + responsePayloadWrite <= '1'; + + if (responsePayloadIndex /= requestPayloadLength) then + configAdr <= std_logic_vector(unsigned(configAdr) + 1); + configDat <= requestPayload; + requestPayloadIndex <= std_logic_vector(unsigned(requestPayloadIndex) + 1); + else + requestDone <= '1'; + configStb_o <= '0'; + state <= CONFIG_WRITE_RESPONSE; + end if; + end if; + + when CONFIG_WRITE_RESPONSE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (responseDone = '1') then + responseWriteReady <= '0'; + state <= IDLE; + else + responseWriteReady <= '1'; + end if; + + when others => + + end case; + end if; + end process; + + ----------------------------------------------------------------------------- + -- Request packet handler. + ----------------------------------------------------------------------------- + RequestInbound: MaintenanceRequestInbound + port map( + clk=>clk, + areset_n=>areset_n, + enable=>enable, + requestReadReady_o=>requestReadReady, + requestWriteReady_o=>requestWriteReady, + requestVc_o=>vc, + requestCrf_o=>crf, + requestPrio_o=>prio, + requestTt_o=>tt, + requestDstId_o=>dstId, + requestSrcId_o=>srcId, + requestTid_o=>tid, + requestOffset_o=>requestOffset, + requestWdptr_o=>wdptr, + requestPayloadLength_o=>requestPayloadLength, + requestPayloadIndex_i=>requestPayloadIndex, + requestPayload_o=>requestPayload, + requestDone_i=>requestDone, + slaveCyc_i=>slaveCyc_i, + slaveStb_i=>slaveStb_i, + slaveAdr_i=>slaveAdr_i, + slaveDat_i=>slaveDat_i, + slaveAck_o=>slaveAck_o); + + ----------------------------------------------------------------------------- + -- Response packet handler. + ----------------------------------------------------------------------------- + -- Note that the dstId and srcId is flipped since the response should be + -- returned to the source. + ResponseOutbound: MaintenanceResponseOutbound + port map( + clk=>clk, areset_n=>areset_n, enable=>enable, + responseReadReady_i=>responseReadReady, + responseWriteReady_i=>responseWriteReady, + responseVc_i=>vc, + responseCrf_i=>crf, + responsePrio_i=>prio, + responseTt_i=>tt, + responseDstId_i=>srcId, + responseSrcId_i=>dstId, + responseTid_i=>tid, + responseWdptr_i=>wdptr, + responsePayloadLength_i=>requestPayloadLength, + responsePayloadWrite_i=>responsePayloadWrite, + responsePayloadIndex_i=>responsePayloadIndex, + responsePayload_i=>configDat_i, + responseDone_o=>responseDone, + masterCyc_o=>masterCyc_o, + masterStb_o=>masterStb_o, + masterDat_o=>masterDat_o, + masterAck_i=>masterAck_i); + +end architecture; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +entity MaintenanceRequestInbound is + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + requestReadReady_o : out std_logic; + requestWriteReady_o : out std_logic; + requestVc_o : out std_logic; + requestCrf_o : out std_logic; + requestPrio_o : out std_logic_vector(1 downto 0); + requestTt_o : out std_logic_vector(1 downto 0); + requestDstId_o : out std_logic_vector(31 downto 0); + requestSrcId_o : out std_logic_vector(31 downto 0); + requestTid_o : out std_logic_vector(7 downto 0); + requestOffset_o : out std_logic_vector(20 downto 0); + requestWdptr_o : out std_logic; + requestPayloadLength_o : out std_logic_vector(3 downto 0); + requestPayloadIndex_i : in std_logic_vector(3 downto 0); + requestPayload_o : out std_logic_vector(31 downto 0); + requestDone_i : in std_logic; + + slaveCyc_i : in std_logic; + slaveStb_i : in std_logic; + slaveAdr_i : in std_logic_vector(7 downto 0); + slaveDat_i : in std_logic_vector(31 downto 0); + slaveAck_o : out std_logic); +end entity; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +architecture MaintenanceRequestInbound of MaintenanceRequestInbound is + component MemorySimpleDualPort + 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; + + type StateType is (RECEIVE_PACKET, READY); + signal state : StateType; + + signal wdptr : std_logic; + signal size : std_logic_vector(3 downto 0); + signal words : natural range 0 to 32; + + signal slaveAck : std_logic; + signal maintReadComplete : std_logic; + signal maintWriteComplete : std_logic; + + signal packetIndex : natural range 0 to 33; + signal requestData : std_logic_vector(31 downto 0); + + signal memoryWrite : std_logic; + signal memoryAddress : std_logic_vector(3 downto 0); + signal memoryDataIn : std_logic_vector(31 downto 0); + +begin + + slaveAck_o <= slaveAck; + + requestReadReady_o <= maintReadComplete when (state = READY) else '0'; + requestWriteReady_o <= maintWriteComplete when (state = READY) else '0'; + + MaintenanceRequest: process(clk, areset_n) + begin + if (areset_n = '0') then + slaveAck <= '0'; + + maintReadComplete <= '0'; + maintWriteComplete <= '0'; + + requestVc_o <= '0'; + requestCrf_o <= '0'; + requestPrio_o <= "00"; + requestTt_o <= "00"; + requestOffset_o <= (others=>'0'); + + wdptr <= '0'; + size <= (others=>'0'); + + packetIndex <= 0; + memoryWrite <= '0'; + memoryAddress <= (others=>'0'); + memoryDataIn <= (others=>'0'); + elsif (clk'event and clk = '1') then + case state is + when RECEIVE_PACKET => + --------------------------------------------------------------------- + -- This state waits for a new maintenance request packet, receives it + -- and parses it. + --------------------------------------------------------------------- + if (slaveCyc_i = '1') then + if (slaveAck = '0') then + if (slaveStb_i = '1') then + if (slaveAdr_i = x"80") then + ------------------------------------------------------------- + -- Maintenance Read Request packet parser. + ------------------------------------------------------------- + case (packetIndex) is + when 0 => + -- x"0000" & ackid & vc & crf & prio & tt & ftype + requestVc_o <= slaveDat_i(9); + requestCrf_o <= slaveDat_i(8); + requestPrio_o <= slaveDat_i(7 downto 6); + requestTt_o <= slaveDat_i(5 downto 4); + packetIndex <= packetIndex + 1; + when 1 => + -- destid + requestDstId_o <= slaveDat_i; + packetIndex <= packetIndex + 1; + when 2 => + -- srcid + requestSrcId_o <= slaveDat_i; + packetIndex <= packetIndex + 1; + when 3 => + -- transaction & rdsize & srcTID & hop & config_offset(20:13) + size <= slaveDat_i(27 downto 24); + requestTid_o <= slaveDat_i(23 downto 16); + requestOffset_o(20 downto 13) <= slaveDat_i(7 downto 0); + packetIndex <= packetIndex + 1; + when 4 => + -- config_offset(12:0) & wdptr & rsrv & crc(15:0) + requestOffset_o(12 downto 0) <= slaveDat_i(31 downto 19); + wdptr <= slaveDat_i(18); + packetIndex <= packetIndex + 1; + maintReadComplete <= '1'; + when others => + -- There should be no more content in a maintenance read request. + -- Discard. + end case; + elsif (slaveAdr_i = x"81") then + ------------------------------------------------------------- + -- Maintenance Write Request packet parser. + ------------------------------------------------------------- + case (packetIndex) is + when 0 => + -- x"0000" & ackid & vc & crf & prio & tt & ftype + requestVc_o <= slaveDat_i(9); + requestCrf_o <= slaveDat_i(8); + requestPrio_o <= slaveDat_i(7 downto 6); + requestTt_o <= slaveDat_i(5 downto 4); + packetIndex <= packetIndex + 1; + when 1 => + -- destId + requestDstId_o <= slaveDat_i; + packetIndex <= packetIndex + 1; + when 2 => + -- srcId + requestSrcId_o <= slaveDat_i; + packetIndex <= packetIndex + 1; + when 3 => + -- transaction & wrsize & srcTID & hop & config_offset(20:13) + size <= slaveDat_i(27 downto 24); + requestTid_o <= slaveDat_i(23 downto 16); + requestOffset_o(20 downto 13) <= slaveDat_i(7 downto 0); + packetIndex <= packetIndex + 1; + when 4 => + -- config_offset(12:0) & wdptr & rsrv & double-word(63:48) + requestOffset_o(12 downto 0) <= slaveDat_i(31 downto 19); + wdptr <= slaveDat_i(18); + requestData(31 downto 16) <= slaveDat_i(15 downto 0); + packetIndex <= packetIndex + 1; + when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 => + -- double-word(47:16) + requestData(31 downto 16) <= slaveDat_i(15 downto 0); + packetIndex <= packetIndex + 1; + + if (not ((size = "1000") and (wdptr = '1'))) then + memoryWrite <= '1'; + memoryDataIn <= requestData(31 downto 16) & slaveDat_i(31 downto 16); + end if; + when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 => + -- double-word(15:0) & double-word(63:48) + requestData(31 downto 16) <= slaveDat_i(15 downto 0); + packetIndex <= packetIndex + 1; + + memoryWrite <= '1'; + memoryDataIn <= requestData(31 downto 16) & slaveDat_i(31 downto 16); + maintWriteComplete <= '1'; + when others => + -- There should be no more content in a maintenance write request. + -- Discard. + end case; + end if; + slaveAck <= '1'; + end if; + else + if (memoryWrite = '1') then + memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); + end if; + + memoryWrite <= '0'; + slaveAck <= '0'; + end if; + else + if (maintReadComplete = '1') or (maintWriteComplete = '1') then + state <= READY; + end if; + packetIndex <= 0; + memoryAddress <= (others=>'0'); + end if; + + when READY => + --------------------------------------------------------------------- + -- Wait for the handler of the packet to signal that it has been + -- processed. + --------------------------------------------------------------------- + if (requestDone_i = '1') then + maintReadComplete <= '0'; + maintWriteComplete <= '0'; + state <= RECEIVE_PACKET; + end if; + + when others => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + + end case; + end if; + end process; + + ----------------------------------------------------------------------------- + -- Transformation of rdsize/wrsize into length of access and byte lanes. + ----------------------------------------------------------------------------- + + process(clk, areset_n) + begin + if (areset_n = '0') then + requestPayloadLength_o <= (others=>'0'); + requestWdptr_o <= '0'; + elsif (clk'event and clk = '1') then + if (maintReadComplete = '1') or (maintWriteComplete = '1') then + if (wdptr = '0') then + case size is + when "1000" => + -- Read 1 word. + requestPayloadLength_o <= "0000"; + requestWdptr_o <= '0'; + when "1011" => + -- Read 2 words. + requestPayloadLength_o <= "0001"; + requestWdptr_o <= '0'; + when "1100" => + -- Read 8 words. + requestPayloadLength_o <= "0111"; + requestWdptr_o <= '0'; + when others => + -- REMARK: Not allowed for a maintenance packet. + requestPayloadLength_o <= "0000"; + requestWdptr_o <= '0'; + end case; + else + case size is + when "1000" => + -- Read 1 word. + requestPayloadLength_o <= "0000"; + requestWdptr_o <= '1'; + when "1011" => + -- Read 4 words. + requestPayloadLength_o <= "0011"; + requestWdptr_o <= '0'; + when "1100" => + -- Read 16 words. + requestPayloadLength_o <= "1111"; + requestWdptr_o <= '0'; + when others => + -- REMARK: Not allowed for a maintenance packet. + requestPayloadLength_o <= "0000"; + requestWdptr_o <= '0'; + end case; + end if; + end if; + end if; + end process; + + ----------------------------------------------------------------------------- + -- Payload content memory. + ----------------------------------------------------------------------------- + PayloadMemory: MemorySimpleDualPort + generic map(ADDRESS_WIDTH=>4, DATA_WIDTH=>32) + port map(clkA_i=>clk, + enableA_i=>memoryWrite, + addressA_i=>memoryAddress, + dataA_i=>memoryDataIn, + clkB_i=>clk, + enableB_i=>enable, + addressB_i=>requestPayloadIndex_i, + dataB_o=>requestPayload_o); + +end architecture; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +-- REMARK: Add handler for maintenance response with error also... +entity MaintenanceResponseOutbound is + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + responseReadReady_i : in std_logic; + responseWriteReady_i : in std_logic; + responseVc_i : in std_logic; + responseCrf_i : in std_logic; + responsePrio_i : in std_logic_vector(1 downto 0); + responseTt_i : in std_logic_vector(1 downto 0); + responseDstId_i : in std_logic_vector(31 downto 0); + responseSrcId_i : in std_logic_vector(31 downto 0); + responseTid_i : in std_logic_vector(7 downto 0); + responseWdptr_i : in std_logic; + responsePayloadLength_i : in std_logic_vector(3 downto 0); + responsePayloadWrite_i : in std_logic; + responsePayloadIndex_i : in std_logic_vector(3 downto 0); + responsePayload_i : in std_logic_vector(31 downto 0); + responseDone_o : out std_logic; + + masterCyc_o : out std_logic; + masterStb_o : out std_logic; + masterDat_o : out std_logic_vector(31 downto 0); + masterAck_i : in std_logic); +end entity; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +architecture MaintenanceResponseOutbound of MaintenanceResponseOutbound is + component MemorySimpleDualPort + 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; + + type StateType is (WAIT_PACKET, + READ_RESPONSE, WRITE_RESPONSE, + WAIT_COMPLETE, RESPONSE_DONE); + signal state : StateType; + + signal packetIndex : natural range 0 to 33; + signal responseHeader : std_logic_vector(31 downto 0); + signal responsePayload : std_logic_vector(31 downto 0); + signal responsePayloadIndex : std_logic_vector(2 downto 0); + + signal memoryEnable : std_logic; + signal memoryAddress : std_logic_vector(3 downto 0); + signal memoryDataRead : std_logic_vector(31 downto 0); + +begin + + responseHeader <= + x"0000" & "000000" & responseVc_i & responseCrf_i & + responsePrio_i & responseTt_i & x"8"; + + MaintenanceResponse: process(clk, areset_n) + begin + if (areset_n = '0') then + masterCyc_o <= '0'; + masterStb_o <= '0'; + + memoryEnable <= '0'; + memoryAddress <= (others=>'0'); + + responsePayloadIndex <= (others=>'0'); + responseDone_o <= '0'; + + state <= WAIT_PACKET; + elsif (clk'event and clk = '1') then + if (enable = '1') then + case state is + when WAIT_PACKET => + ------------------------------------------------------------------- + -- + ------------------------------------------------------------------- + if (responseReadReady_i = '1') then + masterCyc_o <= '1'; + masterStb_o <= '1'; + masterDat_o <= responseHeader; + packetIndex <= 1; + memoryEnable <= '1'; + memoryAddress <= (others=>'0'); + responsePayloadIndex <= (others=>'0'); + state <= READ_RESPONSE; + elsif (responseWriteReady_i = '1') then + masterCyc_o <= '1'; + masterStb_o <= '1'; + masterDat_o <= responseHeader; + packetIndex <= 1; + state <= WRITE_RESPONSE; + end if; + + when READ_RESPONSE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (masterAck_i = '1') then + case (packetIndex) is + when 1 => + -- destination + masterDat_o <= responseDstId_i; + packetIndex <= packetIndex + 1; + when 2 => + -- source + masterDat_o <= responseSrcId_i; + packetIndex <= packetIndex + 1; + when 3 => + -- transaction & status & targetTID & hop & reserved(7:0) + masterDat_o <= "0010" & "0000" & responseTid_i & x"ff" & x"00"; + packetIndex <= packetIndex + 1; + when 4 => + -- reserved(15:0) & double-wordN(63:48) + if (responsePayloadLength_i = "0000") and (responseWdptr_i = '0') then + masterDat_o <= x"0000" & memoryDataRead(31 downto 16); + responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); + memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); + elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then + masterDat_o <= x"0000" & x"0000"; + else + masterDat_o <= x"0000" & memoryDataRead(31 downto 16); + responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); + memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); + end if; + packetIndex <= packetIndex + 1; + when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 => + -- double-wordN(47:16) + if (responsePayloadLength_i = "0000") and (responseWdptr_i = '0') then + masterDat_o <= responsePayload(31 downto 16) & x"0000"; + elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then + masterDat_o <= x"0000" & memoryDataRead(31 downto 16); + responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); + memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); + else + masterDat_o <= + responsePayload(31 downto 16) & memoryDataRead(31 downto 16); + responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); + memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); + end if; + packetIndex <= packetIndex + 1; + when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 => + -- double-wordN(15:0) & double-wordN(63:48) + if (responsePayloadLength_i = "0000") and (responseWdptr_i = '0') then + masterDat_o <= x"0000" & x"0000"; + elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then + masterDat_o <= responsePayload(31 downto 16) & x"0000"; + else + if (responsePayloadIndex /= responsePayloadLength_i(3 downto 1)) then + masterDat_o <= + responsePayload(31 downto 16) & memoryDataRead(31 downto 16); + responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); + memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); + else + masterDat_o <= + responsePayload(31 downto 16) & x"0000"; + responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); + memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); + end if; + end if; + + responsePayloadIndex <= + std_logic_vector(unsigned(responsePayloadIndex) + 1); + + if (responsePayloadIndex = responsePayloadLength_i(3 downto 1)) then + state <= WAIT_COMPLETE; + else + packetIndex <= packetIndex + 1; + end if; + when others => + -- Unallowed response length. + -- Dont do anything. + end case; + end if; + + when WRITE_RESPONSE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (masterAck_i = '1') then + case (packetIndex) is + when 1 => + -- destination + masterDat_o <= responseDstId_i; + packetIndex <= packetIndex + 1; + when 2 => + -- source + masterDat_o <= responseSrcId_i; + packetIndex <= packetIndex + 1; + when 3 => + -- transaction & status & targetTID & hop & reserved(7:0) + masterDat_o <= "0011" & "0000" & responseTid_i & x"ff" & x"00"; + packetIndex <= packetIndex + 1; + when others => + -- reserved(15:0) & crc(15:0) + masterDat_o <= x"00000000"; + packetIndex <= packetIndex + 1; + state <= WAIT_COMPLETE; + end case; + end if; + + when WAIT_COMPLETE => + ------------------------------------------------------------------- + -- + ------------------------------------------------------------------- + if (masterAck_i = '1') then + masterCyc_o <= '0'; + masterStb_o <= '0'; + state <= RESPONSE_DONE; + end if; + + when RESPONSE_DONE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + memoryEnable <= '0'; + if (responseReadReady_i = '0') and (responseWriteReady_i = '0') then + state <= WAIT_PACKET; + responseDone_o <= '0'; + else + responseDone_o <= '1'; + end if; + + when others => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + state <= WAIT_PACKET; + + end case; + end if; + end if; + end process; + + ----------------------------------------------------------------------------- + -- Payload content memory. + ----------------------------------------------------------------------------- + PayloadMemory: MemorySimpleDualPort + generic map(ADDRESS_WIDTH=>4, DATA_WIDTH=>32) + port map(clkA_i=>clk, + enableA_i=>responsePayloadWrite_i, + addressA_i=>responsePayloadIndex_i, + dataA_i=>responsePayload_i, + clkB_i=>clk, + enableB_i=>memoryEnable, + addressB_i=>memoryAddress, + dataB_o=>memoryDataRead); + +end architecture; Index: branches/2.0.0-development/rtl/vhdl/RioLogicalCommon.vhd =================================================================== --- branches/2.0.0-development/rtl/vhdl/RioLogicalCommon.vhd (nonexistent) +++ branches/2.0.0-development/rtl/vhdl/RioLogicalCommon.vhd (revision 41) @@ -0,0 +1,719 @@ +------------------------------------------------------------------------------- +-- +-- RapidIO IP Library Core +-- +-- This file is part of the RapidIO IP library project +-- http://www.opencores.org/cores/rio/ +-- +-- Description +-- Contains a platform to build endpoints on. +-- +-- 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 +-- +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- RioLogicalCommon. +------------------------------------------------------------------------------- +-- Ingress: +-- * Removes in-the-middle and trailing CRC. +-- * Forwards packets to logical-layer handlers depending on ftype and +-- transaction (output as address). +-- * Outputs header and deviceIDs in seperate accesses to facilitate 8- and +-- 16-bit deviceAddress support. All fields are right-justified. +-- Egress: +-- * Adds in-the-middle and trailing CRC. +-- * Receives packets from logical-layer handlers. +-- * Receives header and deviceIDs in seperate accesses to facilitate 8- and +-- 16-bit deviceAddress support. All fields are right-justified. +------------------------------------------------------------------------------- +-- REMARK: Egress; Places packets in different queues depending on the packet priority? +-- REMARK: Do not use Wishbone, use request/grant scheme instead... +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +entity RioLogicalCommon is + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + 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); + + masterCyc_o : out std_logic; + masterStb_o : out std_logic; + masterAdr_o : out std_logic_vector(7 downto 0); + masterDat_o : out std_logic_vector(31 downto 0); + masterAck_i : in std_logic; + + slaveCyc_i : in std_logic; + slaveStb_i : in std_logic; + slaveDat_i : in std_logic_vector(31 downto 0); + slaveAck_o : out std_logic); +end entity; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +architecture RioLogicalCommon of RioLogicalCommon is + + component RioLogicalCommonIngress is + port( + clk : in std_logic; + areset_n : in std_logic; + + 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); + + masterCyc_o : out std_logic; + masterStb_o : out std_logic; + masterAdr_o : out std_logic_vector(7 downto 0); + masterDat_o : out std_logic_vector(31 downto 0); + masterAck_i : in std_logic); + end component; + + component RioLogicalCommonEgress is + port( + clk : in std_logic; + areset_n : in std_logic; + + 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); + + slaveCyc_i : in std_logic; + slaveStb_i : in std_logic; + slaveDat_i : in std_logic_vector(31 downto 0); + slaveAck_o : out std_logic); + end component; + +begin + + Ingress: RioLogicalCommonIngress + port map( + clk=>clk, areset_n=>areset_n, + readFrameEmpty_i=>readFrameEmpty_i, + readFrame_o=>readFrame_o, + readContent_o=>readContent_o, + readContentEnd_i=>readContentEnd_i, + readContentData_i=>readContentData_i, + masterCyc_o=>masterCyc_o, + masterStb_o=>masterStb_o, + masterAdr_o=>masterAdr_o, + masterDat_o=>masterDat_o, + masterAck_i=>masterAck_i); + + Egress: RioLogicalCommonEgress + port map( + clk=>clk, areset_n=>areset_n, + writeFrameFull_i=>writeFrameFull_i, + writeFrame_o=>writeFrame_o, + writeFrameAbort_o=>writeFrameAbort_o, + writeContent_o=>writeContent_o, + writeContentData_o=>writeContentData_o, + slaveCyc_i=>slaveCyc_i, + slaveStb_i=>slaveStb_i, + slaveDat_i=>slaveDat_i, + slaveAck_o=>slaveAck_o); + +end architecture; + + + +------------------------------------------------------------------------------- +-- RioLogicalCommonIngress. +------------------------------------------------------------------------------- +-- REMARK: Check the destination address to see if it matches the one configured??? +-- REMARK: Remove the acknowledge on all accesses on the master bus. +-- REMARK: Add component declarations to riocommon.vhd. +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + +------------------------------------------------------------------------------- +-- Entity for RioLogicalCommonIngress. +------------------------------------------------------------------------------- +entity RioLogicalCommonIngress is + port( + clk : in std_logic; + areset_n : in std_logic; + + 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); + + masterCyc_o : out std_logic; + masterStb_o : out std_logic; + masterAdr_o : out std_logic_vector(7 downto 0); + masterDat_o : out std_logic_vector(31 downto 0); + masterAck_i : in std_logic); +end entity; + + +------------------------------------------------------------------------------- +-- +------------------------------------------------------------------------------- +architecture RioLogicalCommonIngress of RioLogicalCommonIngress is + type StateType is (IDLE, + WAIT_HEADER_0, HEADER_0, HEADER_1, + SEND_HEADER, SEND_DESTINATION, SEND_SOURCE, + FORWARD_SHORT, FORWARD_CRC, FORWARD_LONG, FORWARD_LAST, + END_PACKET); + signal state : StateType; + + signal packetPosition : natural range 0 to 32; + signal packetContent : std_logic_vector(63 downto 0); + + signal tt : std_logic_vector(1 downto 0); + signal ftype : std_logic_vector(3 downto 0); + signal transaction : std_logic_vector(3 downto 0); + +begin + + process(clk, areset_n) + begin + if (areset_n = '0') then + masterCyc_o <= '0'; + masterStb_o <= '0'; + + state <= IDLE; + packetPosition <= 0; + packetContent <= (others=>'0'); + tt <= "00"; + ftype <= "0000"; + transaction <= "0000"; + + readContent_o <= '0'; + readFrame_o <= '0'; + elsif (clk'event and clk = '1') then + readContent_o <= '0'; + readFrame_o <= '0'; + + case state is + when IDLE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + packetPosition <= 0; + if (readFrameEmpty_i = '0') then + readContent_o <= '1'; + state <= WAIT_HEADER_0; + end if; + + when WAIT_HEADER_0 => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + readContent_o <= '1'; + state <= HEADER_0; + + when HEADER_0 => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + packetContent <= packetContent(31 downto 0) & readContentData_i; + packetPosition <= packetPosition + 1; + readContent_o <= '1'; + + tt <= readContentData_i(21 downto 20); + ftype <= readContentData_i(19 downto 16); + + state <= HEADER_1; + + when HEADER_1 => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + packetContent <= packetContent(31 downto 0) & readContentData_i; + packetPosition <= packetPosition + 1; + + if (tt = "00") then + transaction <= readContentData_i(31 downto 28); + elsif (tt = "01") then + transaction <= readContentData_i(15 downto 12); + end if; + + state <= SEND_HEADER; + + when SEND_HEADER => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + masterCyc_o <= '1'; + masterStb_o <= '1'; + masterAdr_o <= ftype & transaction; + masterDat_o <= x"0000" & packetContent(63 downto 48); + packetContent <= packetContent(47 downto 0) & x"0000"; + + state <= SEND_DESTINATION; + + when SEND_DESTINATION => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (masterAck_i = '1') then + if (tt = "00") then + masterDat_o <= x"000000" & packetContent(63 downto 56); + packetContent <= packetContent(55 downto 0) & x"00"; + elsif (tt = "01") then + masterDat_o <= x"0000" & packetContent(63 downto 48); + packetContent <= packetContent(47 downto 0) & x"0000"; + end if; + + state <= SEND_SOURCE; + end if; + + when SEND_SOURCE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (masterAck_i = '1') then + if (tt = "00") then + masterDat_o <= x"000000" & packetContent(63 downto 56); + packetContent <= packetContent(55 downto 0) & x"00"; + elsif (tt = "01") then + masterDat_o <= x"0000" & packetContent(63 downto 48); + packetContent <= packetContent(47 downto 32) & readContentData_i & x"0000"; + readContent_o <= '1'; + end if; + + state <= FORWARD_SHORT; + end if; + + when FORWARD_SHORT => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (masterAck_i = '1') then + packetPosition <= packetPosition + 1; + + if (tt = "00") then + masterDat_o <= packetContent(63 downto 32); + packetContent <= packetContent(31 downto 0) & readContentData_i; + elsif (tt = "01") then + masterDat_o <= packetContent(63 downto 32); + packetContent <= packetContent(31 downto 16) & readContentData_i & x"0000"; + end if; + + if (readContentEnd_i = '0') then + if (packetPosition = 20) then + state <= FORWARD_CRC; + end if; + + readContent_o <= '1'; + else + readFrame_o <= '1'; + state <= END_PACKET; + end if; + end if; + + when FORWARD_CRC => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (masterAck_i = '1') then + masterDat_o <= packetContent(63 downto 32); + + packetPosition <= packetPosition + 1; + packetContent <= + packetContent(31 downto 0) & readContentData_i(15 downto 0) & x"0000"; + + if (readContentEnd_i = '0') then + readContent_o <= '1'; + state <= FORWARD_LONG; + else + readFrame_o <= '1'; + state <= FORWARD_LAST; + end if; + end if; + + when FORWARD_LONG => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (masterAck_i = '1') then + masterDat_o <= packetContent(63 downto 32); + + packetPosition <= packetPosition + 1; + packetContent <= + packetContent(15 downto 0) & readContentData_i & x"0000"; + + if (readContentEnd_i = '0') then + readContent_o <= '1'; + else + readFrame_o <= '1'; + state <= FORWARD_LAST; + end if; + end if; + + when FORWARD_LAST => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + -- REMARK: The last always contain the CRC? + if (masterAck_i = '1') then + masterDat_o <= packetContent(63 downto 32); + state <= END_PACKET; + end if; + + when END_PACKET => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (masterAck_i = '1') then + masterCyc_o <= '0'; + masterStb_o <= '0'; + state <= IDLE; + end if; + + when others => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + state <= IDLE; + end case; + end if; + end process; + +end architecture; + + +------------------------------------------------------------------------------- +-- RioLogicalCommonEgress. +-- Only 8-bit and 16-bit deviceId are supported. The first write must contain +-- the 16-bit header, the second write must contain the destination address and +-- the third must contain the source address. +-- CRC is calculated during the transfer and is inserted at byte 81 and 82 and +-- appended to the packet when it ends. +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rio_common.all; + +------------------------------------------------------------------------------- +-- Entity for RioLogicalCommonEgress. +------------------------------------------------------------------------------- +entity RioLogicalCommonEgress is + port( + clk : in std_logic; + areset_n : in std_logic; + + 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); + + slaveCyc_i : in std_logic; + slaveStb_i : in std_logic; + slaveDat_i : in std_logic_vector(31 downto 0); + slaveAck_o : out std_logic); +end entity; + + +------------------------------------------------------------------------------- +-- Architecture for RioLogicalCommonEgress. +------------------------------------------------------------------------------- +architecture RioLogicalCommonEgress of RioLogicalCommonEgress 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; + + type StateType is (IDLE, + HEADER_GET, HEADER_ACK, + DESTINATION_GET, DESTINATION_ACK, + SOURCE_GET, SOURCE_ACK, + CONTENT_GET, CONTENT_ACK, + CRC_APPEND, SEND_FRAME, + RESTART_FRAME, WAIT_UPDATE); + signal state : StateType; + signal packetPosition : natural range 0 to 31; + signal halfWordPending : std_logic; + signal halfWord : std_logic_vector(15 downto 0); + + signal header : std_logic_vector(15 downto 0); + signal tt : std_logic_vector(1 downto 0); + signal dstAddr : std_logic_vector(7 downto 0); + + signal writeContentData : std_logic_vector(31 downto 0); + + signal crc16Current, crc16Temp, crc16Next: std_logic_vector(15 downto 0); + +begin + + writeContentData_o <= writeContentData; + + process(clk, areset_n) + begin + if (areset_n = '0') then + state <= IDLE; + crc16Current <= x"0000"; + + slaveAck_o <= '0'; + + halfWordPending <= '0'; + + writeContent_o <= '0'; + writeFrame_o <= '0'; + writeFrameAbort_o <= '0'; + writeContentData <= (others=>'0'); + elsif (clk'event and clk = '1') then + writeContent_o <= '0'; + writeFrame_o <= '0'; + + case state is + when IDLE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + packetPosition <= 0; + if (writeFrameFull_i = '0') then + crc16Current <= x"ffff"; + state <= HEADER_GET; + end if; + + when HEADER_GET => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then + header <= slaveDat_i(15 downto 0); + tt <= slaveDat_i(5 downto 4); + + slaveAck_o <= '1'; + state <= HEADER_ACK; + else + state <= HEADER_GET; + end if; + + when HEADER_ACK => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + slaveAck_o <= '0'; + state <= DESTINATION_GET; + + when DESTINATION_GET => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + + if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then + if (tt = "00") then + dstAddr <= slaveDat_i(7 downto 0); + elsif (tt = "01") then + writeContent_o <= '1'; + writeContentData <= header & slaveDat_i(15 downto 0); + packetPosition <= packetPosition + 1; + else + -- REMARK: Not supported. + end if; + + slaveAck_o <= '1'; + state <= DESTINATION_ACK; + else + state <= RESTART_FRAME; + end if; + + when DESTINATION_ACK => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + slaveAck_o <= '0'; + state <= SOURCE_GET; + + if (tt = "01") then + crc16Current <= crc16Next; + end if; + + when SOURCE_GET => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + + if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then + if (tt = "00") then + halfWordPending <= '0'; + writeContent_o <= '1'; + writeContentData <= header & dstAddr & slaveDat_i(7 downto 0); + packetPosition <= packetPosition + 1; + elsif (tt = "01") then + halfWordPending <= '1'; + halfWord <= slaveDat_i(15 downto 0); + else + -- REMARK: Not supported. + end if; + + slaveAck_o <= '1'; + state <= SOURCE_ACK; + else + state <= RESTART_FRAME; + end if; + + when SOURCE_ACK => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + slaveAck_o <= '0'; + state <= CONTENT_GET; + + when CONTENT_GET => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then + if (halfWordPending = '0') then + writeContent_o <= '1'; + writeContentData <= slaveDat_i; + packetPosition <= packetPosition + 1; + else + writeContent_o <= '1'; + writeContentData <= halfWord & slaveDat_i(31 downto 16); + packetPosition <= packetPosition + 1; + halfWord <= slaveDat_i(15 downto 0); + end if; + + slaveAck_o <= '1'; + state <= CONTENT_ACK; + else + state <= CRC_APPEND; + end if; + + when CONTENT_ACK => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + slaveAck_o <= '0'; + + crc16Current <= crc16Next; + + if (packetPosition = 20) then + if (halfWordPending = '0') then + halfWordPending <= '1'; + halfWord <= crc16Next; + else + writeContent_o <= '1'; + writeContentData <= halfWord & crc16Next; + crc16Current <= crc16Next; + packetPosition <= packetPosition + 1; + halfWordPending <= '0'; + halfWord <= crc16Next; + end if; + end if; + + state <= CONTENT_GET; + + when CRC_APPEND => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + if (tt = "00") then + writeContent_o <= '1'; + writeContentData <= crc16Current & x"0000"; + elsif (tt = "01") then + writeContent_o <= '1'; + writeContentData <= crc16Current & x"0000"; + end if; + + state <= SEND_FRAME; + + when SEND_FRAME => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + writeFrame_o <= '1'; + state <= WAIT_UPDATE; + + when RESTART_FRAME => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + writeFrameAbort_o <= '1'; + state <= WAIT_UPDATE; + + when WAIT_UPDATE => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + writeFrameAbort_o <= '0'; + state <= IDLE; + + when others => + --------------------------------------------------------------------- + -- + --------------------------------------------------------------------- + end case; + end if; + end process; + + ----------------------------------------------------------------------------- + -- Packet CRC calculation. + ----------------------------------------------------------------------------- + + 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); + +end architecture; Index: branches/2.0.0-development/rtl/vhdl/RioPacketBuffer.vhd =================================================================== --- branches/2.0.0-development/rtl/vhdl/RioPacketBuffer.vhd (nonexistent) +++ branches/2.0.0-development/rtl/vhdl/RioPacketBuffer.vhd (revision 41) @@ -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;
branches/2.0.0-development/rtl/vhdl/RioPacketBuffer.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: branches/2.0.0-development/rtl/vhdl/srio_pcs_struct.vhd =================================================================== --- branches/2.0.0-development/rtl/vhdl/srio_pcs_struct.vhd (nonexistent) +++ branches/2.0.0-development/rtl/vhdl/srio_pcs_struct.vhd (revision 41) @@ -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: branches/2.0.0-development/rtl/vhdl/RioSwitch.vhd =================================================================== --- branches/2.0.0-development/rtl/vhdl/RioSwitch.vhd (nonexistent) +++ branches/2.0.0-development/rtl/vhdl/RioSwitch.vhd (revision 41) @@ -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; + + +
branches/2.0.0-development/rtl/vhdl/RioSwitch.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: branches/2.0.0-development/doc/rio.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: branches/2.0.0-development/doc/rio.pdf =================================================================== --- branches/2.0.0-development/doc/rio.pdf (nonexistent) +++ branches/2.0.0-development/doc/rio.pdf (revision 41)
branches/2.0.0-development/doc/rio.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: branches/2.0.0-development/doc/rio.odt =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: branches/2.0.0-development/doc/rio.odt =================================================================== --- branches/2.0.0-development/doc/rio.odt (nonexistent) +++ branches/2.0.0-development/doc/rio.odt (revision 41)
branches/2.0.0-development/doc/rio.odt Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property

powered by: WebSVN 2.1.0

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