URL
https://opencores.org/ocsvn/rio/rio/trunk
Subversion Repositories rio
Compare Revisions
- This comparison shows the changes necessary to convert path
/rio/tags
- from Rev 23 to Rev 29
- ↔ Reverse comparison
Rev 23 → Rev 29
/1.0.1/bench/vhdl/TestRioSwitch.vhd
0,0 → 1,1266
------------------------------------------------------------------------------- |
-- |
-- 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); |
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; |
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 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 |
|
--------------------------------------------------------------------------- |
-- Place a new ingress frame on a port. |
--------------------------------------------------------------------------- |
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 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; |
|
--------------------------------------------------------------------------- |
-- Expect a new egress frame on a port. |
--------------------------------------------------------------------------- |
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 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; |
|
--------------------------------------------------------------------------- |
-- Read a configuration-space register. |
--------------------------------------------------------------------------- |
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; |
|
--------------------------------------------------------------------------- |
-- Write a configuration-space register. |
--------------------------------------------------------------------------- |
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; |
|
--------------------------------------------------------------------------- |
-- Set a route table entry. |
--------------------------------------------------------------------------- |
procedure RouteSet(constant deviceId : std_logic_vector(15 downto 0); |
constant portIndex : std_logic_vector(7 downto 0)) is |
variable frame : RioFrame; |
begin |
WriteConfig32(portIndex=>0, destinationId=>x"ffff", sourceId=>x"ffff", hop=>x"00", |
tid=>x"de", address=>x"000070", data=>(x"0000" & deviceId)); |
WriteConfig32(portIndex=>0, destinationId=>x"ffff", sourceId=>x"ffff", hop=>x"00", |
tid=>x"ad", address=>x"000074", data=>(x"000000" & portIndex)); |
end procedure; |
|
--------------------------------------------------------------------------- |
-- Set the default route table entry. |
--------------------------------------------------------------------------- |
procedure RouteSetDefault(constant portIndex : std_logic_vector(7 downto 0)) is |
variable frame : RioFrame; |
begin |
WriteConfig32(portIndex=>0, destinationId=>x"ffff", sourceId=>x"ffff", hop=>x"00", |
tid=>x"ad", address=>x"000078", data=>(x"000000" & portIndex)); |
end procedure; |
|
--------------------------------------------------------------------------- |
-- Send a frame on an ingress port and expect it at an egress port. |
--------------------------------------------------------------------------- |
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; |
|
--------------------------------------------------------------------------- |
-- Variable definitions. |
--------------------------------------------------------------------------- |
|
-- 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 at the same time."); |
PrintS("Result: Both packets should be received at the expected ports."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC3-Step1"); |
--------------------------------------------------------------------------- |
|
-- Setup the routing table for the following steps. |
RouteSet(x"0000", x"00"); |
RouteSet(x"0001", x"00"); |
RouteSet(x"0002", x"00"); |
RouteSet(x"0003", x"00"); |
RouteSet(x"0004", x"01"); |
RouteSet(x"0005", x"02"); |
RouteSet(x"0006", x"03"); |
RouteSetDefault(x"06"); |
|
-- Frame on port 0 to port 1. |
randomPayload.length := 3; |
CreateRandomPayload(randomPayload.data, seed1, seed2); |
SendFrame(portIndex=>0, |
sourceId=>x"ffff", destinationId=>x"0004", payload=>randomPayload); |
ReceiveFrame(portIndex=>1, |
sourceId=>x"ffff", destinationId=>x"0004", 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 that 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"0004", payload=>randomPayload); |
|
-- Frame on port 1 to port 2. |
randomPayload1.length := 6; |
CreateRandomPayload(randomPayload1.data, seed1, seed2); |
SendFrame(portIndex=>1, |
sourceId=>x"0000", destinationId=>x"0005", payload=>randomPayload1); |
|
-- Frame on port 2 to port 2. |
randomPayload2.length := 7; |
CreateRandomPayload(randomPayload2.data, seed1, seed2); |
SendFrame(portIndex=>2, |
sourceId=>x"0000", destinationId=>x"0005", payload=>randomPayload2); |
|
wait for 10 us; |
|
ReceiveFrame(portIndex=>1, |
sourceId=>x"ffff", destinationId=>x"0004", payload=>randomPayload); |
wait until frameComplete(0) = '1'; |
frameValid(0) <= '0'; |
wait until frameReceived(1) = '1'; |
frameExpected(1) <= '0'; |
|
wait for 10 us; |
|
ReceiveFrame(portIndex=>2, |
sourceId=>x"0000", destinationId=>x"0005", payload=>randomPayload1); |
wait until frameComplete(1) = '1'; |
frameValid(1) <= '0'; |
wait until frameReceived(2) = '1'; |
frameExpected(2) <= '0'; |
|
wait for 10 us; |
|
ReceiveFrame(portIndex=>2, |
sourceId=>x"0000", destinationId=>x"0005", payload=>randomPayload2); |
wait until frameComplete(2) = '1'; |
frameValid(2) <= '0'; |
wait until frameReceived(2) = '1'; |
frameExpected(2) <= '0'; |
|
--------------------------------------------------------------------------- |
-- Test completed. |
--------------------------------------------------------------------------- |
|
wait for 10 us; |
|
assert readFrameEmpty = "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), |
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, |
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; |
|
|
|
------------------------------------------------------------------------------- |
-- Switch port test stub. |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
library std; |
use std.textio.all; |
use work.rio_common.all; |
|
|
------------------------------------------------------------------------------- |
-- Entity for TestPort. |
------------------------------------------------------------------------------- |
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; |
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 for TestPort. |
------------------------------------------------------------------------------- |
architecture TestPortImpl of TestPort is |
begin |
|
----------------------------------------------------------------------------- |
-- Egress frame receiver. |
----------------------------------------------------------------------------- |
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; |
|
----------------------------------------------------------------------------- |
-- Ingress frame sender. |
----------------------------------------------------------------------------- |
FrameSender: process |
type StateType is (STATE_IDLE, STATE_READ); |
variable state : StateType; |
variable frameIndex : natural range 0 to 69; |
begin |
readFrameEmpty_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; |
readFrameEmpty_o <= '0'; |
end if; |
|
when STATE_READ => |
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'; |
readContentData_o <= (others => 'U'); |
else |
-- Not reading a frame. |
end if; |
|
end case; |
end loop; |
end process; |
|
end architecture; |
1.0.1/bench/vhdl/TestRioSwitch.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/bench/vhdl/TestRioPcsUart.vhd
===================================================================
--- 1.0.1/bench/vhdl/TestRioPcsUart.vhd (nonexistent)
+++ 1.0.1/bench/vhdl/TestRioPcsUart.vhd (revision 29)
@@ -0,0 +1,673 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- This file contains a testbench for RioPcsUart.
+--
+-- 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
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- TestRioPcsUart.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+library std;
+use std.textio.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for TestRioPcsUart.
+-------------------------------------------------------------------------------
+entity TestRioPcsUart is
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for TestUart.
+-------------------------------------------------------------------------------
+architecture TestRioPcsUartImpl of TestRioPcsUart is
+
+ component RioFifo1 is
+ generic(
+ WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ empty_o : out std_logic;
+ read_i : in std_logic;
+ data_o : out std_logic_vector(WIDTH-1 downto 0);
+
+ full_o : out std_logic;
+ write_i : in std_logic;
+ data_i : in std_logic_vector(WIDTH-1 downto 0));
+ end component;
+
+ component RioSymbolConverter is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ portInitialized_o : out std_logic;
+ outboundSymbolEmpty_i : in std_logic;
+ outboundSymbolRead_o : out std_logic;
+ outboundSymbol_i : in std_logic_vector(33 downto 0);
+ inboundSymbolFull_i : in std_logic;
+ inboundSymbolWrite_o : out std_logic;
+ inboundSymbol_o : out std_logic_vector(33 downto 0);
+
+ uartEmpty_i : in std_logic;
+ uartRead_o : out std_logic;
+ uartData_i : in std_logic_vector(7 downto 0);
+ uartFull_i : in std_logic;
+ uartWrite_o : out std_logic;
+ uartData_o : out std_logic_vector(7 downto 0));
+ end component;
+
+ signal clk : std_logic;
+ signal areset_n : std_logic;
+
+ signal portInitialized : std_logic;
+
+ signal outboundSymbolEmpty : std_logic;
+ signal outboundSymbolRead : std_logic;
+ signal outboundSymbolReadData : std_logic_vector(33 downto 0);
+ signal outboundSymbolFull : std_logic;
+ signal outboundSymbolWrite : std_logic;
+ signal outboundSymbolWriteData : std_logic_vector(33 downto 0);
+
+ signal inboundSymbolFull : std_logic;
+ signal inboundSymbolWrite : std_logic;
+ signal inboundSymbolWriteData : std_logic_vector(33 downto 0);
+
+ signal uartInboundEmpty : std_logic;
+ signal uartInboundRead : std_logic;
+ signal uartInboundReadData : std_logic_vector(7 downto 0);
+ signal uartInboundFull : std_logic;
+ signal uartInboundWrite : std_logic;
+ signal uartInboundWriteData : std_logic_vector(7 downto 0);
+
+ signal uartOutboundFull : std_logic;
+ signal uartOutboundWrite : std_logic;
+ signal uartOutboundWriteData : std_logic_vector(7 downto 0);
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Clock generation.
+ -----------------------------------------------------------------------------
+ ClockGenerator: process
+ begin
+ clk <= '0';
+ wait for 20 ns;
+ clk <= '1';
+ wait for 20 ns;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Serial protocol test driver.
+ -----------------------------------------------------------------------------
+ TestDriver: process
+
+ ---------------------------------------------------------------------------
+ -- Procedure to read a symbol.
+ ---------------------------------------------------------------------------
+ procedure ReadSymbol(
+ constant symbolType : in std_logic_vector(1 downto 0);
+ constant symbolContent : in std_logic_vector(31 downto 0) := x"00000000") is
+ begin
+ inboundSymbolFull <= '0';
+ wait until inboundSymbolWrite = '1' and clk'event and clk = '1';
+ inboundSymbolFull <= '1';
+
+ assert symbolType = inboundSymbolWriteData(33 downto 32)
+ report "Missmatching symbol type:expected=" &
+ integer'image(to_integer(unsigned(symbolType))) &
+ " got=" &
+ integer'image(to_integer(unsigned(outboundSymbolWriteData(33 downto 32))))
+ severity error;
+
+ if (symbolType = SYMBOL_CONTROL) then
+ assert symbolContent(31 downto 8) = inboundSymbolWriteData(31 downto 8)
+ report "Missmatching symbol content:expected=" &
+ integer'image(to_integer(unsigned(symbolContent(31 downto 8)))) &
+ " got=" &
+ integer'image(to_integer(unsigned(inboundSymbolWriteData(31 downto 8))))
+ severity error;
+ elsif (symbolType = SYMBOL_DATA) then
+ assert symbolContent(31 downto 0) = inboundSymbolWriteData(31 downto 0)
+ report "Missmatching symbol content:expected=" &
+ integer'image(to_integer(unsigned(symbolContent(31 downto 0)))) &
+ " got=" &
+ integer'image(to_integer(unsigned(inboundSymbolWriteData(31 downto 0))))
+ severity error;
+ end if;
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to write a symbol.
+ ---------------------------------------------------------------------------
+ procedure WriteSymbol(
+ constant symbolType : in std_logic_vector(1 downto 0);
+ constant symbolContent : in std_logic_vector(31 downto 0) := x"00000000") is
+ begin
+ wait until outboundSymbolFull = '0' and clk'event and clk = '1';
+ outboundSymbolWrite <= '1';
+ outboundSymbolWriteData <= symbolType & symbolContent;
+ wait until clk'event and clk = '1';
+ outboundSymbolWrite <= '0';
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to read an octet.
+ ---------------------------------------------------------------------------
+ procedure ReadOctet(
+ constant octet : in std_logic_vector(7 downto 0) := x"00") is
+ begin
+ uartOutboundFull <= '0';
+ wait until uartOutboundWrite = '1' and clk'event and clk = '1';
+ uartOutboundFull <= '1';
+
+ assert uartOutboundWriteData = octet
+ report "Missmatching octet content:expected=" &
+ integer'image(to_integer(unsigned(octet))) &
+ " got=" &
+ integer'image(to_integer(unsigned(uartOutboundWriteData)))
+ severity error;
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to send a symbol.
+ ---------------------------------------------------------------------------
+ procedure WriteOctet(
+ constant octet : in std_logic_vector(7 downto 0) := x"00") is
+ begin
+ wait until uartInboundFull = '0' and clk'event and clk = '1';
+ uartInboundWrite <= '1';
+ uartInboundWriteData <= octet;
+ wait until clk'event and clk = '1';
+ uartInboundWrite <= '0';
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Process variables.
+ ---------------------------------------------------------------------------
+
+ begin
+ ---------------------------------------------------------------------------
+ -- Test case initialization.
+ ---------------------------------------------------------------------------
+
+ uartOutboundFull <= '1';
+ uartInboundWrite <= '0';
+
+ inboundSymbolFull <= '1';
+ outboundSymbolWrite <= '0';
+
+ -- Generate a startup reset pulse.
+ areset_n <= '0';
+ wait until clk'event and clk = '1';
+ wait until clk'event and clk = '1';
+ areset_n <= '1';
+ wait until clk'event and clk = '1';
+ wait until clk'event and clk = '1';
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioPcsUart");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioPcsUart-TC1");
+ PrintS("Description: Check initial silence time.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC1-Step1");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_IDLE);
+
+ uartOutboundFull <= '0';
+ for i in 0 to 4095 loop
+ wait until clk'event and clk = '1';
+ assert uartOutboundWrite = '0' report "Sending during silence time."
+ severity error;
+ end loop;
+
+ ReadOctet(x"7e");
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioPcsUart-TC2");
+ PrintS("Description: Check outbound symbol generation.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step1");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_IDLE);
+ ReadOctet(x"7e");
+ WriteSymbol(SYMBOL_IDLE);
+ ReadOctet(x"7e");
+ WriteSymbol(SYMBOL_IDLE);
+ ReadOctet(x"7e");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 2:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step2");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_CONTROL, x"123456" & "XXXXXXXX");
+ ReadOctet(x"12");
+ ReadOctet(x"34");
+ ReadOctet(x"56");
+ ReadOctet(x"7e");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 3:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step3");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_CONTROL, x"7d7d7d" & "XXXXXXXX");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7e");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 4:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step4");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_CONTROL, x"7e7e7e" & "XXXXXXXX");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7e");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 5:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step5");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_CONTROL, x"7d7f7e" & "XXXXXXXX");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7f");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7e");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 6:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step6");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_DATA, x"12345678");
+ ReadOctet(x"12");
+ ReadOctet(x"34");
+ ReadOctet(x"56");
+ ReadOctet(x"78");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 7:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step7");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_DATA, x"7d7d7d7d");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 8:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step8");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_DATA, x"7e7e7e7e");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 9:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step9");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_DATA, x"7d7f7e7f");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7f");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7f");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 10:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step10");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_IDLE);
+ ReadOctet(x"7e");
+ WriteSymbol(SYMBOL_CONTROL, x"123456" & "XXXXXXXX");
+ ReadOctet(x"12");
+ ReadOctet(x"34");
+ ReadOctet(x"56");
+ ReadOctet(x"7e");
+ WriteSymbol(SYMBOL_DATA, x"789abcde");
+ ReadOctet(x"78");
+ ReadOctet(x"9a");
+ ReadOctet(x"bc");
+ ReadOctet(x"de");
+ WriteSymbol(SYMBOL_CONTROL, x"123456" & "XXXXXXXX");
+ ReadOctet(x"12");
+ ReadOctet(x"34");
+ ReadOctet(x"56");
+ ReadOctet(x"7e");
+ WriteSymbol(SYMBOL_DATA, x"789abcde");
+ ReadOctet(x"78");
+ ReadOctet(x"9a");
+ ReadOctet(x"bc");
+ ReadOctet(x"de");
+ WriteSymbol(SYMBOL_DATA, x"789abcde");
+ ReadOctet(x"78");
+ ReadOctet(x"9a");
+ ReadOctet(x"bc");
+ ReadOctet(x"de");
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioPcsUart-TC3");
+ PrintS("Description: Check inbound symbol generation.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step1");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"7e");
+ WriteOctet(x"7e");
+ ReadSymbol(SYMBOL_IDLE);
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"12");
+ WriteOctet(x"7e");
+ ReadSymbol(SYMBOL_IDLE);
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"34");
+ WriteOctet(x"56");
+ WriteOctet(x"7e");
+ ReadSymbol(SYMBOL_IDLE);
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"78");
+ WriteOctet(x"9a");
+ WriteOctet(x"bc");
+ WriteOctet(x"7e");
+ ReadSymbol(SYMBOL_CONTROL, x"789abc" & "XXXXXXXX");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"7d");
+ WriteOctet(x"5d");
+ WriteOctet(x"7d");
+ WriteOctet(x"5d");
+ WriteOctet(x"7d");
+ WriteOctet(x"5d");
+ WriteOctet(x"7e");
+ ReadSymbol(SYMBOL_CONTROL, x"7d7d7d" & "XXXXXXXX");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"7d");
+ WriteOctet(x"5e");
+ WriteOctet(x"7d");
+ WriteOctet(x"5e");
+ WriteOctet(x"7d");
+ WriteOctet(x"5e");
+ WriteOctet(x"7e");
+ ReadSymbol(SYMBOL_CONTROL, x"7e7e7e" & "XXXXXXXX");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"f1");
+ WriteOctet(x"11");
+ WriteOctet(x"22");
+ WriteOctet(x"33");
+ ReadSymbol(SYMBOL_DATA, x"f1112233");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"7e");
+ ReadSymbol(SYMBOL_IDLE);
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"7d");
+ WriteOctet(x"5d");
+ WriteOctet(x"7d");
+ WriteOctet(x"5d");
+ WriteOctet(x"7d");
+ WriteOctet(x"5d");
+ WriteOctet(x"7d");
+ WriteOctet(x"5d");
+ ReadSymbol(SYMBOL_DATA, x"7d7d7d7d");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"7d");
+ WriteOctet(x"5e");
+ WriteOctet(x"7d");
+ WriteOctet(x"5e");
+ WriteOctet(x"7d");
+ WriteOctet(x"5e");
+ WriteOctet(x"7d");
+ WriteOctet(x"5e");
+ ReadSymbol(SYMBOL_DATA, x"7e7e7e7e");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"44");
+ WriteOctet(x"55");
+ WriteOctet(x"66");
+ WriteOctet(x"77");
+ ReadSymbol(SYMBOL_DATA, x"44556677");
+ WriteOctet(x"88");
+ WriteOctet(x"99");
+ WriteOctet(x"aa");
+ WriteOctet(x"bb");
+ ReadSymbol(SYMBOL_DATA, x"8899aabb");
+
+ ---------------------------------------------------------------------------
+ -- Test completed.
+ ---------------------------------------------------------------------------
+
+ TestEnd;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ --
+ -----------------------------------------------------------------------------
+
+ OutboundSymbolFifo: RioFifo1
+ generic map(WIDTH=>34)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ empty_o=>outboundSymbolEmpty, read_i=>outboundSymbolRead, data_o=>outboundSymbolReadData,
+ full_o=>outboundSymbolFull, write_i=>outboundSymbolWrite, data_i=>outboundSymbolWriteData);
+
+ InboundOctetFifo: RioFifo1
+ generic map(WIDTH=>8)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ empty_o=>uartInboundEmpty, read_i=>uartInboundRead, data_o=>uartInboundReadData,
+ full_o=>uartInboundFull, write_i=>uartInboundWrite, data_i=>uartInboundWriteData);
+
+ TestSymbolConverter: RioSymbolConverter
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ portInitialized_o=>portInitialized,
+ outboundSymbolEmpty_i=>outboundSymbolEmpty,
+ outboundSymbolRead_o=>outboundSymbolRead, outboundSymbol_i=>outboundSymbolReadData,
+ inboundSymbolFull_i=>inboundSymbolFull,
+ inboundSymbolWrite_o=>inboundSymbolWrite, inboundSymbol_o=>inboundSymbolWriteData,
+ uartEmpty_i=>uartInboundEmpty, uartRead_o=>uartInboundRead, uartData_i=>uartInboundReadData,
+ uartFull_i=>uartOutboundFull, uartWrite_o=>uartOutboundWrite, uartData_o=>uartOutboundWriteData);
+
+end architecture;
1.0.1/bench/vhdl/TestRioPcsUart.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/bench/vhdl/TestUart.vhd
===================================================================
--- 1.0.1/bench/vhdl/TestUart.vhd (nonexistent)
+++ 1.0.1/bench/vhdl/TestUart.vhd (revision 29)
@@ -0,0 +1,228 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Contains a testbench for the generic UART entity.
+--
+-- 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
+--
+-------------------------------------------------------------------------------
+
+
+-------------------------------------------------------------------------------
+-- TestUart.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+library std;
+use std.textio.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for TestUart.
+-------------------------------------------------------------------------------
+entity TestUart is
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for TestUart.
+-------------------------------------------------------------------------------
+architecture TestUartImpl of TestUart is
+
+ component Uart is
+ generic(
+ DIVISOR_WIDTH : natural;
+ DATA_WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ divisor_i : in std_logic_vector(DIVISOR_WIDTH-1 downto 0);
+
+ serial_i : in std_logic;
+ serial_o : out std_logic;
+
+ empty_o : out std_logic;
+ read_i : in std_logic;
+ data_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ full_o : out std_logic;
+ write_i : in std_logic;
+ data_i : in std_logic_vector(DATA_WIDTH-1 downto 0));
+ end component;
+
+ signal clk : std_logic;
+ signal areset_n : std_logic;
+
+ signal rxSerial : std_logic;
+ signal txSerial : std_logic;
+
+ signal rxEmpty : std_logic;
+ signal rxRead : std_logic;
+ signal rxData : std_logic_vector(7 downto 0);
+
+ signal txFull : std_logic;
+ signal txWrite : std_logic;
+ signal txData : std_logic_vector(7 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 SerialSend(
+ constant data : in std_logic_vector(7 downto 0)) is
+ variable outgoing : std_logic_vector(9 downto 0);
+ begin
+ -- Create the complete transmission character.
+ outgoing(0) := '0';
+ for i in 0 to 7 loop
+ outgoing(i+1) := data(i);
+ end loop;
+ outgoing(9) := '1';
+
+ -- Send the character.
+ for i in 0 to 9 loop
+ txSerial <= outgoing(i);
+ wait for 500 ns;
+ end loop;
+ end procedure;
+
+ procedure SerialReceive(
+ constant data : in std_logic_vector(7 downto 0)) is
+ variable incomming : std_logic_vector(9 downto 0);
+ begin
+ -- Receive the character.
+ wait until rxSerial = '0';
+ incomming(0) := '0';
+ for i in 1 to 9 loop
+ wait for 500 ns;
+ incomming(i) := rxSerial;
+ end loop;
+
+ -- Check if the received character is expected.
+ assert (incomming(0) = '0') report "Start bit." severity error;
+ assert (incomming(8 downto 1) = data) report "Data bit" severity error;
+ assert (incomming(9) = '1') report "Stop bit." severity error;
+ end procedure;
+
+ begin
+ txSerial <= '1';
+ txWrite <= '0';
+ rxRead <= '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';
+
+ ---------------------------------------------------------------------------
+ -- Send byte to uart.
+ ---------------------------------------------------------------------------
+ SerialSend(x"55");
+ wait until rxEmpty = '0' and clk'event and clk = '1';
+ rxRead <= '1';
+ wait until clk'event and clk = '1';
+ rxRead <= '0';
+ wait until clk'event and clk = '1';
+ assert rxData = x"55" report "rxData" severity error;
+
+ SerialSend(x"62");
+ wait until rxEmpty = '0' and clk'event and clk = '1';
+ rxRead <= '1';
+ wait until clk'event and clk = '1';
+ rxRead <= '0';
+ wait until clk'event and clk = '1';
+ assert rxData = x"62" report "rxData" severity error;
+
+ wait until txFull = '0' and clk'event and clk = '1';
+ txWrite <= '1';
+ txData <= x"55";
+ wait until clk'event and clk = '1';
+ txWrite <= '0';
+ SerialReceive(x"55");
+
+ wait until txFull = '0' and clk'event and clk = '1';
+ txWrite <= '1';
+ txData <= x"62";
+ wait until clk'event and clk = '1';
+ txWrite <= '0';
+ SerialReceive(x"62");
+
+ -- REMARK: Formalize the tests and write more testcases...
+
+ ---------------------------------------------------------------------------
+ -- Test completed.
+ ---------------------------------------------------------------------------
+
+ TestEnd;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Instantiate the uart.
+ -----------------------------------------------------------------------------
+
+ UartInst: Uart
+ generic map(DIVISOR_WIDTH=>4, DATA_WIDTH=>8)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ divisor_i=>"1011",
+ serial_i=>txSerial, serial_o=>rxSerial,
+ empty_o=>rxEmpty, read_i=>rxRead, data_o=>rxData,
+ full_o=>txFull, write_i=>txWrite, data_i=>txData);
+
+end architecture;
1.0.1/bench/vhdl/TestUart.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/bench/vhdl/TestRioSerial.vhd
===================================================================
--- 1.0.1/bench/vhdl/TestRioSerial.vhd (nonexistent)
+++ 1.0.1/bench/vhdl/TestRioSerial.vhd (revision 29)
@@ -0,0 +1,2486 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Contains automatic simulation test code to verify a RioSerial implementation.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Magnus Rosenius, magro732@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE. See the GNU Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+
+-------------------------------------------------------------------------------
+-- TestRioSerial.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+library std;
+use std.textio.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for TestRioSerial.
+-------------------------------------------------------------------------------
+entity TestRioSerial is
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for TestUart.
+-------------------------------------------------------------------------------
+architecture TestRioSerialImpl of TestRioSerial is
+
+ component TestSwitchPort is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ frameValid_i : in std_logic_vector(0 to 63);
+ frameWrite_i : in RioFrameArray(0 to 63);
+ frameComplete_o : out std_logic;
+
+ frameExpected_i : in std_logic;
+ frameRead_i : in RioFrame;
+ frameReceived_o : out std_logic;
+
+ readFrameEmpty_o : out std_logic;
+ readFrame_i : in std_logic;
+ readFrameRestart_i : in std_logic;
+ readFrameAborted_o : out std_logic;
+
+ readWindowEmpty_o : out std_logic;
+ readWindowReset_i : in std_logic;
+ readWindowNext_i : in std_logic;
+
+ readContentEmpty_o : out std_logic;
+ readContent_i : in std_logic;
+ readContentEnd_o : out std_logic;
+ readContentData_o : out std_logic_vector(31 downto 0);
+
+ writeFrameFull_o : out std_logic;
+ writeFrame_i : in std_logic;
+ writeFrameAbort_i : in std_logic;
+ writeContent_i : in std_logic;
+ writeContentData_i : in std_logic_vector(31 downto 0));
+ end component;
+
+ component RioSerial is
+ generic(
+ TIMEOUT_WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
+ linkInitialized_o : out std_logic;
+ inputPortEnable_i : in std_logic;
+ outputPortEnable_i : in std_logic;
+
+ localAckIdWrite_i : in std_logic;
+ clrOutstandingAckId_i : in std_logic;
+ inboundAckId_i : in std_logic_vector(4 downto 0);
+ outstandingAckId_i : in std_logic_vector(4 downto 0);
+ outboundAckId_i : in std_logic_vector(4 downto 0);
+ inboundAckId_o : out std_logic_vector(4 downto 0);
+ outstandingAckId_o : out std_logic_vector(4 downto 0);
+ outboundAckId_o : out std_logic_vector(4 downto 0);
+
+ readFrameEmpty_i : in std_logic;
+ readFrame_o : out std_logic;
+ readFrameRestart_o : out std_logic;
+ readFrameAborted_i : in std_logic;
+
+ readWindowEmpty_i : in std_logic;
+ readWindowReset_o : out std_logic;
+ readWindowNext_o : out std_logic;
+
+ readContentEmpty_i : in std_logic;
+ readContent_o : out std_logic;
+ readContentEnd_i : in std_logic;
+ readContentData_i : in std_logic_vector(31 downto 0);
+
+ writeFrameFull_i : in std_logic;
+ writeFrame_o : out std_logic;
+ writeFrameAbort_o : out std_logic;
+ writeContent_o : out std_logic;
+ writeContentData_o : out std_logic_vector(31 downto 0);
+
+ portInitialized_i : in std_logic;
+ outboundSymbolEmpty_o : out std_logic;
+ outboundSymbolRead_i : in std_logic;
+ outboundSymbol_o : out std_logic_vector(33 downto 0);
+ inboundSymbolFull_o : out std_logic;
+ inboundSymbolWrite_i : in std_logic;
+ inboundSymbol_i : in std_logic_vector(33 downto 0));
+ end component;
+
+ signal clk : std_logic;
+ signal areset_n : std_logic;
+
+ signal uartInbound : std_logic;
+ signal uartOutbound : std_logic;
+
+ signal portLinkTimeout : std_logic_vector(10 downto 0);
+ signal linkInitialized : std_logic;
+ signal inputPortEnable : std_logic;
+ signal outputPortEnable : std_logic;
+
+ signal localAckIdWrite : std_logic;
+ signal clrOutstandingAckId : std_logic;
+ signal inboundAckIdWrite : std_logic_vector(4 downto 0);
+ signal outstandingAckIdWrite : std_logic_vector(4 downto 0);
+ signal outboundAckIdWrite : std_logic_vector(4 downto 0);
+ signal inboundAckIdRead : std_logic_vector(4 downto 0);
+ signal outstandingAckIdRead : std_logic_vector(4 downto 0);
+ signal outboundAckIdRead : std_logic_vector(4 downto 0);
+
+ signal portInitialized : std_logic;
+ signal outboundSymbolEmpty : std_logic;
+ signal outboundSymbolRead : std_logic;
+ signal outboundSymbol : std_logic_vector(33 downto 0);
+ signal inboundSymbolFull : std_logic;
+ signal inboundSymbolWrite : std_logic;
+ signal inboundSymbol : std_logic_vector(33 downto 0);
+
+ signal readFrameEmpty : std_logic;
+ signal readFrame : std_logic;
+ signal readFrameRestart : std_logic;
+ signal readFrameAborted : std_logic;
+ signal readWindowEmpty : std_logic;
+ signal readWindowReset : std_logic;
+ signal readWindowNext : std_logic;
+ signal readContentEmpty : std_logic;
+ signal readContent : std_logic;
+ signal readContentEnd : std_logic;
+ signal readContentData : std_logic_vector(31 downto 0);
+
+ signal writeFrameFull : std_logic;
+ signal writeFrame : std_logic;
+ signal writeFrameAbort : std_logic;
+ signal writeContent : std_logic;
+ signal writeContentData : std_logic_vector(31 downto 0);
+
+ signal frameValid : std_logic_vector(0 to 63);
+ signal frameWrite : RioFrameArray(0 to 63);
+ signal frameComplete : std_logic;
+ signal frameExpected : std_logic;
+ signal frameRead : RioFrame;
+ signal frameReceived : std_logic;
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Clock generation.
+ -----------------------------------------------------------------------------
+ ClockGenerator: process
+ begin
+ clk <= '0';
+ wait for 20 ns;
+ clk <= '1';
+ wait for 20 ns;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Serial protocol test driver.
+ -----------------------------------------------------------------------------
+ TestDriver: process
+
+ ---------------------------------------------------------------------------
+ -- Procedure to receive a symbol.
+ ---------------------------------------------------------------------------
+ procedure ReceiveSymbol(
+ constant symbolType : in std_logic_vector(1 downto 0);
+ constant symbolContent : in std_logic_vector(31 downto 0) := x"00000000") is
+ begin
+ wait until outboundSymbolEmpty = '0' and clk'event and clk = '1';
+
+ assert symbolType = outboundSymbol(33 downto 32)
+ report "Missmatching symbol type:expected=" &
+ integer'image(to_integer(unsigned(symbolType))) &
+ " got=" &
+ integer'image(to_integer(unsigned(outboundSymbol(33 downto 32))))
+ severity error;
+
+ if ((outboundSymbol(33 downto 32) = SYMBOL_CONTROL) or
+ (outboundSymbol(33 downto 32) = SYMBOL_CONTROL)) then
+ assert symbolContent(31 downto 8) = outboundSymbol(31 downto 8)
+ report "Missmatching symbol content:expected=" &
+ integer'image(to_integer(unsigned(symbolContent(31 downto 8)))) &
+ " got=" &
+ integer'image(to_integer(unsigned(outboundSymbol(31 downto 8))))
+ severity error;
+ elsif (outboundSymbol(33 downto 32) = SYMBOL_DATA) then
+ assert symbolContent(31 downto 0) = outboundSymbol(31 downto 0)
+ report "Missmatching symbol content:expected=" &
+ integer'image(to_integer(unsigned(symbolContent(31 downto 0)))) &
+ " got=" &
+ integer'image(to_integer(unsigned(outboundSymbol(31 downto 0))))
+ severity error;
+ end if;
+
+ outboundSymbolRead <= '1';
+ wait until clk'event and clk = '1';
+ outboundSymbolRead <= '0';
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to send a symbol.
+ ---------------------------------------------------------------------------
+ procedure SendSymbol(
+ constant symbolType : in std_logic_vector(1 downto 0);
+ constant symbolContent : in std_logic_vector(31 downto 0) := x"00000000") is
+ begin
+ wait until inboundSymbolFull = '0' and clk'event and clk = '1';
+
+ inboundSymbolWrite <= '1';
+ inboundSymbol <= symbolType & symbolContent;
+
+ wait until clk'event and clk = '1';
+ inboundSymbolWrite <= '0';
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Process variables.
+ ---------------------------------------------------------------------------
+ variable seed1 : positive := 1;
+ variable seed2 : positive := 1;
+ variable payload : RioPayload;
+
+ variable frame : RioFrame;
+
+ begin
+ ---------------------------------------------------------------------------
+ -- Test case initialization.
+ ---------------------------------------------------------------------------
+
+ frameValid <= (others=>'0');
+ frameExpected <= '0';
+
+ portLinkTimeout <= (others=>'1');
+ inputPortEnable <= '1';
+ outputPortEnable <= '1';
+
+ portInitialized <= '0';
+ outboundSymbolRead <= '0';
+ inboundSymbolWrite <= '0';
+ inboundSymbol <= (others => '0');
+
+ localAckIdWrite <= '0';
+ clrOutstandingAckId <= '0';
+ inboundAckIdWrite <= (others=>'0');
+ outstandingAckIdWrite <= (others=>'0');
+ outboundAckIdWrite <= (others=>'0');
+
+ -- Generate a startup reset pulse.
+ areset_n <= '0';
+ wait until clk'event and clk = '1';
+ wait until clk'event and clk = '1';
+ areset_n <= '1';
+ wait until clk'event and clk = '1';
+ wait until clk'event and clk = '1';
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioSerial");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioSerial-TC1");
+ PrintS("Description: Test idle-sequence transmission at startup.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Read transmission port.");
+ PrintS("Result: Idle sequence symbols should be read.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC1-Step1");
+ ---------------------------------------------------------------------------
+
+ -- Make sure only idle-sequences are transmitted at startup.
+ for i in 0 to 1024 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioSerial-TC2");
+ PrintS("Description: Test idle-sequence and status symbol transmission");
+ PrintS(" when the port has been initialized.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Set port initialized and read transmission port.");
+ PrintS("Result: Idle sequence and status symbols should be read.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC2-Step1");
+ ---------------------------------------------------------------------------
+
+ -- Initialize the port to trigger a change of state.
+ portInitialized <= '1';
+
+ -- The transmitter should send idle sequences at startup and a status once
+ -- in a while.
+ for i in 0 to 254 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_NOP, "000"));
+ for i in 0 to 254 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Toggle port initialized pin and check that no status ");
+ PrintS(" symbols are transmitted when uninitialized.");
+ PrintS("Result: Only idle sequences should be read when uninitialized.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC2-Step2");
+ ---------------------------------------------------------------------------
+
+ -- Deassert the port initialized flag.
+ portInitialized <= '0';
+
+ -- Make sure only idle-sequences are transmitted at startup.
+ for i in 0 to 1024 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+
+ -- Initialize the port to trigger a change of state.
+ portInitialized <= '1';
+
+ -- The transmitter should send idle sequences at startup and a status once
+ -- in a while.
+ for i in 0 to 254 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_NOP, "000"));
+ for i in 0 to 254 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Send one error free status symbol to trigger the ");
+ PrintS(" transmission of status symbols with a higher frequency.");
+ PrintS("Result: Idle sequence and status symbols should be read but ");
+ PrintS(" status symbols should be recived more often.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC2-Step3");
+ ---------------------------------------------------------------------------
+
+ -- A received error-free status triggers transmission of status symbols in
+ -- a more rapid past.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- The transmitter should send at least 15 additional statuses after
+ -- receiving an error free status.
+ for j in 0 to 15 loop
+ for i in 0 to 15 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_NOP, "000"));
+ end loop;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 4:");
+ PrintS("Action: Send one errornous status symbol to restart the status ");
+ PrintS(" counting.");
+ PrintS("Result: Idle sequence and status symbols should be read but ");
+ PrintS(" status symbols should still be received more often.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC2-Step4");
+ ---------------------------------------------------------------------------
+
+ -- REMARK: Add this...
+ PrintR("Not implemented.");
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 5:");
+ PrintS("Action: Send one errornous status symbol to restart the status ");
+ PrintS(" counting.");
+ PrintS("Result: Idle sequence and status symbols should be read but ");
+ PrintS(" status symbols should still be received more often.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC2-Step5");
+ ---------------------------------------------------------------------------
+
+ -- Make the link fully initialized by sending 7 additional statuses.
+ for i in 0 to 6 loop
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_NOP, "000"));
+ end loop;
+
+ wait until linkInitialized = '1';
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioSerial-TC3");
+ PrintS("Description: Test port reception.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send an inbound frame with pad after the CRC.");
+ PrintS("Result: The frame should end up in a frame buffer.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step1");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 1;
+ frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- End the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00000", "11111",
+ STYPE1_NOP, "000"));
+
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Send an inbound frame without a pad after the CRC.");
+ PrintS("Result: The frame should end up in a frame buffer.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step2");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 2;
+ frame := RioFrameCreate(ackId=>"00001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- End the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmited frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00001", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Send an inbound frame with maximum size.");
+ PrintS("Result: The frame should end up in a frame buffer.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step3");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 133;
+ frame := RioFrameCreate(ackId=>"00010", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- End the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00010", "11111",
+ STYPE1_NOP, "000"));
+
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 4:");
+ PrintS("Action: Send two packets without end-of-packet in between.");
+ PrintS("Result: Both packets should be accepted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step4");
+ ---------------------------------------------------------------------------
+
+ -- Create the first frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 10;
+ frame := RioFrameCreate(ackId=>"00011", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Start the reception of a frame, implicitly ending the previous.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+ wait until clk'event and clk = '1';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00011", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Create the second frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 13;
+ frame := RioFrameCreate(ackId=>"00100", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- End the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00100", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 5:");
+ PrintS("Action: Start to send a packet. Abort it with stomp. Then send ");
+ PrintS(" another packet.");
+ PrintS("Result: The first packet should be discarded and the second should");
+ PrintS(" be accepted. The retried packet should be acknowledged.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step5");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 7;
+ frame := RioFrameCreate(ackId=>"00101", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Abort the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_STOMP, "000"));
+
+ -- Dont expect the aborted frame anymore.
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the retry was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_RETRY, "00101", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Acknowledge the canceled packet.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_RESTART_FROM_RETRY, "000"));
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 8;
+ frame := RioFrameCreate(ackId=>"00101", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Abort the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00101", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 6:");
+ PrintS("Action: Start to send a packet but dont send any payload. Abort it");
+ PrintS(" with stomp. Then send another packet.");
+ PrintS("Result: The first packet should be discarded and the second should");
+ PrintS(" be accepted. The retried packet should be acknowledged.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step6");
+ ---------------------------------------------------------------------------
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Abort the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_STOMP, "000"));
+
+ -- Receive an idle symbol left in the FIFO before the retry was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_RETRY, "00110", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Acknowledge the canceled packet.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_RESTART_FROM_RETRY, "000"));
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 8;
+ frame := RioFrameCreate(ackId=>"00110", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Abort the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00110", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 7:");
+ PrintS("Action: Start to send a packet with payload, then send a ");
+ PrintS(" link-request. Then send another packet.");
+ PrintS("Result: The first packet should be canceled without any ");
+ PrintS(" confirmation and a link-response should be returned. The");
+ PrintS(" second packet should be accepted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step7");
+ ---------------------------------------------------------------------------
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 9;
+ frame := RioFrameCreate(ackId=>"00111", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Send a link-request/input-status to abort the current packet.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- The frame should be canceled by the link-request, dont expect it anymore.
+ frameExpected <= '0';
+
+ -- Receive link-response indicating normal operation and expected ackId.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00111", "10000",
+ STYPE1_NOP, "000"));
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 10;
+ frame := RioFrameCreate(ackId=>"00111", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Abort the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00111", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 8:");
+ PrintS("Action: Start to send a packet, no payload, then send a ");
+ PrintS(" link-request. Then send another packet.");
+ PrintS("Result: The first packet should be canceled without any ");
+ PrintS(" confirmation and a link-response should be returned. The");
+ PrintS(" second packet should be accepted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step8");
+ ---------------------------------------------------------------------------
+
+ -- Expect an empty packet to be aborted.
+ frameExpected <= '1';
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send a link-request/input-status to abort the current packet.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Dont expect any frames anymore.
+ frameExpected <= '0';
+
+ -- Receive link-response indicating normal operation and expected ackId.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01000", "10000",
+ STYPE1_NOP, "000"));
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 11;
+ frame := RioFrameCreate(ackId=>"01000", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Abort the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01000", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 9:");
+ PrintS("Action: Send a packet when no buffers is available. Reset receiver");
+ PrintS(" with link-request.");
+ PrintS("Result: A packet-retry should be transmitted and receiver should");
+ PrintS(" enter input-retry-stopped.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step9");
+ ---------------------------------------------------------------------------
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 11;
+ frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ SendSymbol(SYMBOL_DATA, frame.payload(0));
+
+ -- Receive notification about that the packet needs to be retried.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_RETRY, "01001", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Check the status of the input port and verify the input-retry-stopped state.
+ -- This should also set the receiver into normal operation.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "00100",
+ STYPE1_NOP, "000"));
+
+ -- Check the status of the input port and verify the input-retry-stopped state.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "10000",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 10:");
+ PrintS("Action: Send a packet when no buffers is available. Reset receiver");
+ PrintS(" with restart-from-retry.");
+ PrintS("Result: A packet-retry should be transmitted and receiver should");
+ PrintS(" enter input-retry-stopped.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step10");
+ ---------------------------------------------------------------------------
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 11;
+ frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ SendSymbol(SYMBOL_DATA, frame.payload(0));
+
+ -- Receive notification about that the packet needs to be retried.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_RETRY, "01001", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Acknowledge the retried packet.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_RESTART_FROM_RETRY, "000"));
+
+ -- Check the status of the input port and verify the input-retry-stopped state.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "10000",
+ STYPE1_NOP, "000"));
+
+ -- Always receive a status after a link response when leaving input-error-stopped.
+-- ReceiveSymbol(SYMBOL_CONTROL,
+-- RioControlSymbolCreate(STYPE0_STATUS, "01001", "11111",
+-- STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 11:");
+ PrintS("Action: Start a new packet when in input-retry-stopped state.");
+ PrintS("Result: The packet should be discarded.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step11");
+ ---------------------------------------------------------------------------
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 11;
+ frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ SendSymbol(SYMBOL_DATA, frame.payload(0));
+
+ -- Receive notification about that the packet needs to be retried.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_RETRY, "01001", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Create a packet and send it. It should be discarded.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 12;
+ frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Acknowledge the retried packet.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_RESTART_FROM_RETRY, "000"));
+
+ -- Create a packet and send it.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 13;
+ frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01001", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 12:");
+ PrintS("Action: Send an erronous control-symbol. Then restore with");
+ PrintS(" link-request.");
+ PrintS("Result: Receiver should enter input-error-stopped and return to");
+ PrintS(" normal operation after the link-request was receiver.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step12");
+ ---------------------------------------------------------------------------
+
+ -- Create, corrupt and send a control symbol.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000") xor x"00100000");
+
+ -- Receive a packet-not-accepted indicating error in control-symbol crc.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_NOT_ACCEPTED, "00000", "00010",
+ STYPE1_NOP, "000"));
+
+ -- Create a packet and send it. It should be discarded.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 14;
+ frame := RioFrameCreate(ackId=>"01010", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Make the receiver go back to normal operation by sending a link-request.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01010", "00101",
+ STYPE1_NOP, "000"));
+
+ -- Always receive a status after a link response when leaving input-error-stopped.
+-- ReceiveSymbol(SYMBOL_CONTROL,
+-- RioControlSymbolCreate(STYPE0_STATUS, "01010", "11111",
+-- STYPE1_NOP, "000"));
+
+ -- Create a packet and send it.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 15;
+ frame := RioFrameCreate(ackId=>"01010", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01010", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 13:");
+ PrintS("Action: Send an erronous packet. Then restore with link-request.");
+ PrintS("Result: Receiver should enter input-error-stopped and return to");
+ PrintS(" normal operation after the link-request was receiver.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step13");
+ ---------------------------------------------------------------------------
+
+ -- Create a packet and send it with a bit error. It should be discarded.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 15;
+ frame := RioFrameCreate(ackId=>"01011", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frame.payload(0) := frame.payload(0) xor x"00000010";
+ frameExpected <= '1';
+ frameRead <= frame;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Receive a packet-not-accepted indicating error in control-symbol crc.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_NOT_ACCEPTED, "00000", "00100",
+ STYPE1_NOP, "000"));
+
+ -- Dont expect any frame anymore.
+ frameExpected <= '0';
+
+ -- Make the receiver go back to normal operation by sending a link-request.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01011", "00101",
+ STYPE1_NOP, "000"));
+
+ -- Send a new frame without error.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 16;
+ frame := RioFrameCreate(ackId=>"01011", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01011", "11111",
+ STYPE1_NOP, "000"));
+
+ -- REMARK: Complete with some more error situations: invalid ackId, too
+ -- short packet, too long packet, etc...
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioSerial-TC4");
+ PrintS("Description: Test port transmission.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send an outbound frame.");
+ PrintS("Result: The frame should be read from the frame buffer and ");
+ PrintS(" received as symbols.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step1");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 3;
+ frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(0) <= '1';
+ frameWrite(0) <= frame;
+
+ -- Make sure the transmitter fills in the correct ackId and dont use the
+ -- one in the input packet.
+ frameWrite(0).payload(0)(31 downto 27) <= "UUUUU";
+
+ -- Receive an idle symbol left in the FIFO before the start of the frame was
+ -- generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive the start of the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Receive the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Wait for the frame to complete.
+ wait until frameComplete = '1';
+ frameValid(0) <= '0';
+
+ -- Receive the end of the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send acknowledge that the frame was received.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00000", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Send an outbound packet with maximum length.");
+ PrintS("Result: The packet should be fragmented and received in symbols.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step2");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 133;
+ frame := RioFrameCreate(ackId=>"00001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(1) <= '1';
+ frameWrite(1) <= frame;
+
+ -- Receive an idle symbol left in the FIFO before the start of the frame was
+ -- generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive the start of the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Receive the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Wait for the frame to complete.
+ wait until frameComplete = '1';
+ frameValid(1) <= '0';
+
+ -- Receive the end of the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send acknowledge that the frame was received.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00001", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Send a packet and confirm it with packet-retry.");
+ PrintS("Result: A restart-from-retry should be transmitted and the packet");
+ PrintS(" should be retransmitted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step3");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 4;
+ frame := RioFrameCreate(ackId=>"00010", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(2) <= '1';
+ frameWrite(2) <= frame;
+
+ -- Receive an idle symbol left in the FIFO before the start of the frame was
+ -- generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive the start of the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Receive the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Receive the end of the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send packet-retry that the frame should be retransmitted.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_RETRY, "00010", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive the acknowledgement for the retransmission.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_RESTART_FROM_RETRY, "000"));
+
+ -- Receive the start of the retransmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Receive the data symbols of the retransmitted frame.
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Wait for the frame to complete.
+ wait until frameComplete = '1' and clk'event and clk = '1';
+ frameValid(2) <= '0';
+
+ -- Receive the end of the retransmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send acknowledge that the frame was received.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00010", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 4:");
+ PrintS("Action: Send a packet and confirm it with packet-not-accepted. ");
+ PrintS("Result: A link-request should be transmitted and the packet should");
+ PrintS(" be retransmitted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step4");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 5;
+ frame := RioFrameCreate(ackId=>"00011", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(3) <= '1';
+ frameWrite(3) <= frame;
+
+ -- Receive the start of the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Receive the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Receive the end of the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send packet-retry that the frame should be retransmitted.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_NOT_ACCEPTED, "00000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive the acknowledgement for the retransmission.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00011", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive the start of the retransmitted frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Receive the data symbols of the retransmitted frame.
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Wait for the frame to complete.
+ wait until frameComplete = '1';
+ frameValid(3) <= '0';
+
+ -- Receive the end of the retransmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send acknowledge that the frame was received.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00011", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 5:");
+ PrintS("Action: Let a packet timeout expire. Then answer with link-response.");
+ PrintS("Result: A link-request should be transmitted and the packet should");
+ PrintS(" be retransmitted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step5");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 5;
+ frame := RioFrameCreate(ackId=>"00100", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(4) <= '1';
+ frameWrite(4) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Wait a while to let the timer expire and receive the link-request.
+ for i in 0 to 2048 loop
+ wait until clk'event and clk = '1';
+ end loop;
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Send a link-response to make the transmitter to back to normal mode.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00100", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive the retransmitted frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Wait for the frame to complete.
+ wait until frameComplete = '1';
+ frameValid(4) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send acknowledge that the frame was received.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00100", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 6:");
+ PrintS("Action: Let a packet timeout expire. Then answer with link-response");
+ Prints(" that indicates that the packet was received.");
+ PrintS("Result: A link-request should be transmitted and the packet should");
+ PrintS(" not be retransmitted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step6");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 6;
+ frame := RioFrameCreate(ackId=>"00101", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(5) <= '1';
+ frameWrite(5) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(5) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Wait a while to let the timer expire and receive the link-request.
+ for i in 0 to 2048 loop
+ wait until clk'event and clk = '1';
+ end loop;
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Send a link-response that indicates that the frame was received to make
+ -- the transmitter to back to normal mode.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00110", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 7:");
+ PrintS("Action: Let a packet timeout expire. No more replies.");
+ PrintS("Result: Three link-requests should be transmitted. When the third");
+ PrintS(" times out the link will be restarted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step7");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 7;
+ frame := RioFrameCreate(ackId=>"00110", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(6) <= '1';
+ frameWrite(6) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Wait a while to let the timer expire and receive the link-request.
+ for i in 0 to 2048 loop
+ wait until clk'event and clk = '1';
+ end loop;
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Wait a while to let the timer expire and receive the link-request.
+ for i in 0 to 2048 loop
+ wait until clk'event and clk = '1';
+ end loop;
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Wait a while to let the timer expire and receive the link-request.
+ for i in 0 to 2048 loop
+ wait until clk'event and clk = '1';
+ end loop;
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Wait a while to let the timer expire and receive the link-request.
+ for i in 0 to 2048 loop
+ wait until clk'event and clk = '1';
+ end loop;
+
+ -- Reinitialize the transmitter.
+ for i in 0 to 255 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_NOP, "000"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00110", "11111",
+ STYPE1_NOP, "000"));
+ for j in 0 to 14 loop
+ for i in 0 to 15 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_NOP, "000"));
+ end loop;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(6) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00110", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 8:");
+ PrintS("Action: Let a packet timeout expire. Then answer with totally ");
+ PrintS(" unexpected ackId.");
+ PrintS("Result: A link request should be transmitted and the link should ");
+ PrintS(" be restarted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step8");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 8;
+ frame := RioFrameCreate(ackId=>"00111", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(7) <= '1';
+ frameWrite(7) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Wait a while to let the timer expire and receive the link-request.
+ for i in 0 to 2048 loop
+ wait until clk'event and clk = '1';
+ end loop;
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Send a link-response with unexpected ackId.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "10000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Reinitialize the transmitter.
+ for i in 0 to 255 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_NOP, "000"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00111", "11111",
+ STYPE1_NOP, "000"));
+ for j in 0 to 14 loop
+ for i in 0 to 15 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_NOP, "000"));
+ end loop;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(7) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00111", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 9:");
+ PrintS("Action: Send status with unexpected ackId in normal operation.");
+ PrintS("Result: The transmitter should disregard the error.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step9");
+ ---------------------------------------------------------------------------
+
+ -- Send a status with unexpected ackId.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "10000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive no change.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 10:");
+ PrintS("Action: Send packet-retry with unexpected ackId in normal operation.");
+ PrintS("Result: The transmitter should enter output-error-stopped.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step10");
+ ---------------------------------------------------------------------------
+
+ -- Send a packet-retry with unexpected ackId.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_RETRY, "10000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive link-request.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Send a link-response with unexpected ackId.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 10;
+ frame := RioFrameCreate(ackId=>"01000", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(8) <= '1';
+ frameWrite(8) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(8) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01000", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 11:");
+ PrintS("Action: Send packet-accepted with unexpected ackId in normal ");
+ PrintS(" operation.");
+ PrintS("Result: The transmitter should enter output-error-stopped.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step11");
+ ---------------------------------------------------------------------------
+
+ -- Send a packet-accepted with unexpected ackId.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "10000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive link-request.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Send a link-response with unexpected ackId.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 11;
+ frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(9) <= '1';
+ frameWrite(9) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(9) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01001", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 12:");
+ PrintS("Action: Send a packet and then accept it with unexpected ackId.");
+ PrintS("Result: The transmitter should enter output-error-stopped.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step12");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 12;
+ frame := RioFrameCreate(ackId=>"01010", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(10) <= '1';
+ frameWrite(10) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(10) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send unexpected ackId in packet-accepted.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "10000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive link-request.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Send a link-response with expected ackId.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01011", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 13:");
+ PrintS("Action: Set two valid packets.");
+ PrintS("Result: The two packet should be sent without waiting for ");
+ PrintS(" packet-accepted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step13");
+ ---------------------------------------------------------------------------
+
+ -- Create the first frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 13;
+ frame := RioFrameCreate(ackId=>"01011", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(11) <= '1';
+ frameWrite(11) <= frame;
+
+ -- Create the second frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 14;
+ frame := RioFrameCreate(ackId=>"01100", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(12) <= '1';
+ frameWrite(12) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frameWrite(11).length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frameWrite(11).payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(11) <= '0';
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frameWrite(12).length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frameWrite(12).payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(12) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+
+ -- Send packet-accepted for both packets.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01011", "11111",
+ STYPE1_NOP, "000"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01100", "11111",
+ STYPE1_NOP, "000"));
+
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 14:");
+ PrintS("Action: Set maximum number of valid packets.");
+ PrintS("Result: Maximum 31 packets should be sent without waiting for ");
+ PrintS(" packet-accepted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step14");
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ -- Create the frames.
+ ---------------------------------------------------------------------------
+
+ for j in 0 to 47 loop
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := j+13;
+ frame := RioFrameCreate(ackId=>std_logic_vector(to_unsigned((j+13) mod 32, 5)), vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(j+13) <= '1';
+ frameWrite(j+13) <= frame;
+ end loop;
+
+ ---------------------------------------------------------------------------
+ -- Receive the frames.
+ ---------------------------------------------------------------------------
+
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ for j in 0 to 30 loop
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frameWrite(j+13).length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frameWrite(j+13).payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(j+13) <= '0';
+ end loop;
+
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_IDLE);
+
+
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01101", "11111",
+ STYPE1_NOP, "000"));
+
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step X:");
+ PrintS("Action: Start sending an outbound packet and while in transmission, ");
+ PrintS(" start and complete an inbound packet.");
+ PrintS("Result: The ack for the inbound packet should be inserted into the");
+ PrintS(" outbound packet.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-StepX");
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step X:");
+ PrintS("Action: Send a packet but not all content is available yet.");
+ PrintS("Result: Idle symbols should be inserted into the packet.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-StepX");
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ -- REMARK: Send long frames with a CRC in the middle...
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ -- Test completed.
+ ---------------------------------------------------------------------------
+
+ TestEnd;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Instantiate the uart.
+ -----------------------------------------------------------------------------
+
+ TestPort: TestSwitchPort
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ frameValid_i=>frameValid, frameWrite_i=>frameWrite, frameComplete_o=>frameComplete,
+ frameExpected_i=>frameExpected, frameRead_i=>frameRead, frameReceived_o=>frameReceived,
+ readFrameEmpty_o=>readFrameEmpty, readFrame_i=>readFrame,
+ readFrameRestart_i=>readFrameRestart, readFrameAborted_o=>readFrameAborted,
+ readWindowEmpty_o=>readWindowEmpty,
+ readWindowReset_i=>readWindowReset, readWindowNext_i=>readWindowNext,
+ readContentEmpty_o=>readContentEmpty, readContent_i=>readContent,
+ readContentEnd_o=>readContentEnd, readContentData_o=>readContentData,
+ writeFrameFull_o=>writeFrameFull, writeFrame_i=>writeFrame, writeFrameAbort_i=>writeFrameAbort,
+ writeContent_i=>writeContent, writeContentData_i=>writeContentData);
+
+ TestPhy: RioSerial
+ generic map(
+ TIMEOUT_WIDTH=>11)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ portLinkTimeout_i=>portLinkTimeout,
+ linkInitialized_o=>linkInitialized,
+ inputPortEnable_i=>inputPortEnable,
+ outputPortEnable_i=>outputPortEnable,
+ localAckIdWrite_i=>localAckIdWrite,
+ clrOutstandingAckId_i=>clrOutstandingAckId,
+ inboundAckId_i=>inboundAckIdWrite,
+ outstandingAckId_i=>outstandingAckIdWrite,
+ outboundAckId_i=>outboundAckIdWrite,
+ inboundAckId_o=>inboundAckIdRead,
+ outstandingAckId_o=>outstandingAckIdRead,
+ outboundAckId_o=>outboundAckIdRead,
+ readFrameEmpty_i=>readFrameEmpty, readFrame_o=>readFrame, readFrameRestart_o=>readFrameRestart,
+ readFrameAborted_i=>readFrameAborted,
+ readWindowEmpty_i=>readWindowEmpty,
+ readWindowReset_o=>readWindowReset, readWindowNext_o=>readWindowNext,
+ readContentEmpty_i=>readContentEmpty,
+ readContent_o=>readContent, readContentEnd_i=>readContentEnd, readContentData_i=>readContentData,
+ writeFrameFull_i=>writeFrameFull, writeFrame_o=>writeFrame, writeFrameAbort_o=>writeFrameAbort,
+ writeContent_o=>writeContent, writeContentData_o=>writeContentData,
+ portInitialized_i=>portInitialized,
+ outboundSymbolEmpty_o=>outboundSymbolEmpty, outboundSymbolRead_i=>outboundSymbolRead,
+ outboundSymbol_o=>outboundSymbol,
+ inboundSymbolFull_o=>inboundSymbolFull, inboundSymbolWrite_i=>inboundSymbolWrite,
+ inboundSymbol_i=>inboundSymbol);
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+library std;
+use std.textio.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+entity TestSwitchPort is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ frameValid_i : in std_logic_vector(0 to 63);
+ frameWrite_i : in RioFrameArray(0 to 63);
+ frameComplete_o : out std_logic;
+
+ frameExpected_i : in std_logic;
+ frameRead_i : in RioFrame;
+ frameReceived_o : out std_logic;
+
+ readFrameEmpty_o : out std_logic;
+ readFrame_i : in std_logic;
+ readFrameRestart_i : in std_logic;
+ readFrameAborted_o : out std_logic;
+
+ readWindowEmpty_o : out std_logic;
+ readWindowReset_i : in std_logic;
+ readWindowNext_i : in std_logic;
+
+ readContentEmpty_o : out std_logic;
+ readContent_i : in std_logic;
+ readContentEnd_o : out std_logic;
+ readContentData_o : out std_logic_vector(31 downto 0);
+
+ writeFrameFull_o : out std_logic;
+ writeFrame_i : in std_logic;
+ writeFrameAbort_i : in std_logic;
+ writeContent_i : in std_logic;
+ writeContentData_i : in std_logic_vector(31 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+architecture TestSwitchPortImpl of TestSwitchPort is
+begin
+
+ -----------------------------------------------------------------------------
+ --
+ -----------------------------------------------------------------------------
+ FrameSender: process
+ variable frameIndex : natural range 0 to 70;
+ variable backIndex, frontIndex : natural range 0 to 63;
+ begin
+ readFrameEmpty_o <= '1';
+ readFrameAborted_o <= '0';
+ readWindowEmpty_o <= '1';
+ readContentEmpty_o <= '1';
+ readContentEnd_o <= '0';
+ readContentData_o <= (others=>'U');
+ frameComplete_o <= '0';
+ backIndex := 0;
+ frontIndex := 0;
+ wait until areset_n = '1';
+
+ loop
+ wait until clk'event and clk = '1';
+
+ if (readFrame_i = '1') then
+ assert (frontIndex - backIndex) >= 0 report "Unexpected readFrame." severity error;
+ if(backIndex < 63) then
+ backIndex := backIndex + 1;
+ else
+ backIndex := 0;
+ end if;
+ end if;
+
+ if (readWindowReset_i = '1') then
+ frameIndex := 0;
+ frontIndex := backIndex;
+ readContentEnd_o <= '0';
+ readContentData_o <= (others=>'U');
+ end if;
+
+ if (readWindowNext_i = '1') then
+ assert frameIndex = frameWrite_i(frontIndex).length report "Did not read all frame content." severity error;
+ frameComplete_o <= '1';
+ readContentEnd_o <= '0';
+ readContentData_o <= (others=>'U');
+ frameIndex := 0;
+ if(frontIndex < 63) then
+ frontIndex := frontIndex + 1;
+ else
+ frontIndex := 0;
+ end if;
+ else
+ frameComplete_o <= '0';
+ end if;
+
+ if (readFrameRestart_i = '1') then
+ frameIndex := 0;
+ readContentEnd_o <= '0';
+ readContentData_o <= (others=>'U');
+ end if;
+
+ if (readContent_i = '1') then
+ assert frameValid_i(frontIndex) = '1' report "Unexpected content read." severity error;
+ if (frameIndex /= frameWrite_i(frontIndex).length) then
+ readContentEnd_o <= '0';
+ readContentData_o <= frameWrite_i(frontIndex).payload(frameIndex);
+ frameIndex := frameIndex + 1;
+ else
+ readContentEnd_o <= '1';
+ readContentData_o <= (others=>'U');
+ end if;
+ end if;
+
+ if(frameValid_i(frontIndex) = '1') then
+ readFrameEmpty_o <= '0';
+ readWindowEmpty_o <= '0';
+ readContentEmpty_o <= '0';
+ else
+ readFrameEmpty_o <= '1';
+ readWindowEmpty_o <= '1';
+ readContentEmpty_o <= '1';
+ end if;
+
+ end loop;
+ end process;
+
+ -----------------------------------------------------------------------------
+ --
+ -----------------------------------------------------------------------------
+ FrameReader: process
+ type StateType is (STATE_IDLE, STATE_READ, STATE_UPDATE);
+ variable state : StateType;
+ variable frameIndex : natural range 0 to 69;
+ begin
+ writeFrameFull_o <= '1';
+ frameReceived_o <= '0';
+ wait until areset_n = '1';
+
+ state := STATE_IDLE;
+
+ loop
+ wait until clk'event and clk = '1';
+
+ case state is
+ when STATE_IDLE =>
+ frameReceived_o <= '0';
+ if (frameExpected_i = '1') then
+ state := STATE_READ;
+ frameIndex := 0;
+ writeFrameFull_o <= '0';
+ end if;
+ assert writeFrame_i = '0' report "Unexpected frame received." severity error;
+ --assert writeFrameAbort_i = '0' report "Unexpected frame aborted received." severity error;
+ assert writeContent_i = '0' report "Unexpected content received." severity error;
+
+ when STATE_READ =>
+ if (writeFrame_i = '1') then
+ state := STATE_UPDATE;
+ frameReceived_o <= '1';
+ writeFrameFull_o <= '1';
+ assert frameIndex = frameRead_i.length report "Did not finish the expected frame." severity error;
+ end if;
+ if (writeFrameAbort_i = '1') then
+ frameIndex := 0;
+ end if;
+ if (writeContent_i = '1') then
+ assert writeContentData_i = frameRead_i.payload(frameIndex)
+ report "Unexpected frame content received." severity error;
+ frameIndex := frameIndex + 1;
+ end if;
+ if (frameExpected_i = '0') then
+ state := STATE_IDLE;
+ end if;
+
+ when STATE_UPDATE =>
+ if (frameExpected_i = '0') then
+ state := STATE_IDLE;
+ end if;
+
+ end case;
+ end loop;
+ end process;
+
+end architecture;
1.0.1/bench/vhdl/TestRioSerial.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/bench/vhdl/TestRioPacketBuffer.vhd
===================================================================
--- 1.0.1/bench/vhdl/TestRioPacketBuffer.vhd (nonexistent)
+++ 1.0.1/bench/vhdl/TestRioPacketBuffer.vhd (revision 29)
@@ -0,0 +1,2247 @@
+-------------------------------------------------------------------------------
+--
+-- 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)) 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 = '0')
+ report "Unexpected content end." severity error;
+
+ outboundReadContent <= '0';
+ end procedure;
+
+ procedure SetOutboundReadContentEnd is
+ begin
+ outboundReadContent <= '1';
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+
+ assert (outboundReadContentEnd = '1')
+ 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 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;
+
+ SetOutboundReadContentEnd;
+ 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 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;
+
+ SetOutboundReadContentEnd;
+ 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 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;
+
+ SetOutboundReadContentEnd;
+ 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 2 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;
+
+ SetOutboundReadContentEnd;
+ 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 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;
+
+ SetOutboundReadContentEnd;
+ 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 2 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;
+
+ SetOutboundReadContentEnd;
+ 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 2 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;
+
+ SetOutboundReadContentEnd;
+ 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 2 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;
+
+ SetOutboundReadContentEnd;
+ 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 2 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;
+
+ SetOutboundReadContentEnd;
+ 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 2 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;
+
+ SetOutboundReadContentEnd;
+ 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 30 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;
+
+ SetOutboundReadContentEnd;
+ 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 68 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;
+
+ SetOutboundReadContentEnd;
+ 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 68 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;
+
+ SetOutboundReadContentEnd;
+ 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 3 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;
+
+ SetOutboundReadContentEnd;
+ 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)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadContentEnd;
+ 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 3 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;
+
+ SetOutboundReadContentEnd;
+ 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 3 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;
+
+ SetOutboundReadContentEnd;
+ 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 3 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;
+
+ SetOutboundReadContentEnd;
+ 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 3 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;
+
+ SetOutboundReadContentEnd;
+ 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)));
+ 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;
+
+ SetOutboundReadContentEnd;
+ 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)));
+ 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;
+
+ SetOutboundReadContentEnd;
+ 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)));
+ 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;
+
+ SetOutboundReadContentEnd;
+ 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;
1.0.1/bench/vhdl/TestRioPacketBuffer.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/rtl/vhdl/RioSwitch.vhd
===================================================================
--- 1.0.1/rtl/vhdl/RioSwitch.vhd (nonexistent)
+++ 1.0.1/rtl/vhdl/RioSwitch.vhd (revision 29)
@@ -0,0 +1,2473 @@
+-------------------------------------------------------------------------------
+--
+-- 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);
+ 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;
+ 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),
+ 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;
+ 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_ERROR,
+ 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';
+ elsif (clk'event and clk = '1') then
+ readContent_o <= '0';
+ readFrame_o <= '0';
+
+ 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_ERROR;
+ end if;
+ else
+ -- End of frame.
+ -- The frame is too short to contain a valid frame. Discard it.
+ readFrame_o <= '1';
+ masterState <= STATE_ERROR;
+ end if;
+
+ when STATE_ERROR =>
+ ---------------------------------------------------------------------
+ -- Wait one tick for the packet buffer to update its outputs. Then
+ -- start waiting for a new packet.
+ ---------------------------------------------------------------------
+
+ masterState <= STATE_IDLE;
+
+ 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 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 (lookupAck = '0') then
+ if (lookupStb_i = '1') then
+ lookupAck <= '1';
+ end if;
+ 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) and activeCycle;
+ 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
+ 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 := 0;
+ 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 ((activeCycle = '1') and (selectedSlave = i)) else '0';
+ slaveStb_o(i) <= masterStb_i(selectedMaster) when ((activeCycle = '1') and (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;
+
+end architecture;
1.0.1/rtl/vhdl/RioSwitch.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/rtl/vhdl/RioCommon.vhd
===================================================================
--- 1.0.1/rtl/vhdl/RioCommon.vhd (nonexistent)
+++ 1.0.1/rtl/vhdl/RioCommon.vhd (revision 29)
@@ -0,0 +1,1138 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Contains commonly used types, functions, procedures and entities used in
+-- the RapidIO IP library project.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Magnus Rosenius, magro732@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE. See the GNU Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+
+-------------------------------------------------------------------------------
+-- RioCommon library.
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+use std.textio.all;
+
+
+-------------------------------------------------------------------------------
+-- RioCommon package description.
+-------------------------------------------------------------------------------
+package rio_common is
+ -----------------------------------------------------------------------------
+ -- Commonly used types.
+ -----------------------------------------------------------------------------
+ type Array1 is array (natural range <>) of
+ std_logic;
+ type Array2 is array (natural range <>) of
+ std_logic_vector(1 downto 0);
+ type Array3 is array (natural range <>) of
+ std_logic_vector(2 downto 0);
+ type Array4 is array (natural range <>) of
+ std_logic_vector(3 downto 0);
+ type Array5 is array (natural range <>) of
+ std_logic_vector(4 downto 0);
+ type Array8 is array (natural range <>) of
+ std_logic_vector(7 downto 0);
+ type Array9 is array (natural range <>) of
+ std_logic_vector(8 downto 0);
+ type Array10 is array (natural range <>) of
+ std_logic_vector(9 downto 0);
+ type Array16 is array (natural range <>) of
+ std_logic_vector(15 downto 0);
+ type Array32 is array (natural range <>) of
+ std_logic_vector(31 downto 0);
+ type Array34 is array (natural range <>) of
+ std_logic_vector(33 downto 0);
+
+ -----------------------------------------------------------------------------
+ -- Commonly used constants.
+ -----------------------------------------------------------------------------
+
+ -- Symbol types between the serial and the PCS layer.
+ constant SYMBOL_IDLE : std_logic_vector(1 downto 0) := "00";
+ constant SYMBOL_CONTROL : std_logic_vector(1 downto 0) := "01";
+ constant SYMBOL_ERROR : std_logic_vector(1 downto 0) := "10";
+ constant SYMBOL_DATA : std_logic_vector(1 downto 0) := "11";
+
+ -- STYPE0 constants.
+ constant STYPE0_PACKET_ACCEPTED : std_logic_vector(2 downto 0) := "000";
+ constant STYPE0_PACKET_RETRY : std_logic_vector(2 downto 0) := "001";
+ constant STYPE0_PACKET_NOT_ACCEPTED : std_logic_vector(2 downto 0) := "010";
+ constant STYPE0_RESERVED : std_logic_vector(2 downto 0) := "011";
+ constant STYPE0_STATUS : std_logic_vector(2 downto 0) := "100";
+ constant STYPE0_VC_STATUS : std_logic_vector(2 downto 0) := "101";
+ constant STYPE0_LINK_RESPONSE : std_logic_vector(2 downto 0) := "110";
+ constant STYPE0_IMPLEMENTATION_DEFINED : std_logic_vector(2 downto 0) := "111";
+
+ -- STYPE1 constants.
+ constant STYPE1_START_OF_PACKET : std_logic_vector(2 downto 0) := "000";
+ constant STYPE1_STOMP : std_logic_vector(2 downto 0) := "001";
+ constant STYPE1_END_OF_PACKET : std_logic_vector(2 downto 0) := "010";
+ constant STYPE1_RESTART_FROM_RETRY : std_logic_vector(2 downto 0) := "011";
+ constant STYPE1_LINK_REQUEST : std_logic_vector(2 downto 0) := "100";
+ constant STYPE1_MULTICAST_EVENT : std_logic_vector(2 downto 0) := "101";
+ constant STYPE1_RESERVED : std_logic_vector(2 downto 0) := "110";
+ constant STYPE1_NOP : std_logic_vector(2 downto 0) := "111";
+
+ -- FTYPE constants.
+ constant FTYPE_REQUEST_CLASS : std_logic_vector(3 downto 0) := "0010";
+ constant FTYPE_WRITE_CLASS : std_logic_vector(3 downto 0) := "0101";
+ constant FTYPE_STREAMING_WRITE_CLASS : std_logic_vector(3 downto 0) := "0110";
+ constant FTYPE_MAINTENANCE_CLASS : std_logic_vector(3 downto 0) := "1000";
+ constant FTYPE_RESPONSE_CLASS : std_logic_vector(3 downto 0) := "1101";
+ constant FTYPE_DOORBELL_CLASS : std_logic_vector(3 downto 0) := "1010";
+ constant FTYPE_MESSAGE_CLASS : std_logic_vector(3 downto 0) := "0010";
+
+ -- TTYPE Constants
+ constant TTYPE_MAINTENANCE_READ_REQUEST : std_logic_vector(3 downto 0) := "0000";
+ constant TTYPE_MAINTENANCE_WRITE_REQUEST : std_logic_vector(3 downto 0) := "0001";
+ constant TTYPE_MAINTENANCE_READ_RESPONSE : std_logic_vector(3 downto 0) := "0010";
+ constant TTYPE_MAINTENANCE_WRITE_RESPONSE : std_logic_vector(3 downto 0) := "0011";
+ constant TTYPE_NREAD_TRANSACTION : std_logic_vector(3 downto 0) := "0100";
+ constant TTYPE_NWRITE_TRANSACTION : std_logic_vector(3 downto 0) := "0100";
+
+ constant LINK_REQUEST_CMD_RESET_DEVICE : std_logic_vector(2 downto 0) := "011";
+ constant LINK_REQUEST_CMD_INPUT_STATUS : std_logic_vector(2 downto 0) := "100";
+
+ constant PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID : std_logic_vector(4 downto 0) := "00001";
+ constant PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC : std_logic_vector(4 downto 0) := "00010";
+ constant PACKET_NOT_ACCEPTED_CAUSE_NON_MAINTENANCE_STOPPED : std_logic_vector(4 downto 0) := "00011";
+ constant PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC : std_logic_vector(4 downto 0) := "00100";
+ constant PACKET_NOT_ACCEPTED_CAUSE_INVALID_CHARACTER : std_logic_vector(4 downto 0) := "00101";
+ constant PACKET_NOT_ACCEPTED_CAUSE_NO_RESOURCES : std_logic_vector(4 downto 0) := "00110";
+ constant PACKET_NOT_ACCEPTED_CAUSE_LOSS_DESCRAMBLER : std_logic_vector(4 downto 0) := "00111";
+ constant PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR : std_logic_vector(4 downto 0) := "11111";
+
+ -----------------------------------------------------------------------------
+ -- Types used in simulations.
+ -----------------------------------------------------------------------------
+ type ByteArray is array (natural range <>) of
+ std_logic_vector(7 downto 0);
+ type HalfwordArray is array (natural range <>) of
+ std_logic_vector(15 downto 0);
+ type WordArray is array (natural range <>) of
+ std_logic_vector(31 downto 0);
+ type DoublewordArray is array (natural range <>) of
+ std_logic_vector(63 downto 0);
+
+ -- Type defining a RapidIO frame.
+ type RioFrame is record
+ length : natural range 0 to 69;
+ payload : WordArray(0 to 68);
+ end record;
+ type RioFrameArray is array (natural range <>) of RioFrame;
+
+ -- Type defining a RapidIO payload.
+ type RioPayload is record
+ length : natural range 0 to 133;
+ data : HalfwordArray(0 to 132);
+ end record;
+
+ -----------------------------------------------------------------------------
+ -- Crc5 calculation function.
+ -- ITU, polynom=0x15.
+ -----------------------------------------------------------------------------
+ function Crc5(constant data : in std_logic_vector(18 downto 0);
+ constant crc : in std_logic_vector(4 downto 0))
+ return std_logic_vector;
+
+ ---------------------------------------------------------------------------
+ -- Create a RapidIO physical layer control symbol.
+ ---------------------------------------------------------------------------
+ function RioControlSymbolCreate(
+ constant stype0 : in std_logic_vector(2 downto 0);
+ constant parameter0 : in std_logic_vector(4 downto 0);
+ constant parameter1 : in std_logic_vector(4 downto 0);
+ constant stype1 : in std_logic_vector(2 downto 0);
+ constant cmd : in std_logic_vector(2 downto 0))
+ return std_logic_vector;
+
+ -----------------------------------------------------------------------------
+ -- Crc16 calculation function.
+ -- CITT, polynom=0x1021.
+ -----------------------------------------------------------------------------
+ function Crc16(constant data : in std_logic_vector(15 downto 0);
+ constant crc : in std_logic_vector(15 downto 0))
+ return std_logic_vector;
+
+ ---------------------------------------------------------------------------
+ -- Create a randomly initialized data array.
+ ---------------------------------------------------------------------------
+ procedure CreateRandomPayload(
+ variable payload : out HalfwordArray(0 to 132);
+ variable seed1 : inout positive;
+ variable seed2 : inout positive);
+ procedure CreateRandomPayload(
+ variable payload : out DoublewordArray(0 to 31);
+ variable seed1 : inout positive;
+ variable seed2 : inout positive);
+
+ ---------------------------------------------------------------------------
+ -- Create a generic RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioFrameCreate(
+ constant ackId : in std_logic_vector(4 downto 0);
+ constant vc : in std_logic;
+ constant crf : in std_logic;
+ constant prio : in std_logic_vector(1 downto 0);
+ constant tt : in std_logic_vector(1 downto 0);
+ constant ftype : in std_logic_vector(3 downto 0);
+ constant sourceId : in std_logic_vector(15 downto 0);
+ constant destId : in std_logic_vector(15 downto 0);
+ constant payload : in RioPayload)
+ return RioFrame;
+
+ ---------------------------------------------------------------------------
+ -- Create a NWRITE RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioNwrite(
+ constant wrsize : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant address : in std_logic_vector(28 downto 0);
+ constant wdptr : in std_logic;
+ constant xamsbs : in std_logic_vector(1 downto 0);
+ constant dataLength : in natural range 1 to 32;
+ constant data : in DoublewordArray(0 to 31))
+ return RioPayload;
+
+ ---------------------------------------------------------------------------
+ -- Create a NREAD RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioNread(
+ constant rdsize : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant address : in std_logic_vector(28 downto 0);
+ constant wdptr : in std_logic;
+ constant xamsbs : in std_logic_vector(1 downto 0))
+ return RioPayload;
+
+ ---------------------------------------------------------------------------
+ -- Create a RESPONSE RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioResponse(
+ constant status : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant dataLength : in natural range 0 to 32;
+ constant data : in DoublewordArray(0 to 31))
+ return RioPayload;
+
+ ---------------------------------------------------------------------------
+ -- Create a Maintenance RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioMaintenance(
+ constant transaction : in std_logic_vector(3 downto 0);
+ constant size : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant hopCount : in std_logic_vector(7 downto 0);
+ constant configOffset : in std_logic_vector(20 downto 0);
+ constant wdptr : in std_logic;
+ constant dataLength : in natural range 0 to 8;
+ constant data : in DoublewordArray(0 to 7))
+ return RioPayload;
+
+ -----------------------------------------------------------------------------
+ -- Function to convert a std_logic_vector to a string.
+ -----------------------------------------------------------------------------
+ function byteToString(constant byte : std_logic_vector(7 downto 0))
+ return string;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to print to report file and output
+ ---------------------------------------------------------------------------
+ procedure PrintR( constant str : string );
+
+ ---------------------------------------------------------------------------
+ -- Procedure to print to spec file
+ ---------------------------------------------------------------------------
+ procedure PrintS( constant str : string );
+
+ ---------------------------------------------------------------------------
+ -- Procedure to Assert Expression
+ ---------------------------------------------------------------------------
+ procedure AssertE( constant exp: boolean; constant str : string );
+
+ ---------------------------------------------------------------------------
+ -- Procedure to Print Error
+ ---------------------------------------------------------------------------
+ procedure PrintE( constant str : string );
+
+ ---------------------------------------------------------------------------
+ -- Procedure to end a test.
+ ---------------------------------------------------------------------------
+ procedure TestEnd;
+
+end package;
+
+-------------------------------------------------------------------------------
+-- RioCommon package body description.
+-------------------------------------------------------------------------------
+package body rio_common is
+ -----------------------------------------------------------------------------
+ -- Crc5 calculation function.
+ -- ITU, polynom=0x15.
+ -----------------------------------------------------------------------------
+ function Crc5(constant data : in std_logic_vector(18 downto 0);
+ constant crc : in std_logic_vector(4 downto 0))
+ return std_logic_vector is
+ type crcTableType is array (0 to 31) of std_logic_vector(7 downto 0);
+ constant crcTable : crcTableType := (
+ x"00", x"15", x"1f", x"0a", x"0b", x"1e", x"14", x"01",
+ x"16", x"03", x"09", x"1c", x"1d", x"08", x"02", x"17",
+ x"19", x"0c", x"06", x"13", x"12", x"07", x"0d", x"18",
+ x"0f", x"1a", x"10", x"05", x"04", x"11", x"1b", x"0e" );
+ variable index : natural range 0 to 31;
+ variable result : std_logic_vector(4 downto 0);
+ begin
+ result := crc;
+ index := to_integer(unsigned(data(18 downto 14) xor result));
+ result := crcTable(index)(4 downto 0);
+ index := to_integer(unsigned(data(13 downto 9) xor result));
+ result := crcTable(index)(4 downto 0);
+ index := to_integer(unsigned(data(8 downto 4) xor result));
+ result := crcTable(index)(4 downto 0);
+ index := to_integer(unsigned((data(3 downto 0) & '0') xor result));
+ return crcTable(index)(4 downto 0);
+ end Crc5;
+
+ ---------------------------------------------------------------------------
+ -- Create a RapidIO physical layer control symbol.
+ ---------------------------------------------------------------------------
+ function RioControlSymbolCreate(
+ constant stype0 : in std_logic_vector(2 downto 0);
+ constant parameter0 : in std_logic_vector(4 downto 0);
+ constant parameter1 : in std_logic_vector(4 downto 0);
+ constant stype1 : in std_logic_vector(2 downto 0);
+ constant cmd : in std_logic_vector(2 downto 0))
+ return std_logic_vector is
+ variable returnValue : std_logic_vector(31 downto 0);
+ variable symbolData : std_logic_vector(18 downto 0);
+ begin
+ symbolData(18 downto 16) := stype0;
+ symbolData(15 downto 11) := parameter0;
+ symbolData(10 downto 6) := parameter1;
+ symbolData(5 downto 3) := stype1;
+ symbolData(2 downto 0) := cmd;
+
+ returnValue(31 downto 13) := symbolData;
+ returnValue(12 downto 8) := Crc5(symbolData, "11111");
+ returnValue(7 downto 0) := x"00";
+
+ return returnValue;
+ end function;
+
+ -----------------------------------------------------------------------------
+ -- Crc16 calculation function.
+ -- CITT, polynom=0x1021.
+ -----------------------------------------------------------------------------
+ function Crc16(constant data : in std_logic_vector(15 downto 0);
+ constant crc : in std_logic_vector(15 downto 0))
+ return std_logic_vector is
+ type crcTableType is array (0 to 255) of std_logic_vector(15 downto 0);
+ constant crcTable : crcTableType := (
+ x"0000", x"1021", x"2042", x"3063", x"4084", x"50a5", x"60c6", x"70e7",
+ x"8108", x"9129", x"a14a", x"b16b", x"c18c", x"d1ad", x"e1ce", x"f1ef",
+ x"1231", x"0210", x"3273", x"2252", x"52b5", x"4294", x"72f7", x"62d6",
+ x"9339", x"8318", x"b37b", x"a35a", x"d3bd", x"c39c", x"f3ff", x"e3de",
+ x"2462", x"3443", x"0420", x"1401", x"64e6", x"74c7", x"44a4", x"5485",
+ x"a56a", x"b54b", x"8528", x"9509", x"e5ee", x"f5cf", x"c5ac", x"d58d",
+ x"3653", x"2672", x"1611", x"0630", x"76d7", x"66f6", x"5695", x"46b4",
+ x"b75b", x"a77a", x"9719", x"8738", x"f7df", x"e7fe", x"d79d", x"c7bc",
+ x"48c4", x"58e5", x"6886", x"78a7", x"0840", x"1861", x"2802", x"3823",
+ x"c9cc", x"d9ed", x"e98e", x"f9af", x"8948", x"9969", x"a90a", x"b92b",
+ x"5af5", x"4ad4", x"7ab7", x"6a96", x"1a71", x"0a50", x"3a33", x"2a12",
+ x"dbfd", x"cbdc", x"fbbf", x"eb9e", x"9b79", x"8b58", x"bb3b", x"ab1a",
+ x"6ca6", x"7c87", x"4ce4", x"5cc5", x"2c22", x"3c03", x"0c60", x"1c41",
+ x"edae", x"fd8f", x"cdec", x"ddcd", x"ad2a", x"bd0b", x"8d68", x"9d49",
+ x"7e97", x"6eb6", x"5ed5", x"4ef4", x"3e13", x"2e32", x"1e51", x"0e70",
+ x"ff9f", x"efbe", x"dfdd", x"cffc", x"bf1b", x"af3a", x"9f59", x"8f78",
+ x"9188", x"81a9", x"b1ca", x"a1eb", x"d10c", x"c12d", x"f14e", x"e16f",
+ x"1080", x"00a1", x"30c2", x"20e3", x"5004", x"4025", x"7046", x"6067",
+ x"83b9", x"9398", x"a3fb", x"b3da", x"c33d", x"d31c", x"e37f", x"f35e",
+ x"02b1", x"1290", x"22f3", x"32d2", x"4235", x"5214", x"6277", x"7256",
+ x"b5ea", x"a5cb", x"95a8", x"8589", x"f56e", x"e54f", x"d52c", x"c50d",
+ x"34e2", x"24c3", x"14a0", x"0481", x"7466", x"6447", x"5424", x"4405",
+ x"a7db", x"b7fa", x"8799", x"97b8", x"e75f", x"f77e", x"c71d", x"d73c",
+ x"26d3", x"36f2", x"0691", x"16b0", x"6657", x"7676", x"4615", x"5634",
+ x"d94c", x"c96d", x"f90e", x"e92f", x"99c8", x"89e9", x"b98a", x"a9ab",
+ x"5844", x"4865", x"7806", x"6827", x"18c0", x"08e1", x"3882", x"28a3",
+ x"cb7d", x"db5c", x"eb3f", x"fb1e", x"8bf9", x"9bd8", x"abbb", x"bb9a",
+ x"4a75", x"5a54", x"6a37", x"7a16", x"0af1", x"1ad0", x"2ab3", x"3a92",
+ x"fd2e", x"ed0f", x"dd6c", x"cd4d", x"bdaa", x"ad8b", x"9de8", x"8dc9",
+ x"7c26", x"6c07", x"5c64", x"4c45", x"3ca2", x"2c83", x"1ce0", x"0cc1",
+ x"ef1f", x"ff3e", x"cf5d", x"df7c", x"af9b", x"bfba", x"8fd9", x"9ff8",
+ x"6e17", x"7e36", x"4e55", x"5e74", x"2e93", x"3eb2", x"0ed1", x"1ef0" );
+ variable index : natural range 0 to 255;
+ variable result : std_logic_vector(15 downto 0);
+ begin
+ result := crc;
+ index := to_integer(unsigned(data(15 downto 8) xor result(15 downto 8)));
+ result := crcTable(index) xor (result(7 downto 0) & x"00");
+ index := to_integer(unsigned(data(7 downto 0) xor result(15 downto 8)));
+ result := crcTable(index) xor (result(7 downto 0) & x"00");
+ return result;
+ end Crc16;
+
+ ---------------------------------------------------------------------------
+ -- Create a randomly initialized data array.
+ ---------------------------------------------------------------------------
+ procedure CreateRandomPayload(
+ variable payload : out HalfwordArray(0 to 132);
+ variable seed1 : inout positive;
+ variable seed2 : inout positive) is
+ variable rand: real;
+ variable int_rand: integer;
+ variable stim: std_logic_vector(7 downto 0);
+ begin
+ for i in payload'range loop
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(7 downto 0) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(15 downto 8) := std_logic_vector(to_unsigned(int_rand, 8));
+ end loop;
+ end procedure;
+
+ procedure CreateRandomPayload(
+ variable payload : out DoublewordArray(0 to 31);
+ variable seed1 : inout positive;
+ variable seed2 : inout positive) is
+ variable rand: real;
+ variable int_rand: integer;
+ variable stim: std_logic_vector(7 downto 0);
+ begin
+ for i in payload'range loop
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(7 downto 0) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(15 downto 8) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(23 downto 16) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(31 downto 24) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(39 downto 32) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(47 downto 40) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(55 downto 48) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(63 downto 56) := std_logic_vector(to_unsigned(int_rand, 8));
+ end loop;
+ end procedure;
+ ---------------------------------------------------------------------------
+ -- Create a generic RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioFrameCreate(
+ constant ackId : in std_logic_vector(4 downto 0);
+ constant vc : in std_logic;
+ constant crf : in std_logic;
+ constant prio : in std_logic_vector(1 downto 0);
+ constant tt : in std_logic_vector(1 downto 0);
+ constant ftype : in std_logic_vector(3 downto 0);
+ constant sourceId : in std_logic_vector(15 downto 0);
+ constant destId : in std_logic_vector(15 downto 0);
+ constant payload : in RioPayload) return RioFrame is
+ variable frame : RioFrame;
+ variable result : HalfwordArray(0 to 137);
+ variable crc : std_logic_vector(15 downto 0) := x"ffff";
+ begin
+ -- Add the header and addresses.
+ result(0) := ackId & "0" & vc & crf & prio & tt & ftype;
+ result(1) := destId;
+ result(2) := sourceId;
+
+ -- Update the calculated CRC with the header contents.
+ crc := Crc16("00000" & result(0)(10 downto 0), crc);
+ crc := Crc16(result(1), crc);
+ crc := Crc16(result(2), crc);
+
+ -- Check if a single CRC should be added or two.
+ if (payload.length <= 37) then
+ -- Single CRC.
+ for i in 0 to payload.length-1 loop
+ result(i+3) := payload.data(i);
+ crc := Crc16(payload.data(i), crc);
+ end loop;
+ result(payload.length+3) := crc;
+
+ -- Check if paddning is needed to make the payload even 32-bit.
+ if ((payload.length mod 2) = 1) then
+ result(payload.length+4) := x"0000";
+ frame.length := (payload.length+5) / 2;
+ else
+ frame.length := (payload.length+4) / 2;
+ end if;
+ else
+ -- Double CRC.
+ for i in 0 to 36 loop
+ result(i+3) := payload.data(i);
+ crc := Crc16(payload.data(i), crc);
+ end loop;
+
+ -- Add in-the-middle crc.
+ result(40) := crc;
+ crc := Crc16(crc, crc);
+
+ for i in 37 to payload.length-1 loop
+ result(i+4) := payload.data(i);
+ crc := Crc16(payload.data(i), crc);
+ end loop;
+ result(payload.length+4) := crc;
+
+ -- Check if paddning is needed to make the payload even 32-bit.
+ if ((payload.length mod 2) = 0) then
+ result(payload.length+5) := x"0000";
+ frame.length := (payload.length+6) / 2;
+ else
+ frame.length := (payload.length+5) / 2;
+ end if;
+ end if;
+
+ -- Update the result length.
+ for i in 0 to frame.length-1 loop
+ frame.payload(i) := result(2*i) & result(2*i+1);
+ end loop;
+
+ return frame;
+ end function;
+
+ -----------------------------------------------------------------------------
+ --
+ -----------------------------------------------------------------------------
+ function RioNwrite(
+ constant wrsize : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant address : in std_logic_vector(28 downto 0);
+ constant wdptr : in std_logic;
+ constant xamsbs : in std_logic_vector(1 downto 0);
+ constant dataLength : in natural range 1 to 32;
+ constant data : in DoublewordArray(0 to 31))
+ return RioPayload is
+ variable payload : RioPayload;
+ begin
+ payload.data(0)(15 downto 12) := "0100";
+ payload.data(0)(11 downto 8) := wrsize;
+ payload.data(0)(7 downto 0) := tid;
+
+ payload.data(1) := address(28 downto 13);
+
+ payload.data(2)(15 downto 3) := address(12 downto 0);
+ payload.data(2)(2) := wdptr;
+ payload.data(2)(1 downto 0) := xamsbs;
+
+ for i in 0 to dataLength-1 loop
+ payload.data(3+4*i) := data(i)(63 downto 48);
+ payload.data(4+4*i) := data(i)(47 downto 32);
+ payload.data(5+4*i) := data(i)(31 downto 16);
+ payload.data(6+4*i) := data(i)(15 downto 0);
+ end loop;
+
+ payload.length := 3 + 4*dataLength;
+
+ return payload;
+ end function;
+
+ -----------------------------------------------------------------------------
+ --
+ -----------------------------------------------------------------------------
+ function RioNread(
+ constant rdsize : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant address : in std_logic_vector(28 downto 0);
+ constant wdptr : in std_logic;
+ constant xamsbs : in std_logic_vector(1 downto 0))
+ return RioPayload is
+ variable payload : RioPayload;
+ begin
+ payload.data(0)(15 downto 12) := "0100";
+ payload.data(0)(11 downto 8) := rdsize;
+ payload.data(0)(7 downto 0) := tid;
+
+ payload.data(1) := address(28 downto 13);
+
+ payload.data(2)(15 downto 3) := address(12 downto 0);
+ payload.data(2)(2) := wdptr;
+ payload.data(2)(1 downto 0) := xamsbs;
+
+ payload.length := 3;
+
+ return payload;
+ end function;
+
+ ---------------------------------------------------------------------------
+ -- Create a RESPONSE RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioResponse(
+ constant status : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant dataLength : in natural range 0 to 32;
+ constant data : in DoublewordArray(0 to 31))
+ return RioPayload is
+ variable payload : RioPayload;
+ begin
+ payload.data(0)(11 downto 8) := status;
+ payload.data(0)(7 downto 0) := tid;
+
+ if (dataLength = 0) then
+ payload.data(0)(15 downto 12) := "0000";
+ payload.length := 1;
+ else
+ payload.data(0)(15 downto 12) := "1000";
+
+ for i in 0 to dataLength-1 loop
+ payload.data(1+4*i) := data(i)(63 downto 48);
+ payload.data(2+4*i) := data(i)(47 downto 32);
+ payload.data(3+4*i) := data(i)(31 downto 16);
+ payload.data(4+4*i) := data(i)(15 downto 0);
+ end loop;
+
+ payload.length := 1 + 4*dataLength;
+ end if;
+
+ return payload;
+ end function;
+
+ ---------------------------------------------------------------------------
+ -- Create a Maintenance RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioMaintenance(
+ constant transaction : in std_logic_vector(3 downto 0);
+ constant size : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant hopCount : in std_logic_vector(7 downto 0);
+ constant configOffset : in std_logic_vector(20 downto 0);
+ constant wdptr : in std_logic;
+ constant dataLength : in natural range 0 to 8;
+ constant data : in DoublewordArray(0 to 7))
+ return RioPayload is
+ variable payload : RioPayload;
+ begin
+ payload.data(0)(15 downto 12) := transaction;
+ payload.data(0)(11 downto 8) := size;
+ payload.data(0)(7 downto 0) := tid;
+
+ payload.data(1)(15 downto 8) := hopCount;
+ payload.data(1)(7 downto 0) := configOffset(20 downto 13);
+
+ payload.data(2)(15 downto 3) := configOffset(12 downto 0);
+ payload.data(2)(2) := wdptr;
+ payload.data(2)(1 downto 0) := "00";
+
+ if (dataLength = 0) then
+ payload.length := 3;
+ else
+ for i in 0 to dataLength-1 loop
+ payload.data(3+4*i) := data(i)(63 downto 48);
+ payload.data(4+4*i) := data(i)(47 downto 32);
+ payload.data(5+4*i) := data(i)(31 downto 16);
+ payload.data(6+4*i) := data(i)(15 downto 0);
+ end loop;
+
+ payload.length := 3 + 4*dataLength;
+ end if;
+
+ return payload;
+ end function;
+
+ -----------------------------------------------------------------------------
+ -- Function to convert a std_logic_vector to a string.
+ -----------------------------------------------------------------------------
+ function byteToString(constant byte : std_logic_vector(7 downto 0))
+ return string is
+ constant table : string(1 to 16) := "0123456789abcdef";
+ variable returnValue : string(1 to 2);
+ begin
+ returnValue(1) := table(to_integer(unsigned(byte(7 downto 4))) + 1);
+ returnValue(2) := table(to_integer(unsigned(byte(3 downto 0))) + 1);
+ return returnValue;
+ end function;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to print test report
+ ---------------------------------------------------------------------------
+ procedure PrintR( constant str : string ) is
+ file reportFile : text;
+ variable reportLine, outputLine : line;
+ variable fStatus: FILE_OPEN_STATUS;
+ begin
+ --Write report note to wave/transcript window
+ report str severity NOTE;
+ end PrintR;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to print test spec
+ ---------------------------------------------------------------------------
+ procedure PrintS( constant str : string ) is
+ file specFile : text;
+ variable specLine, outputLine : line;
+ variable fStatus: FILE_OPEN_STATUS;
+ begin
+ --Write to spec file
+ file_open(fStatus, specFile, "testspec.txt", append_mode);
+ write(specLine, string'(str));
+ writeline (specFile, specLine);
+ file_close(specFile);
+ end PrintS;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to Assert Expression
+ ---------------------------------------------------------------------------
+ procedure AssertE( constant exp: boolean; constant str : string ) is
+ file reportFile : text;
+ variable reportLine, outputLine : line;
+ variable fStatus: FILE_OPEN_STATUS;
+ begin
+ if (not exp) then
+ --Write to STD_OUTPUT
+ report(str) severity error;
+ else
+ PrintR("Status: Passed");
+ PrintS("Status: Passed");
+ end if;
+ end AssertE;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to Print Error
+ ---------------------------------------------------------------------------
+ procedure PrintE( constant str : string ) is
+ file reportFile : text;
+ variable reportLine, outputLine : line;
+ variable fStatus: FILE_OPEN_STATUS;
+ begin
+ --Write to STD_OUTPUT
+ report str severity error;
+ end PrintE;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to end a test.
+ ---------------------------------------------------------------------------
+ procedure TestEnd is
+ begin
+ assert false report "Test complete." severity failure;
+ wait;
+ end TestEnd;
+
+end rio_common;
+
+
+
+-------------------------------------------------------------------------------
+-- Crc16CITT
+-- A CRC-16 calculator following the implementation proposed in the 2.2
+-- standard.
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for Crc16CITT.
+-------------------------------------------------------------------------------
+entity Crc16CITT is
+ port(
+ d_i : in std_logic_vector(15 downto 0);
+ crc_i : in std_logic_vector(15 downto 0);
+ crc_o : out std_logic_vector(15 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for Crc16CITT.
+-------------------------------------------------------------------------------
+architecture Crc16Impl of Crc16CITT is
+ signal d : std_logic_vector(0 to 15);
+ signal c : std_logic_vector(0 to 15);
+ signal e : std_logic_vector(0 to 15);
+ signal cc : std_logic_vector(0 to 15);
+begin
+
+ -- Reverse the bit vector indexes to make them the same as in the standard.
+ d(15) <= d_i(0); d(14) <= d_i(1); d(13) <= d_i(2); d(12) <= d_i(3);
+ d(11) <= d_i(4); d(10) <= d_i(5); d(9) <= d_i(6); d(8) <= d_i(7);
+ d(7) <= d_i(8); d(6) <= d_i(9); d(5) <= d_i(10); d(4) <= d_i(11);
+ d(3) <= d_i(12); d(2) <= d_i(13); d(1) <= d_i(14); d(0) <= d_i(15);
+
+ -- Reverse the bit vector indexes to make them the same as in the standard.
+ c(15) <= crc_i(0); c(14) <= crc_i(1); c(13) <= crc_i(2); c(12) <= crc_i(3);
+ c(11) <= crc_i(4); c(10) <= crc_i(5); c(9) <= crc_i(6); c(8) <= crc_i(7);
+ c(7) <= crc_i(8); c(6) <= crc_i(9); c(5) <= crc_i(10); c(4) <= crc_i(11);
+ c(3) <= crc_i(12); c(2) <= crc_i(13); c(1) <= crc_i(14); c(0) <= crc_i(15);
+
+ -- Calculate the resulting crc.
+ e <= c xor d;
+ cc(0) <= e(4) xor e(5) xor e(8) xor e(12);
+ cc(1) <= e(5) xor e(6) xor e(9) xor e(13);
+ cc(2) <= e(6) xor e(7) xor e(10) xor e(14);
+ cc(3) <= e(0) xor e(7) xor e(8) xor e(11) xor e(15);
+ cc(4) <= e(0) xor e(1) xor e(4) xor e(5) xor e(9);
+ cc(5) <= e(1) xor e(2) xor e(5) xor e(6) xor e(10);
+ cc(6) <= e(0) xor e(2) xor e(3) xor e(6) xor e(7) xor e(11);
+ cc(7) <= e(0) xor e(1) xor e(3) xor e(4) xor e(7) xor e(8) xor e(12);
+ cc(8) <= e(0) xor e(1) xor e(2) xor e(4) xor e(5) xor e(8) xor e(9) xor e(13);
+ cc(9) <= e(1) xor e(2) xor e(3) xor e(5) xor e(6) xor e(9) xor e(10) xor e(14);
+ cc(10) <= e(2) xor e(3) xor e(4) xor e(6) xor e(7) xor e(10) xor e(11) xor e(15);
+ cc(11) <= e(0) xor e(3) xor e(7) xor e(11);
+ cc(12) <= e(0) xor e(1) xor e(4) xor e(8) xor e(12);
+ cc(13) <= e(1) xor e(2) xor e(5) xor e(9) xor e(13);
+ cc(14) <= e(2) xor e(3) xor e(6) xor e(10) xor e(14);
+ cc(15) <= e(3) xor e(4) xor e(7) xor e(11) xor e(15);
+
+ -- Reverse the bit vector indexes to make them the same as in the standard.
+ crc_o(15) <= cc(0); crc_o(14) <= cc(1); crc_o(13) <= cc(2); crc_o(12) <= cc(3);
+ crc_o(11) <= cc(4); crc_o(10) <= cc(5); crc_o(9) <= cc(6); crc_o(8) <= cc(7);
+ crc_o(7) <= cc(8); crc_o(6) <= cc(9); crc_o(5) <= cc(10); crc_o(4) <= cc(11);
+ crc_o(3) <= cc(12); crc_o(2) <= cc(13); crc_o(1) <= cc(14); crc_o(0) <= cc(15);
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- MemoryDualPort
+-- Generic synchronous memory with one read/write port and one read port.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for MemoryDualPort.
+-------------------------------------------------------------------------------
+entity MemoryDualPort is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ writeEnableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ dataA_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ clkB_i : in std_logic;
+ enableB_i : in std_logic;
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for MemoryDualPort.
+-------------------------------------------------------------------------------
+architecture MemoryDualPortImpl of MemoryDualPort is
+ type MemoryType is array (natural range <>) of
+ std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1);
+
+begin
+ process(clkA_i)
+ begin
+ if (clkA_i'event and clkA_i = '1') then
+ if (enableA_i = '1') then
+ if (writeEnableA_i = '1') then
+ memory(to_integer(unsigned(addressA_i))) <= dataA_i;
+ end if;
+
+ dataA_o <= memory(to_integer(unsigned(addressA_i)));
+ end if;
+ end if;
+ end process;
+
+ process(clkB_i)
+ begin
+ if (clkB_i'event and clkB_i = '1') then
+ if (enableB_i = '1') then
+ dataB_o <= memory(to_integer(unsigned(addressB_i)));
+ end if;
+ end if;
+ end process;
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- MemorySimpleDualPort
+-- Generic synchronous memory with one write port and one read port.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for MemorySimpleDualPort.
+-------------------------------------------------------------------------------
+entity MemorySimpleDualPort is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ clkB_i : in std_logic;
+ enableB_i : in std_logic;
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for MemorySimpleDualPort.
+-------------------------------------------------------------------------------
+architecture MemorySimpleDualPortImpl of MemorySimpleDualPort is
+ type MemoryType is array (natural range <>) of
+ std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1);
+
+begin
+ process(clkA_i)
+ begin
+ if (clkA_i'event and clkA_i = '1') then
+ if (enableA_i = '1') then
+ memory(to_integer(unsigned(addressA_i))) <= dataA_i;
+ end if;
+ end if;
+ end process;
+
+ process(clkB_i)
+ begin
+ if (clkB_i'event and clkB_i = '1') then
+ if (enableB_i = '1') then
+ dataB_o <= memory(to_integer(unsigned(addressB_i)));
+ end if;
+ end if;
+ end process;
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- MemorySinglePort
+-- Generic synchronous memory with one read/write port.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for MemorySinglePort.
+-------------------------------------------------------------------------------
+entity MemorySinglePort is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clk_i : in std_logic;
+ enable_i : in std_logic;
+ writeEnable_i : in std_logic;
+ address_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ data_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ data_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for MemorySinglePort.
+-------------------------------------------------------------------------------
+architecture MemorySinglePortImpl of MemorySinglePort is
+ type MemoryType is array (natural range <>) of
+ std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1);
+
+begin
+ process(clk_i)
+ begin
+ if (clk_i'event and clk_i = '1') then
+ if (enable_i = '1') then
+ if (writeEnable_i = '1') then
+ memory(to_integer(unsigned(address_i))) <= data_i;
+ end if;
+
+ data_o <= memory(to_integer(unsigned(address_i)));
+ end if;
+ end if;
+ end process;
+
+end architecture;
+
+
+
+
+-------------------------------------------------------------------------------
+-- MemorySimpleDualPortAsync
+-- Generic memory with one synchronous write port and one asynchronous read port.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for MemorySimpleDualPortAsync.
+-------------------------------------------------------------------------------
+entity MemorySimpleDualPortAsync is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1;
+ INIT_VALUE : std_logic := 'U');
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for MemorySimpleDualPortAsync.
+-------------------------------------------------------------------------------
+architecture MemorySimpleDualPortAsyncImpl of MemorySimpleDualPortAsync is
+ type MemoryType is array (natural range <>) of
+ std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1) := (others=>(others=>INIT_VALUE));
+
+begin
+ process(clkA_i)
+ begin
+ if (clkA_i'event and clkA_i = '1') then
+ if (enableA_i = '1') then
+ memory(to_integer(unsigned(addressA_i))) <= dataA_i;
+ end if;
+ end if;
+ end process;
+
+ dataB_o <= memory(to_integer(unsigned(addressB_i)));
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- RioFifo1
+-- Simple fifo which is one entry deep.
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for RioFifo1.
+-------------------------------------------------------------------------------
+entity RioFifo1 is
+ generic(
+ WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ empty_o : out std_logic;
+ read_i : in std_logic;
+ data_o : out std_logic_vector(WIDTH-1 downto 0);
+
+ full_o : out std_logic;
+ write_i : in std_logic;
+ data_i : in std_logic_vector(WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for RioFifo1.
+-------------------------------------------------------------------------------
+architecture RioFifo1Impl of RioFifo1 is
+ signal empty : std_logic;
+ signal full : std_logic;
+begin
+
+ empty_o <= empty;
+ full_o <= full;
+
+ process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ empty <= '1';
+ full <= '0';
+ data_o <= (others => '0');
+ elsif (clk'event and clk = '1') then
+ if (empty = '1') then
+ if (write_i = '1') then
+ empty <= '0';
+ full <= '1';
+ data_o <= data_i;
+ end if;
+ else
+ if (read_i = '1') then
+ empty <= '1';
+ full <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
+
+end architecture;
1.0.1/rtl/vhdl/RioCommon.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/rtl/vhdl/RioSerial.vhd
===================================================================
--- 1.0.1/rtl/vhdl/RioSerial.vhd (nonexistent)
+++ 1.0.1/rtl/vhdl/RioSerial.vhd (revision 29)
@@ -0,0 +1,2428 @@
+-------------------------------------------------------------------------------
+--
+-- 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
+--
+-- clk - System clock.
+-- areset_n - System reset. Asynchronous, active low.
+--
+-- 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.
+-- outboundSymbol_o - The outbound symbol. The two MSB bits are the type of the
+-- symbol.
+-- bit 34-33
+-- 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 symbol data.
+-- 10=ERROR, the rest of the bits are not used.
+-- 11=DATA, all the remaining bits contain the data-symbol payload.
+-- 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.
+-------------------------------------------------------------------------------
+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);
+ port(
+ -- System signals.
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ -- Status signals for maintenance operations.
+ portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
+ linkInitialized_o : out std_logic;
+ inputPortEnable_i : in std_logic;
+ outputPortEnable_i : in std_logic;
+
+ -- Support for portLocalAckIdCSR.
+ localAckIdWrite_i : in std_logic;
+ clrOutstandingAckId_i : in std_logic;
+ inboundAckId_i : in std_logic_vector(4 downto 0);
+ outstandingAckId_i : in std_logic_vector(4 downto 0);
+ outboundAckId_i : in std_logic_vector(4 downto 0);
+ inboundAckId_o : out std_logic_vector(4 downto 0);
+ outstandingAckId_o : out std_logic_vector(4 downto 0);
+ outboundAckId_o : out std_logic_vector(4 downto 0);
+
+ -- Outbound frame interface.
+ readFrameEmpty_i : in std_logic;
+ readFrame_o : out std_logic;
+ readFrameRestart_o : out std_logic;
+ readFrameAborted_i : in std_logic;
+ readWindowEmpty_i : in std_logic;
+ readWindowReset_o : out std_logic;
+ readWindowNext_o : out std_logic;
+ readContentEmpty_i : in std_logic;
+ readContent_o : out std_logic;
+ readContentEnd_i : in std_logic;
+ readContentData_i : in std_logic_vector(31 downto 0);
+
+ -- Inbound frame interface.
+ writeFrameFull_i : in std_logic;
+ writeFrame_o : out std_logic;
+ writeFrameAbort_o : out std_logic;
+ writeContent_o : out std_logic;
+ writeContentData_o : out std_logic_vector(31 downto 0);
+
+ -- PCS layer signals.
+ portInitialized_i : in std_logic;
+ outboundSymbolEmpty_o : out std_logic;
+ outboundSymbolRead_i : in std_logic;
+ outboundSymbol_o : out std_logic_vector(33 downto 0);
+ inboundSymbolFull_o : out std_logic;
+ inboundSymbolWrite_i : in std_logic;
+ inboundSymbol_i : in std_logic_vector(33 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for RioSerial.
+-------------------------------------------------------------------------------
+architecture RioSerialImpl of RioSerial is
+
+ component RioFifo1 is
+ generic(
+ WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ empty_o : out std_logic;
+ read_i : in std_logic;
+ data_o : out std_logic_vector(WIDTH-1 downto 0);
+
+ full_o : out std_logic;
+ write_i : in std_logic;
+ data_i : in std_logic_vector(WIDTH-1 downto 0));
+ end component;
+
+ component RioTransmitter is
+ generic(
+ TIMEOUT_WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
+ portEnable_i : in std_logic;
+
+ localAckIdWrite_i : in std_logic;
+ clrOutstandingAckId_i : in std_logic;
+ outstandingAckId_i : in std_logic_vector(4 downto 0);
+ outboundAckId_i : in std_logic_vector(4 downto 0);
+ outstandingAckId_o : out std_logic_vector(4 downto 0);
+ outboundAckId_o : out std_logic_vector(4 downto 0);
+
+ portInitialized_i : in std_logic;
+ txFull_i : in std_logic;
+ txWrite_o : out std_logic;
+ txControl_o : out std_logic_vector(1 downto 0);
+ txData_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_i : in std_logic;
+ linkInitialized_o : out std_logic;
+ ackIdStatus_i : in std_logic_vector(4 downto 0);
+
+ readFrameEmpty_i : in std_logic;
+ readFrame_o : out std_logic;
+ readFrameRestart_o : out std_logic;
+ readFrameAborted_i : in std_logic;
+ readWindowEmpty_i : in std_logic;
+ readWindowReset_o : out std_logic;
+ readWindowNext_o : out std_logic;
+ readContentEmpty_i : in std_logic;
+ readContent_o : out std_logic;
+ readContentEnd_i : in std_logic;
+ readContentData_i : in std_logic_vector(31 downto 0));
+ end component;
+
+ component RioReceiver is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ portEnable_i : in std_logic;
+
+ localAckIdWrite_i : in std_logic;
+ inboundAckId_i : in std_logic_vector(4 downto 0);
+ inboundAckId_o : out std_logic_vector(4 downto 0);
+
+ portInitialized_i : in std_logic;
+ rxEmpty_i : in std_logic;
+ rxRead_o : out std_logic;
+ rxControl_i : in std_logic_vector(1 downto 0);
+ rxData_i : in std_logic_vector(31 downto 0);
+
+ txControlWrite_o : out std_logic;
+ txControlSymbol_o : out std_logic_vector(12 downto 0);
+ rxControlWrite_o : out std_logic;
+ rxControlSymbol_o : out std_logic_vector(12 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(31 downto 0));
+ end component;
+
+ signal linkInitializedRx : std_logic;
+ signal linkInitializedTx : std_logic;
+ signal ackIdStatus : std_logic_vector(4 downto 0);
+
+ signal txControlWrite : std_logic;
+ signal txControlWriteSymbol : std_logic_vector(12 downto 0);
+ signal txControlReadEmpty : std_logic;
+ signal txControlRead : std_logic;
+ signal txControlReadSymbol : std_logic_vector(12 downto 0);
+
+ signal rxControlWrite : std_logic;
+ signal rxControlWriteSymbol : std_logic_vector(12 downto 0);
+ signal rxControlReadEmpty : std_logic;
+ signal rxControlRead : std_logic;
+ signal rxControlReadSymbol : std_logic_vector(12 downto 0);
+
+ signal outboundFull : std_logic;
+ signal outboundWrite : std_logic;
+ signal outboundControl : std_logic_vector(1 downto 0);
+ signal outboundData : std_logic_vector(31 downto 0);
+ signal outboundSymbol : std_logic_vector(33 downto 0);
+
+ signal inboundEmpty : std_logic;
+ signal inboundRead : std_logic;
+ signal inboundControl : std_logic_vector(1 downto 0);
+ signal inboundData : std_logic_vector(31 downto 0);
+ signal inboundSymbol : std_logic_vector(33 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)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ portLinkTimeout_i=>portLinkTimeout_i,
+ portEnable_i=>outputPortEnable_i,
+ localAckIdWrite_i=>localAckIdWrite_i,
+ clrOutstandingAckId_i=>clrOutstandingAckId_i,
+ outstandingAckId_i=>outstandingAckId_i,
+ outboundAckId_i=>outboundAckId_i,
+ outstandingAckId_o=>outstandingAckId_o,
+ outboundAckId_o=>outboundAckId_o,
+ portInitialized_i=>portInitialized_i,
+ txFull_i=>outboundFull, txWrite_o=>outboundWrite,
+ txControl_o=>outboundControl, txData_o=>outboundData,
+ txControlEmpty_i=>txControlReadEmpty, txControlSymbol_i=>txControlReadSymbol,
+ txControlUpdate_o=>txControlRead,
+ rxControlEmpty_i=>rxControlReadEmpty, rxControlSymbol_i=>rxControlReadSymbol,
+ rxControlUpdate_o=>rxControlRead,
+ linkInitialized_o=>linkInitializedTx,
+ linkInitialized_i=>linkInitializedRx, ackIdStatus_i=>ackIdStatus,
+ readFrameEmpty_i=>readFrameEmpty_i, readFrame_o=>readFrame_o,
+ readFrameRestart_o=>readFrameRestart_o, readFrameAborted_i=>readFrameAborted_i,
+ readWindowEmpty_i=>readWindowEmpty_i,
+ readWindowReset_o=>readWindowReset_o, readWindowNext_o=>readWindowNext_o,
+ readContentEmpty_i=>readContentEmpty_i, readContent_o=>readContent_o,
+ readContentEnd_i=>readContentEnd_i, readContentData_i=>readContentData_i);
+
+ TxSymbolFifo: RioFifo1
+ generic map(WIDTH=>13)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ empty_o=>txControlReadEmpty, read_i=>txControlRead, data_o=>txControlReadSymbol,
+ full_o=>open, write_i=>txControlWrite, data_i=>txControlWriteSymbol);
+
+ RxSymbolFifo: RioFifo1
+ generic map(WIDTH=>13)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ empty_o=>rxControlReadEmpty, read_i=>rxControlRead, data_o=>rxControlReadSymbol,
+ full_o=>open, write_i=>rxControlWrite, data_i=>rxControlWriteSymbol);
+
+ Receiver: RioReceiver
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ portEnable_i=>inputPortEnable_i,
+ localAckIdWrite_i=>localAckIdWrite_i,
+ inboundAckId_i=>inboundAckId_i,
+ inboundAckId_o=>inboundAckId_o,
+ portInitialized_i=>portInitialized_i,
+ rxEmpty_i=>inboundEmpty, rxRead_o=>inboundRead,
+ rxControl_i=>inboundControl, rxData_i=>inboundData,
+ txControlWrite_o=>txControlWrite, txControlSymbol_o=>txControlWriteSymbol,
+ rxControlWrite_o=>rxControlWrite, rxControlSymbol_o=>rxControlWriteSymbol,
+ ackIdStatus_o=>ackIdStatus,
+ linkInitialized_o=>linkInitializedRx,
+ writeFrameFull_i=>writeFrameFull_i,
+ writeFrame_o=>writeFrame_o, writeFrameAbort_o=>writeFrameAbort_o,
+ writeContent_o=>writeContent_o, writeContentData_o=>writeContentData_o);
+
+ -----------------------------------------------------------------------------
+ -- PCS layer FIFO interface.
+ -----------------------------------------------------------------------------
+
+ outboundSymbol <= outboundControl & outboundData;
+ OutboundSymbolFifo: RioFifo1
+ generic map(WIDTH=>34)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ empty_o=>outboundSymbolEmpty_o, read_i=>outboundSymbolRead_i, data_o=>outboundSymbol_o,
+ full_o=>outboundFull, write_i=>outboundWrite, data_i=>outboundSymbol);
+
+ inboundControl <= inboundSymbol(33 downto 32);
+ inboundData <= inboundSymbol(31 downto 0);
+ InboundSymbolFifo: RioFifo1
+ generic map(WIDTH=>34)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ empty_o=>inboundEmpty, read_i=>inboundRead, data_o=>inboundSymbol,
+ full_o=>inboundSymbolFull_o, write_i=>inboundSymbolWrite_i, data_i=>inboundSymbol_i);
+
+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);
+ port(
+ -- System signals.
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ -- Status signals used for maintenance.
+ portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
+ portEnable_i : in std_logic;
+
+ -- Support for localAckIdCSR.
+ localAckIdWrite_i : in std_logic;
+ clrOutstandingAckId_i : in std_logic;
+ outstandingAckId_i : in std_logic_vector(4 downto 0);
+ outboundAckId_i : in std_logic_vector(4 downto 0);
+ outstandingAckId_o : out std_logic_vector(4 downto 0);
+ outboundAckId_o : out std_logic_vector(4 downto 0);
+
+ -- Port output interface.
+ portInitialized_i : in std_logic;
+ txFull_i : in std_logic;
+ txWrite_o : out std_logic;
+ txControl_o : out std_logic_vector(1 downto 0);
+ txData_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);
+
+ -- 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 RioTransmitter.
+-------------------------------------------------------------------------------
+architecture RioTransmitterImpl of RioTransmitter is
+
+ constant NUMBER_STATUS_TRANSMIT : natural := 15;
+ constant NUMBER_LINK_RESPONSE_RETRIES : natural := 2;
+
+ 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;
+
+ component Crc5ITU is
+ port(
+ d_i : in std_logic_vector(18 downto 0);
+ crc_o : out std_logic_vector(4 downto 0));
+ end component;
+
+ type StateType is (STATE_UNINITIALIZED, STATE_PORT_INITIALIZED,
+ STATE_NORMAL,
+ STATE_OUTPUT_RETRY_STOPPED,
+ STATE_SEND_LINK_REQUEST, STATE_OUTPUT_ERROR_STOPPED,
+ STATE_RECOVER, STATE_FATAL_ERROR);
+ signal stateCurrent, stateNext : StateType;
+
+ signal statusReceivedCurrent, statusReceivedNext : std_logic;
+ signal counterCurrent, counterNext : natural range 0 to 15;
+ signal symbolsTransmittedCurrent, symbolsTransmittedNext : natural range 0 to 255;
+
+ type FrameStateType is (FRAME_START, FRAME_CHECK, FRAME_ACKID, FRAME_BODY, FRAME_END);
+ signal frameStateCurrent, frameStateNext : FrameStateType;
+ signal ackIdCurrent, ackIdNext : unsigned(4 downto 0) := (others=>'0');
+ signal ackIdWindowCurrent, ackIdWindowNext : unsigned(4 downto 0) := (others=>'0');
+ signal bufferStatusCurrent, bufferStatusNext : std_logic_vector(4 downto 0);
+
+ signal stype0 : std_logic_vector(2 downto 0);
+ signal parameter0 : std_logic_vector(4 downto 0);
+ signal parameter1 : std_logic_vector(4 downto 0);
+ signal stype1 : std_logic_vector(2 downto 0);
+ signal cmd : std_logic_vector(2 downto 0);
+
+ signal txControlStype0 : std_logic_vector(2 downto 0);
+ signal txControlParameter0 : std_logic_vector(4 downto 0);
+ signal txControlParameter1 : std_logic_vector(4 downto 0);
+
+ signal rxControlStype0 : std_logic_vector(2 downto 0);
+ signal rxControlParameter0 : std_logic_vector(4 downto 0);
+ signal rxControlParameter1 : std_logic_vector(4 downto 0);
+
+ signal symbolWrite : std_logic;
+ signal symbolType : std_logic_vector(1 downto 0);
+ signal symbolControl : std_logic_vector(31 downto 0);
+ signal symbolData : std_logic_vector(31 downto 0);
+ signal crcCalculated : std_logic_vector(4 downto 0);
+
+ signal timeoutWrite : std_logic;
+ signal timeoutCounter : unsigned(TIMEOUT_WIDTH downto 0);
+ signal timeoutFrame : unsigned(TIMEOUT_WIDTH downto 0);
+ signal timeoutElapsed : unsigned(TIMEOUT_WIDTH downto 0);
+ signal timeoutDelta : unsigned(TIMEOUT_WIDTH downto 0);
+ signal timeoutExpired : std_logic;
+
+ signal timeoutAddress : std_logic_vector(4 downto 0);
+ signal timeoutMemoryOut : std_logic_vector(TIMEOUT_WIDTH downto 0);
+
+begin
+
+ linkInitialized_o <= '0' when ((stateCurrent = STATE_UNINITIALIZED) or
+ (stateCurrent = STATE_PORT_INITIALIZED)) else '1';
+
+ -----------------------------------------------------------------------------
+ -- Assign control symbol from fifo signals.
+ -----------------------------------------------------------------------------
+
+ txControlStype0 <= txControlSymbol_i(12 downto 10);
+ txControlParameter0 <= txControlSymbol_i(9 downto 5);
+ txControlParameter1 <= txControlSymbol_i(4 downto 0);
+
+ rxControlStype0 <= rxControlSymbol_i(12 downto 10);
+ rxControlParameter0 <= rxControlSymbol_i(9 downto 5);
+ rxControlParameter1 <= rxControlSymbol_i(4 downto 0);
+
+ -----------------------------------------------------------------------------
+ -- Outbound symbol creation logic.
+ -----------------------------------------------------------------------------
+
+ symbolControl(31 downto 29) <= stype0;
+ symbolControl(28 downto 24) <= parameter0;
+ symbolControl(23 downto 19) <= parameter1;
+ symbolControl(18 downto 16) <= stype1;
+ symbolControl(15 downto 13) <= cmd;
+ symbolControl(12 downto 8) <= crcCalculated;
+ symbolControl(7 downto 0) <= x"00";
+
+ Crc5Calculator: Crc5ITU
+ port map(
+ d_i=>symbolControl(31 downto 13), crc_o=>crcCalculated);
+
+ txWrite_o <= symbolWrite;
+ txControl_o <= symbolType;
+ txData_o <= symbolControl when (symbolType = SYMBOL_CONTROL) else symbolData;
+
+ -----------------------------------------------------------------------------
+ -- Packet timeout logic.
+ -----------------------------------------------------------------------------
+
+ -- Note that the timer is one bit larger to be able to detect a timeout on a
+ -- free-running counter.
+ process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ timeoutCounter <= (others=>'0');
+ elsif (clk'event and clk = '1') then
+ timeoutCounter <= timeoutCounter + 1;
+ end if;
+ end process;
+
+ timeoutElapsed <= timeoutCounter - timeoutFrame;
+ timeoutDelta <= unsigned('0' & portLinkTimeout_i) - timeoutElapsed;
+ timeoutExpired <= timeoutDelta(TIMEOUT_WIDTH);
+
+ timeoutFrame <= unsigned(timeoutMemoryOut);
+ TimeoutMemory: MemorySimpleDualPortAsync
+ generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>TIMEOUT_WIDTH+1, INIT_VALUE=>'0')
+ port map(
+ clkA_i=>clk, enableA_i=>timeoutWrite,
+ addressA_i=>timeoutAddress, dataA_i=>std_logic_vector(timeoutCounter),
+ addressB_i=>std_logic_vector(ackIdCurrent), dataB_o=>timeoutMemoryOut);
+
+ -----------------------------------------------------------------------------
+ -- Main outbound symbol handler, synchronous part.
+ -----------------------------------------------------------------------------
+ process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ stateCurrent <= STATE_UNINITIALIZED;
+
+ statusReceivedCurrent <= '0';
+ counterCurrent <= 0;
+ symbolsTransmittedCurrent <= 0;
+
+ frameStateCurrent <= FRAME_START;
+ ackIdCurrent <= (others => '0');
+ ackIdWindowCurrent <= (others => '0');
+ bufferStatusCurrent <= (others => '0');
+ elsif (clk'event and clk = '1') then
+ stateCurrent <= stateNext;
+
+ statusReceivedCurrent <= statusReceivedNext;
+ counterCurrent <= counterNext;
+ symbolsTransmittedCurrent <= symbolsTransmittedNext;
+
+ frameStateCurrent <= frameStateNext;
+ ackIdCurrent <= ackIdNext;
+ ackIdWindowCurrent <= ackIdWindowNext;
+ bufferStatusCurrent <= bufferStatusNext;
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Main outbound symbol handler, combinatorial part.
+ -----------------------------------------------------------------------------
+ process(stateCurrent,
+ statusReceivedCurrent, counterCurrent,
+ symbolsTransmittedCurrent,
+ frameStateCurrent, ackIdCurrent, ackIdWindowCurrent, bufferStatusCurrent,
+ txControlStype0, txControlParameter0, txControlParameter1,
+ rxControlStype0, rxControlParameter0, rxControlParameter1,
+ portEnable_i,
+ localAckIdWrite_i, clrOutstandingAckId_i,
+ outstandingAckId_i, outboundAckId_i,
+ txFull_i,
+ txControlEmpty_i, txControlSymbol_i,
+ rxControlEmpty_i, rxControlSymbol_i,
+ portInitialized_i, linkInitialized_i, ackIdStatus_i,
+ readFrameEmpty_i, readFrameAborted_i,
+ readWindowEmpty_i,
+ readContentEmpty_i, readContentEnd_i, readContentData_i,
+ timeoutExpired)
+ begin
+ stateNext <= stateCurrent;
+ statusReceivedNext <= statusReceivedCurrent;
+ counterNext <= counterCurrent;
+ symbolsTransmittedNext <= symbolsTransmittedCurrent;
+
+ frameStateNext <= frameStateCurrent;
+ ackIdNext <= ackIdCurrent;
+ ackIdWindowNext <= ackIdWindowCurrent;
+ bufferStatusNext <= bufferStatusCurrent;
+
+ txControlUpdate_o <= '0';
+ rxControlUpdate_o <= '0';
+
+ readFrame_o <= '0';
+ readFrameRestart_o <= '0';
+ readWindowReset_o <= '0';
+ readWindowNext_o <= '0';
+ readContent_o <= '0';
+
+ symbolWrite <= '0';
+ symbolType <= (others=>'U');
+ stype0 <= (others=>'U');
+ parameter0 <= (others=>'U');
+ parameter1 <= (others=>'U');
+ stype1 <= (others=>'U');
+ cmd <= (others=>'U');
+ symbolData <= (others=>'U');
+
+ timeoutWrite <= '0';
+ timeoutAddress <= (others=>'U');
+
+ outstandingAckId_o <= std_logic_vector(ackIdCurrent);
+ outboundAckId_o <= std_logic_vector(ackIdWindowCurrent);
+
+ -- Check if a localAckIdWrite is active.
+ if (localAckIdWrite_i = '1') then
+ -- A localAckIdWrite is active.
+
+ -- Check if all outstanding packets should be discarded.
+ if (clrOutstandingAckId_i = '1') then
+ -- Delete all outbound packets.
+ -- REMARK: Remove all packets in another way... what if uninitialized???
+ stateNext <= STATE_RECOVER;
+ end if;
+
+ -- Set ackIds.
+ ackIdNext <= unsigned(outstandingAckId_i);
+ ackIdWindowNext <= unsigned(outboundAckId_i);
+ else
+ -- A localAckIdWrite is not active.
+
+ -- Act on the current state.
+ case (stateCurrent) is
+
+ when STATE_UNINITIALIZED =>
+ -----------------------------------------------------------------------
+ -- 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 = '0') then
+ -- Port not initialized.
+
+ -- Check if any new symbols from the link partner has been received.
+ if (txControlEmpty_i = '0') then
+ -- New symbols have been received.
+ -- Discard all new symbols in this state.
+ txControlUpdate_o <= '1';
+ else
+ -- No new symbols from the link partner.
+ -- Dont do anything.
+ end if;
+
+ -- Check if any new symbols should be transmitted to the link partner.
+ if (rxControlEmpty_i = '0') then
+ -- New symbols should be transmitted.
+ -- Do not forward any symbols in this state.
+ rxControlUpdate_o <= '1';
+ else
+ -- No new symbols to transmit.
+ -- Dont do anything.
+ end if;
+
+ -- Check if a new symbol should be transmitted.
+ if (txFull_i = '0') then
+ -- A new symbol should be transmitted.
+
+ -- Send idle sequence.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_IDLE;
+ else
+ -- The outbound fifo is full.
+ -- Dont do anything.
+ end if;
+
+ -- Check if a new full packet is ready.
+ if (readFrameEmpty_i = '0') then
+ -- A new full packet is ready.
+ -- It is not possible to send the packet now. If the packet is not
+ -- discarded it might congest the full system if the link does not
+ -- go initialized. To avoid a congested switch, the packet is
+ -- discarded and will have to be resent by the source when the link
+ -- is up and running.
+ readFrame_o <= '1';
+ else
+ -- No new full packets are ready.
+ -- Dont do anything.
+ end if;
+ else
+ -- Port is initialized.
+
+ -- Go to the initialized state and reset the counters.
+ statusReceivedNext <= '0';
+ counterNext <= NUMBER_STATUS_TRANSMIT;
+ symbolsTransmittedNext <= 0;
+ stateNext <= STATE_PORT_INITIALIZED;
+ end if;
+
+ when STATE_PORT_INITIALIZED =>
+ -----------------------------------------------------------------------
+ -- 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 the port is initialized.
+ if (portInitialized_i = '1') then
+ -- Port is initialized.
+
+ -- Check if we are ready to change state to linkInitialized.
+ if ((linkInitialized_i = '1') and (counterCurrent = 0)) then
+ -- Receiver has received enough error free status symbols and we have
+ -- transmitted enough.
+
+ -- Initialize framing before entering the normal state.
+ ackIdWindowNext <= ackIdCurrent;
+ frameStateNext <= FRAME_START;
+ readWindowReset_o <= '1';
+
+ -- Considder the link initialized.
+ stateNext <= STATE_NORMAL;
+ else
+ -- Not ready to change state to linkInitialized.
+ -- Dont do anything.
+ end if;
+
+ -- Check if any new symbols from the link partner has been received.
+ if (txControlEmpty_i = '0') then
+ -- New symbols have been received.
+
+ -- Check if the new symbol is a status.
+ if (txControlStype0 = STYPE0_STATUS) then
+ -- A new status control symbol has been received.
+ statusReceivedNext <= '1';
+
+ -- Set the ackId and the linkpartner buffer status to what is indicated
+ -- in the received control symbol.
+ ackIdNext <= unsigned(txControlParameter0);
+ bufferStatusNext <= txControlParameter1;
+ else
+ -- Did not receive a status control symbol.
+ -- Discard it.
+ end if;
+
+ -- Update to the next control symbol received by the receiver.
+ txControlUpdate_o <= '1';
+ else
+ -- No new symbols from the link partner.
+ -- Dont do anything.
+ end if;
+
+ -- Check if any new symbols should be transmitted to the link partner.
+ if (rxControlEmpty_i = '0') then
+ -- New symbols should be transmitted.
+ -- Do not forward any symbols in this state.
+ rxControlUpdate_o <= '1';
+ else
+ -- No new symbols to transmit.
+ -- Dont do anything.
+ end if;
+
+ -- Check if a new symbol may be transmitted.
+ if (txFull_i = '0') then
+ -- A new symbol can be transmitted.
+
+ -- Check if idle sequence or a status symbol should be transmitted.
+ if (((statusReceivedCurrent = '0') and (symbolsTransmittedCurrent = 255)) or
+ ((statusReceivedCurrent = '1') and (symbolsTransmittedCurrent > 15))) then
+ -- A status symbol should be transmitted.
+
+ -- Send a status control symbol to the link partner.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= STYPE0_STATUS;
+ parameter0 <= ackIdStatus_i;
+ parameter1 <= "11111";
+ stype1 <= STYPE1_NOP;
+ cmd <= "000";
+
+ -- Reset idle sequence transmission counter.
+ symbolsTransmittedNext <= 0;
+
+ -- Check if the number of transmitted statuses should be updated.
+ if (statusReceivedCurrent = '1') and (counterCurrent /= 0) then
+ counterNext <= counterCurrent - 1;
+ end if;
+ else
+ -- A idle sequence should be transmitted.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_IDLE;
+
+ -- Increment the idle sequence transmission counter.
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+ end if;
+ else
+ -- Cannot send a new symbol.
+ -- Dont do anything.
+ end if;
+ else
+ -- Go back to the uninitialized state.
+ stateNext <= STATE_UNINITIALIZED;
+ end if;
+
+ when STATE_NORMAL =>
+ -------------------------------------------------------------------
+ -- This state is the normal state. It relays frames and handle flow
+ -- control.
+ -------------------------------------------------------------------
+
+ -- Check that both the port and link is initialized.
+ if (portInitialized_i = '1') and (linkInitialized_i = '1') then
+ -- The port and link is initialized.
+
+ -- 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 =>
+ -- Save the number of buffers in the link partner.
+ bufferStatusNext <= txControlParameter1;
+
+ when STYPE0_PACKET_ACCEPTED =>
+ -- The link partner is accepting a frame.
+
+ -- Save the number of buffers in the link partner.
+ bufferStatusNext <= txControlParameter1;
+
+ -- Check if expecting this type of reply and that the ackId is
+ -- expected.
+ if ((ackIdCurrent /= ackIdWindowCurrent) and
+ (ackIdCurrent = unsigned(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.
+ readFrame_o <= '1';
+ ackIdNext <= ackIdCurrent + 1;
+ else
+ -- Unexpected packet-accepted or packet-accepted for
+ -- unexpected ackId.
+ counterNext <= NUMBER_LINK_RESPONSE_RETRIES;
+ stateNext <= STATE_SEND_LINK_REQUEST;
+ end if;
+
+ when STYPE0_PACKET_RETRY =>
+ -- The link partner has asked for a frame retransmission.
+
+ -- Save the number of buffers in the link partner.
+ bufferStatusNext <= txControlParameter1;
+
+ -- Check if the ackId is the one expected.
+ if (ackIdCurrent = unsigned(txControlParameter0)) then
+ -- The ackId to retry is expected.
+ -- Go to the output-retry-stopped state.
+ stateNext <= STATE_OUTPUT_RETRY_STOPPED;
+ else
+ -- Unexpected ackId to retry.
+ counterNext <= NUMBER_LINK_RESPONSE_RETRIES;
+ stateNext <= STATE_SEND_LINK_REQUEST;
+ end if;
+
+ when STYPE0_PACKET_NOT_ACCEPTED =>
+ -- Packet was rejected by the link-partner.
+ -- REMARK: Indicate that this has happened to the outside...
+ counterNext <= NUMBER_LINK_RESPONSE_RETRIES;
+ stateNext <= STATE_SEND_LINK_REQUEST;
+
+ when STYPE0_LINK_RESPONSE =>
+ -- Dont expect or need a link-response in this state.
+ -- Discard it.
+
+ 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.
+ txControlUpdate_o <= '1';
+ else
+ -- No control symbol has been received.
+
+ -- Check if the oldest frame timeout has expired.
+ if ((ackIdCurrent /= ackIdWindowCurrent) and
+ (timeoutExpired = '1')) then
+ -- There has been a timeout on a transmitted frame.
+
+ -- Send link-request.
+ counterNext <= NUMBER_LINK_RESPONSE_RETRIES;
+ stateNext <= STATE_SEND_LINK_REQUEST;
+ else
+ -- There has been no timeout.
+
+ -- Check if the outbound fifo needs new data.
+ if (txFull_i = '0') then
+ -- There is room available in the outbound FIFO.
+
+ -- Check if there are any events from the receiver.
+ if (rxControlEmpty_i = '0') then
+ -- A symbol from the receiver should be transmitted.
+
+ -- Send the receiver symbol and a NOP.
+ -- REMARK: Combine this symbol with an STYPE1 to more effectivly
+ -- utilize the link.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= rxControlStype0;
+ parameter0 <= rxControlParameter0;
+ parameter1 <= rxControlParameter1;
+ stype1 <= STYPE1_NOP;
+ cmd <= "000";
+
+ -- Remove the symbol from the fifo.
+ rxControlUpdate_o <= '1';
+
+ -- Check if the transmitted symbol contains status about
+ -- available buffers.
+ if ((rxControlStype0 = STYPE0_PACKET_ACCEPTED) or
+ (rxControlStype0 = STYPE0_PACKET_RETRY)) then
+ -- A symbol containing the bufferStatus has been sent.
+ symbolsTransmittedNext <= 0;
+ else
+ -- A symbol not containing the bufferStatus has been sent.
+ -- REMARK: symbolsTransmitted might overflow...
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+ end if;
+ else
+ -- No events from the receiver.
+
+ -- Check if a status symbol must be sent.
+ if (symbolsTransmittedCurrent = 255) then
+ -- A status symbol must be sent.
+
+ -- Reset the number of transmitted symbols between statuses.
+ symbolsTransmittedNext <= 0;
+
+ -- Send status.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= STYPE0_STATUS;
+ parameter0 <= ackIdStatus_i;
+ parameter1 <= "11111";
+ stype1 <= STYPE1_NOP;
+ cmd <= "000";
+ else
+ -- A status symbol does not have to be sent.
+
+ -- Check if a frame transfer is in progress.
+ case frameStateCurrent is
+
+ when FRAME_START =>
+ ---------------------------------------------------------------
+ -- No frame has been started.
+ ---------------------------------------------------------------
+
+ -- Wait for a new frame to arrive from the frame buffer,
+ -- for new buffers to be available at the link-partner
+ -- and also check that a maximum 31 frames are outstanding.
+ if ((readWindowEmpty_i = '0') and (bufferStatusCurrent /= "00000") and
+ ((ackIdWindowCurrent - ackIdCurrent) /= 31)) then
+ -- New data is available for transmission and there
+ -- is room to receive it at the other side.
+
+ -- Indicate that a control symbol has been sent to start the
+ -- transmission of the frame.
+ frameStateNext <= FRAME_CHECK;
+
+ -- Update the output from the frame buffer to contain the
+ -- data when it is read later.
+ readContent_o <= '1';
+ else
+ -- There are no frame data to send or the link partner has
+ -- no available buffers.
+
+ -- Send idle-sequence.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_IDLE;
+
+ -- A symbol not containing the buffer status has been sent.
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+ end if;
+
+ when FRAME_CHECK =>
+ -------------------------------------------------------
+ -- Check if we are allowed to transmit this packet.
+ -------------------------------------------------------
+
+ -- Check if this packet is allowed to be transmitted.
+ if ((portEnable_i = '1') or (readContentData_i(19 downto 16) = FTYPE_MAINTENANCE_CLASS)) then
+ -- The packet may be transmitted.
+
+ -- Indicate that a control symbol has been sent to start the
+ -- transmission of the frame.
+ frameStateNext <= FRAME_ACKID;
+
+ -- Send a control symbol to start the packet and a status to complete
+ -- the symbol.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= STYPE0_STATUS;
+ parameter0 <= ackIdStatus_i;
+ parameter1 <= "11111";
+ stype1 <= STYPE1_START_OF_PACKET;
+ cmd <= "000";
+
+ -- A symbol containing the bufferStatus has been sent.
+ symbolsTransmittedNext <= 0;
+ else
+ -- The packet should be discarded.
+
+ -- Check that there are no outstanding packets that
+ -- has not been acknowledged.
+ if(ackIdWindowCurrent /= ackIdCurrent) then
+ -- There are packets that has not been acknowledged.
+
+ -- Send idle-sequence.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_IDLE;
+
+ -- A symbol not containing the buffer status has been sent.
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+ else
+ -- No unacknowledged packets.
+ -- It is now safe to remove the unallowed frame.
+ readFrame_o <= '1';
+
+ -- Go back and send a new frame.
+ frameStateNext <= FRAME_START;
+ end if;
+ end if;
+
+ when FRAME_ACKID =>
+ ---------------------------------------------------------------
+ -- Send the first packet content containing our current
+ -- ackId.
+ ---------------------------------------------------------------
+
+ -- Write a new data symbol and fill in our ackId on the
+ -- packet.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_DATA;
+ symbolData <= std_logic_vector(ackIdWindowCurrent) & "0" & readContentData_i(25 downto 0);
+
+ -- Continue to send the rest of the body of the packet.
+ readContent_o <= '1';
+ frameStateNext <= FRAME_BODY;
+
+ -- A symbol not containing the buffer status has been sent.
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+
+ when FRAME_BODY =>
+ ---------------------------------------------------------------
+ -- The frame has not been fully sent.
+ -- Send a data symbol.
+ ---------------------------------------------------------------
+ -- REMARK: Add support for partial frames...
+
+ -- Check if the frame is ending.
+ if (readContentEnd_i = '0') then
+ -- The frame is not ending.
+
+ -- Write a new data symbol.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_DATA;
+ symbolData <= readContentData_i;
+
+ -- Continue to send the rest of the body of the packet.
+ readContent_o <= '1';
+
+ -- A symbol not containing the buffer status has been sent.
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+ else
+ -- The frame is ending.
+
+ -- Update the window to the next frame.
+ -- It takes one tick for the output from the frame
+ -- buffer to get updated.
+ readWindowNext_o <= '1';
+
+ -- Proceed to check if there is another frame to start
+ -- with directly.
+ frameStateNext <= FRAME_END;
+ end if;
+
+ when FRAME_END =>
+ ---------------------------------------------------------------
+ -- A frame has ended and the window has been updated.
+ -- Check if the next symbol should end the frame or if a
+ -- new one should be started.
+ ---------------------------------------------------------------
+
+ -- Check if there is a new frame pending.
+ if (readWindowEmpty_i = '1') then
+ -- No new frame is pending.
+
+ -- Send a control symbol to end the packet.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= STYPE0_STATUS;
+ parameter0 <= ackIdStatus_i;
+ parameter1 <= "11111";
+ stype1 <= STYPE1_END_OF_PACKET;
+ cmd <= "000";
+
+ -- A symbol containing the bufferStatus has been sent.
+ symbolsTransmittedNext <= 0;
+ end if;
+
+ -- Update the window ackId.
+ ackIdWindowNext <= ackIdWindowCurrent + 1;
+
+ -- Start timeout supervision for transmitted frame.
+ timeoutWrite <= '1';
+ timeoutAddress <= std_logic_vector(ackIdWindowCurrent);
+
+ -- Start a new frame the next time.
+ frameStateNext <= FRAME_START;
+
+ when others =>
+ ---------------------------------------------------------------
+ --
+ ---------------------------------------------------------------
+ null;
+
+ end case;
+ end if;
+ end if;
+ else
+ -- Wait for new storage in the transmission FIFO to become
+ -- available.
+ -- Dont do anything.
+ end if;
+ end if;
+ end if;
+ else
+ -- The port or the link has become uninitialized.
+ -- Go back to the uninitialized state.
+ stateNext <= STATE_UNINITIALIZED;
+ end if;
+
+ when STATE_OUTPUT_RETRY_STOPPED =>
+ -----------------------------------------------------------------------
+ -- This is the output-retry-stopped state described in 5.9.1.5.
+ -----------------------------------------------------------------------
+
+ -- Check if the outbound fifo needs new data.
+ if (txFull_i = '0') then
+ -- There is room available in the outbound FIFO.
+
+ -- Send a restart-from-retry control symbol to acknowledge the restart
+ -- of the frame.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= STYPE0_STATUS;
+ parameter0 <= ackIdStatus_i;
+ parameter1 <= "11111";
+ stype1 <= STYPE1_RESTART_FROM_RETRY;
+ cmd <= "000";
+
+ -- Make sure there wont be any timeout before the frame is
+ -- starting to be retransmitted.
+ timeoutWrite <= '1';
+ timeoutAddress <= std_logic_vector(ackIdCurrent);
+
+ -- Restart the frame transmission.
+ ackIdWindowNext <= ackIdCurrent;
+ frameStateNext <= FRAME_START;
+ readWindowReset_o <= '1';
+
+ -- Proceed back to the normal state.
+ stateNext <= STATE_NORMAL;
+
+ -- A symbol containing the bufferStatus has been sent.
+ symbolsTransmittedNext <= 0;
+ end if;
+
+ when STATE_SEND_LINK_REQUEST =>
+ -----------------------------------------------------------------------
+ -- Send a link-request symbol when the transmission fifo is ready. Then
+ -- always proceed to the output-error-state.
+ -----------------------------------------------------------------------
+
+ -- Check if the outbound fifo needs new data.
+ if (txFull_i = '0') then
+ -- There is room available in the outbound FIFO.
+
+ -- Send a link-request symbol.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= STYPE0_STATUS;
+ parameter0 <= ackIdStatus_i;
+ parameter1 <= "11111";
+ stype1 <= STYPE1_LINK_REQUEST;
+ cmd <= LINK_REQUEST_CMD_INPUT_STATUS;
+
+ -- Write the current timer value.
+ timeoutWrite <= '1';
+ timeoutAddress <= std_logic_vector(ackIdCurrent);
+
+ -- Proceed to the output-error-stopped state.
+ stateNext <= STATE_OUTPUT_ERROR_STOPPED;
+
+ -- A symbol containing the bufferStatus has been sent.
+ symbolsTransmittedNext <= 0;
+ end if;
+
+ when STATE_OUTPUT_ERROR_STOPPED =>
+ -------------------------------------------------------------------
+ -- This state is the error stopped state described in 5.13.2.7.
+ -------------------------------------------------------------------
+
+ -- Check that both the port and link is initialized.
+ if (portInitialized_i = '1') and (linkInitialized_i = '1') then
+ -- The port and link is initialized.
+
+ -- 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_PACKET_ACCEPTED =>
+ -- Wait for a link-response.
+ -- Discard these.
+
+ when STYPE0_PACKET_RETRY =>
+ -- Wait for a link-response.
+ -- Discard these.
+
+ when STYPE0_PACKET_NOT_ACCEPTED =>
+ -- Wait for a link-response.
+ -- Discard these.
+
+ when STYPE0_STATUS =>
+ -- Wait for a link-response.
+ -- Discard these.
+
+ when STYPE0_LINK_RESPONSE =>
+ -- Check if the link partner return value is acceptable.
+ if ((unsigned(txControlParameter0) - ackIdCurrent) <=
+ (ackIdWindowCurrent - ackIdCurrent)) then
+ -- Recoverable error.
+ -- Use the received ackId and recover by removing packets
+ -- that were received by the link-partner.
+ ackIdWindowNext <= unsigned(txControlParameter0);
+ stateNext <= STATE_RECOVER;
+ else
+ -- Totally out of sync.
+ stateNext <= STATE_FATAL_ERROR;
+ end if;
+
+ when STYPE0_VC_STATUS =>
+ -- Not supported.
+
+ when STYPE0_RESERVED =>
+ -- Not supported.
+
+ when STYPE0_IMPLEMENTATION_DEFINED =>
+ -- Not supported.
+
+ when others =>
+ null;
+ end case;
+
+ -- Indicate the control symbol has been processed.
+ txControlUpdate_o <= '1';
+ else
+ -- No control symbol has been received.
+
+ -- Check if the timeout for a link-response has expired.
+ if (timeoutExpired = '1') then
+ -- There was no reply on the link-request.
+
+ -- Count the number of retransmissions and abort if
+ -- no reply has been received for too many times.
+ if (counterCurrent /= 0) then
+ -- Not sent link-request too many times.
+
+ -- Send another link-request.
+ counterNext <= counterCurrent - 1;
+ stateNext <= STATE_SEND_LINK_REQUEST;
+ else
+ -- No response for too many times.
+ stateNext <= STATE_FATAL_ERROR;
+ end if;
+ else
+ -- There has been no timeout.
+
+ -- Check if the outbound fifo needs new data.
+ if (txFull_i = '0') then
+ -- There is room available in the outbound FIFO.
+
+ -- Check if there are any events from the receiver.
+ if (rxControlEmpty_i = '0') then
+ -- A symbol from the receiver should be transmitted.
+
+ -- Send the receiver symbol and a NOP.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= rxControlStype0;
+ parameter0 <= rxControlParameter0;
+ parameter1 <= rxControlParameter1;
+ stype1 <= STYPE1_NOP;
+ cmd <= "000";
+
+ -- Remove the symbol from the fifo.
+ rxControlUpdate_o <= '1';
+
+ -- Check if the transmitted symbol contains status about
+ -- available buffers.
+ -- The receiver never send any status so that does not have
+ -- to be checked.
+ if ((rxControlStype0 = STYPE0_PACKET_ACCEPTED) or
+ (rxControlStype0 = STYPE0_PACKET_RETRY)) then
+ -- A symbol containing the bufferStatus has been sent.
+ symbolsTransmittedNext <= 0;
+ else
+ -- A symbol not containing the buffer status has been sent.
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+ end if;
+ else
+ -- No events from the receiver.
+ -- There are no frame data to send or the link partner has
+ -- no available buffers.
+
+ -- Check if a status symbol must be sent.
+ if (symbolsTransmittedCurrent = 255) then
+ -- A status symbol must be sent.
+
+ -- Reset the number of transmitted symbols between statuses.
+ symbolsTransmittedNext <= 0;
+
+ -- Send status.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= STYPE0_STATUS;
+ parameter0 <= ackIdStatus_i;
+ parameter1 <= "11111";
+ stype1 <= STYPE1_NOP;
+ cmd <= "000";
+ else
+ -- A status symbol does not have to be sent.
+
+ -- Send idle-sequence.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_IDLE;
+
+ -- A symbol not containing the buffer status has been sent.
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+ end if;
+ end if;
+ else
+ -- Wait for new storage in the transmission FIFO to become
+ -- available.
+ -- Dont do anything.
+ end if;
+ end if;
+ end if;
+ else
+ -- The port or the link has become uninitialized.
+ -- Go back to the uninitialized state.
+ stateNext <= STATE_UNINITIALIZED;
+ end if;
+
+ when STATE_RECOVER =>
+ -----------------------------------------------------------------------
+ -- A recoverable error condition has occurred.
+ -- When this state is entered, ackIdWindow should contain the ackId to
+ -- proceed with.
+ -----------------------------------------------------------------------
+
+ -- Check if the expected ackId has incremented enough.
+ if (ackIdCurrent /= ackIdWindowCurrent) then
+ -- Remove this frame. It has been received by the link-partner.
+ readFrame_o <= '1';
+ ackIdNext <= ackIdCurrent + 1;
+ else
+ -- Keep this frame.
+ -- Restart the window and the frame transmission.
+ frameStateNext <= FRAME_START;
+ readWindowReset_o <= '1';
+ stateNext <= STATE_NORMAL;
+ end if;
+
+ when STATE_FATAL_ERROR =>
+ -----------------------------------------------------------------------
+ -- A fatal error condition has occurred.
+ -----------------------------------------------------------------------
+
+ -- Reset the window and resynchronize the link.
+ -- REMARK: Count these situations...
+ -- REMARK: Do something else here???
+ readWindowReset_o <= '1';
+ stateNext <= STATE_UNINITIALIZED;
+
+ when others =>
+ -------------------------------------------------------------------
+ --
+ -------------------------------------------------------------------
+ null;
+ end case;
+ end if;
+ end process;
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+entity RioReceiver is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ -- Status signals used for maintenance.
+ portEnable_i : in std_logic;
+
+ -- Support for localAckIdCSR.
+ localAckIdWrite_i : in std_logic;
+ inboundAckId_i : in std_logic_vector(4 downto 0);
+ inboundAckId_o : out std_logic_vector(4 downto 0);
+
+ -- Port input interface.
+ portInitialized_i : in std_logic;
+ rxEmpty_i : in std_logic;
+ rxRead_o : out std_logic;
+ rxControl_i : in std_logic_vector(1 downto 0);
+ rxData_i : in std_logic_vector(31 downto 0);
+
+ -- Receiver has received a control symbol containing:
+ -- packet-accepted, packet-retry, packet-not-accepted,
+ -- status, VC_status, link-response
+ txControlWrite_o : out std_logic;
+ txControlSymbol_o : out std_logic_vector(12 downto 0);
+
+ -- Reciever wants to signal the link partner:
+ -- a new frame has been accepted => packet-accepted(rxAckId, bufferStatus)
+ -- a frame needs to be retransmitted due to buffering =>
+ -- packet-retry(rxAckId, bufferStatus)
+ -- a frame is rejected due to errors => packet-not-accepted
+ -- a link-request should be answered => link-response
+ rxControlWrite_o : out std_logic;
+ rxControlSymbol_o : out std_logic_vector(12 downto 0);
+
+ -- Status signals used internally.
+ ackIdStatus_o : out std_logic_vector(4 downto 0);
+ linkInitialized_o : out std_logic;
+
+ -- 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(31 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+architecture RioReceiverImpl of RioReceiver 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;
+
+ type StateType is (STATE_UNINITIALIZED, STATE_PORT_INITIALIZED,
+ STATE_NORMAL,
+ STATE_INPUT_RETRY_STOPPED, STATE_INPUT_ERROR_STOPPED);
+ signal state : StateType;
+
+ signal statusCounter : natural range 0 to 8;
+
+ signal ackId : unsigned(4 downto 0);
+ signal frameIndex : natural range 0 to 70;
+
+ signal stype0 : std_logic_vector(2 downto 0);
+ signal parameter0 : std_logic_vector(4 downto 0);
+ signal parameter1 : std_logic_vector(4 downto 0);
+ signal stype1 : std_logic_vector(2 downto 0);
+ signal cmd : std_logic_vector(2 downto 0);
+
+ signal crc5 : std_logic_vector(4 downto 0);
+ signal crc5Calculated : std_logic_vector(4 downto 0);
+
+ signal crc16Valid : 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 rxRead : std_logic;
+
+begin
+
+ linkInitialized_o <= '0' when ((state = STATE_UNINITIALIZED) or
+ (state = STATE_PORT_INITIALIZED)) else '1';
+ ackIdStatus_o <= std_logic_vector(ackId);
+
+ -----------------------------------------------------------------------------
+ -- Get the entries in a control symbol.
+ -----------------------------------------------------------------------------
+
+ stype0 <= rxData_i(31 downto 29);
+ parameter0 <= rxData_i(28 downto 24);
+ parameter1 <= rxData_i(23 downto 19);
+ stype1 <= rxData_i(18 downto 16);
+ cmd <= rxData_i(15 downto 13);
+ crc5 <= rxData_i(12 downto 8);
+
+ -----------------------------------------------------------------------------
+ -- Entity for CRC-5 calculation on control symbols according to the standard.
+ -----------------------------------------------------------------------------
+
+ Crc5Calculator: Crc5ITU
+ port map(
+ d_i=>rxData_i(31 downto 13), crc_o=>crc5Calculated);
+
+ -----------------------------------------------------------------------------
+ -- Entities for CRC-16 calculation on 32-bit data in frames according to the
+ -- standard.
+ -----------------------------------------------------------------------------
+
+ -- If the CRC is correct, there is either zero in crc16Next if no pad exists
+ -- or zero in crc16Temp and crc16Data(15 downto 0). This means that crc16Next
+ -- will always be zero here if the CRC is correct.
+ crc16Valid <= '1' when (crc16Next = x"0000") else '0';
+
+ 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);
+
+ -----------------------------------------------------------------------------
+ -- Main inbound symbol handler.
+ -----------------------------------------------------------------------------
+ rxRead_o <= rxRead;
+ inboundAckId_o <= std_logic_vector(ackId);
+ process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ state <= STATE_UNINITIALIZED;
+
+ rxRead <= '0';
+ txControlWrite_o <= '0';
+ txControlSymbol_o <= (others => '0');
+ rxControlWrite_o <= '0';
+ rxControlSymbol_o <= (others => '0');
+
+ writeFrame_o <= '0';
+ writeFrameAbort_o <= '0';
+ writeContent_o <= '0';
+ writeContentData_o <= (others => '0');
+
+ -- REMARK: Use frameIndex instead of this...
+ statusCounter <= 0;
+
+ frameIndex <= 0;
+ ackId <= (others => '0');
+
+ crc16Current <= (others => '0');
+ crc16Data <= (others => '0');
+ elsif (clk'event and clk = '1') then
+ rxRead <= '0';
+
+ txControlWrite_o <= '0';
+ rxControlWrite_o <= '0';
+
+ writeFrame_o <= '0';
+ writeFrameAbort_o <= '0';
+ writeContent_o <= '0';
+
+ -- Check if a locakAckIdWrite is active.
+ if (localAckIdWrite_i = '1') then
+ -- A localAckIdWrite is active.
+ -- Set ackId.
+ ackId <= unsigned(inboundAckId_i);
+ else
+ -- A localAckIdWrite is not active.
+
+ -- Act on the current state.
+ case state is
+
+ when STATE_UNINITIALIZED =>
+ -----------------------------------------------------------------------
+ -- This state is entered at startup. A port that is not initialized
+ -- should discard all received symbols.
+ -----------------------------------------------------------------------
+
+ -- Check if the port is initialized.
+ if (portInitialized_i = '0') then
+ -- Port not initialized.
+
+ -- Check if a new symbol is ready to be read.
+ if (rxRead = '0') and (rxEmpty_i = '0') then
+ -- New symbol ready.
+ -- Discard all received symbols in this state.
+ rxRead <= '1';
+ else
+ -- No new symbol ready to be read.
+ -- Dont do anything.
+ end if;
+ else
+ -- Port is initialized.
+
+ -- Go to the initialized state and reset the counters.
+ state <= STATE_PORT_INITIALIZED;
+ statusCounter <= 0;
+ end if;
+
+ when STATE_PORT_INITIALIZED =>
+ ---------------------------------------------------------------------
+ -- The port has been initialized and status control symbols are being
+ -- received on the link to check if it is working. Count the number
+ -- of error-free status symbols and considder the link initialized
+ -- 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 a new symbol is ready to be read.
+ if (rxRead = '0') and (rxEmpty_i = '0') then
+ -- There is a new symbol to read.
+
+ -- Check the type of symbol.
+ if (rxControl_i = SYMBOL_CONTROL) then
+ -- This is a control symbol that is not a packet delimiter.
+
+ -- Check if the control symbol has a valid checksum.
+ if (crc5Calculated = crc5) then
+ -- The control symbol has a valid checksum.
+
+ -- Forward the stype0 part of the symbol to the transmitter.
+ txControlWrite_o <= '1';
+ txControlSymbol_o <= stype0 & parameter0 & parameter1;
+
+ -- Check the stype0 part if we should count the number of
+ -- error-free status symbols.
+ if (stype0 = STYPE0_STATUS) then
+ -- The symbol is a status.
+
+ -- Check if enough status symbols have been received.
+ if (statusCounter = 7) then
+ -- Enough status symbols have been received.
+
+ -- Reset all packets.
+ frameIndex <= 0;
+ writeFrameAbort_o <= '1';
+
+ -- Set the link as initialized.
+ state <= STATE_NORMAL;
+ else
+ -- Increase the number of error-free status symbols that
+ -- has been received.
+ statusCounter <= statusCounter + 1;
+ end if;
+ else
+ -- The symbol is not a status.
+ -- Dont do anything.
+ end if;
+ else
+ -- A control symbol with CRC5 error was recevied.
+ statusCounter <= 0;
+ end if;
+ else
+ -- Symbol that is not allowed in this state have been received.
+ -- Discard it.
+ end if;
+
+ -- Update to the next symbol.
+ rxRead <= '1';
+ else
+ -- No new symbol ready to be read.
+ -- Dont do anything.
+ end if;
+ else
+ -- Go back to the uninitialized state.
+ state <= STATE_UNINITIALIZED;
+ end if;
+
+ when STATE_NORMAL =>
+ ---------------------------------------------------------------------
+ -- 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 a new symbol is ready to be read.
+ if (rxRead = '0') and (rxEmpty_i = '0') then
+ -- There is a new symbol to read.
+
+ -- Check the type of symbol.
+ if (rxControl_i = SYMBOL_CONTROL) then
+ -- This is a control symbol with or without a packet delimiter.
+
+ -- Check if the control symbol has a valid CRC-5.
+ if (crc5Calculated = crc5) then
+ -- The control symbol is correct.
+
+ -- Forward the stype0 part of the symbol to the transmitter.
+ txControlWrite_o <= '1';
+ txControlSymbol_o <= stype0 & parameter0 & parameter1;
+
+ -- Check the stype1 part.
+ case stype1 is
+
+ when STYPE1_START_OF_PACKET =>
+ -------------------------------------------------------------
+ -- Start the reception of a new frame or end a currently
+ -- ongoing frame.
+ -------------------------------------------------------------
+
+ -- Check if a frame has already been started.
+ if (frameIndex /= 0) then
+ -- A frame is already started.
+ -- Complete the last frame and start to ackumulate a new one
+ -- and update the ackId.
+
+ -- Check the CRC-16 and the length of the received frame.
+ if (crc16Valid = '1') and (frameIndex > 3) then
+ -- The CRC-16 is ok.
+
+ -- Reset the frame index to indicate the frame is started.
+ frameIndex <= 1;
+
+ -- Update the frame buffer to indicate that the frame has
+ -- been completly received.
+ writeFrame_o <= '1';
+
+ -- Update ackId.
+ ackId <= ackId + 1;
+
+ -- Send packet-accepted.
+ -- The buffer status is appended by the transmitter
+ -- when sent to get the latest number.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_ACCEPTED & std_logic_vector(ackId) & "11111";
+ else
+ -- The CRC-16 is not ok.
+
+ -- Make the transmitter send a packet-not-accepted to indicate
+ -- that the received packet contained a CRC error.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_NOT_ACCEPTED &
+ "00000" &
+ PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
+ state <= STATE_INPUT_ERROR_STOPPED;
+ end if;
+ else
+ -- No frame has been started.
+
+ -- Reset the frame index to indicate the frame is started.
+ frameIndex <= 1;
+ end if;
+
+ when STYPE1_END_OF_PACKET =>
+ -------------------------------------------------------------
+ -- End the reception of an old frame.
+ -------------------------------------------------------------
+
+ -- Check the CRC-16 and the length of the received frame.
+ if (crc16Valid = '1') and (frameIndex > 3) then
+ -- The CRC-16 is ok.
+
+ -- Reset frame reception to indicate that no frame is ongoing.
+ frameIndex <= 0;
+
+ -- Update the frame buffer to indicate that the frame has
+ -- been completly received.
+ writeFrame_o <= '1';
+
+ -- Update ackId.
+ ackId <= ackId + 1;
+
+ -- Send packet-accepted.
+ -- The buffer status is appended by the transmitter
+ -- when sent to get the latest number.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_ACCEPTED & std_logic_vector(ackId) & "11111";
+ else
+ -- The CRC-16 is not ok.
+
+ -- Make the transmitter send a packet-not-accepted to indicate
+ -- that the received packet contained a CRC error.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_NOT_ACCEPTED &
+ "00000" &
+ PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
+ state <= STATE_INPUT_ERROR_STOPPED;
+ end if;
+
+ when STYPE1_STOMP =>
+ -------------------------------------------------------------
+ -- Restart the reception of an old frame.
+ -------------------------------------------------------------
+ -- See 5.10 in the standard.
+
+ -- Make the transmitter send a packet-retry to indicate
+ -- that the packet cannot be accepted.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_RETRY & std_logic_vector(ackId) & "11111";
+
+ -- Enter the input retry-stopped state.
+ state <= STATE_INPUT_RETRY_STOPPED;
+
+ when STYPE1_RESTART_FROM_RETRY =>
+ -------------------------------------------------------------
+ -- The receiver indicates a restart from a retry sent
+ -- from us.
+ -------------------------------------------------------------
+ -- See 5.10 in the standard.
+ -- Protocol error, this symbol should not be received here since
+ -- we should have been in input-retry-stopped.
+
+ -- Send a packet-not-accepted to indicate that a protocol
+ -- error has occurred.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_NOT_ACCEPTED &
+ "00000" &
+ PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR;
+ state <= STATE_INPUT_ERROR_STOPPED;
+
+ when STYPE1_LINK_REQUEST =>
+ -------------------------------------------------------------
+ -- Reply to a LINK-REQUEST.
+ -------------------------------------------------------------
+
+ -- Check the command part.
+ if (cmd = "100") then
+ -- Return input port status command.
+ -- This functions as a link-request(restart-from-error)
+ -- control symbol under error situations.
+
+ -- Send a link response containing an ok reply.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_LINK_RESPONSE & std_logic_vector(ackId) & "10000";
+ elsif (cmd = "011") then
+ -- Reset device command.
+ -- Discard this.
+ else
+ -- Unsupported command.
+ -- Discard this.
+ end if;
+
+ -- Abort the frame and reset frame reception.
+ frameIndex <= 0;
+ writeFrameAbort_o <= '1';
+
+ when STYPE1_MULTICAST_EVENT =>
+ -------------------------------------------------------------
+ -- Multicast symbol.
+ -------------------------------------------------------------
+ -- Discard the symbol.
+
+ when STYPE1_RESERVED =>
+ -------------------------------------------------------------
+ -- Reserved.
+ -------------------------------------------------------------
+ -- Not supported, dont do anything.
+
+ when STYPE1_NOP =>
+ -------------------------------------------------------------
+ -- NOP, no operation.
+ -------------------------------------------------------------
+ -- Dont do anything.
+
+ when others =>
+ -------------------------------------------------------------
+ --
+ -------------------------------------------------------------
+ -- NOP, no operation, dont do anything.
+ null;
+
+ end case;
+ else
+ -- The control symbol contains a crc error.
+
+ -- Send a packet-not-accepted to indicate that a corrupted
+ -- control-symbol has been received and change state.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_NOT_ACCEPTED &
+ "00000" &
+ PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC;
+ state <= STATE_INPUT_ERROR_STOPPED;
+ end if;
+ elsif (rxControl_i = SYMBOL_DATA) then
+ -- This is a data symbol.
+ -- REMARK: Add check for in-the-middle-crc here...
+
+ -- Check if a frame has been started.
+ -- Index=0 not started
+ -- index=1 started and expecting to receive the first data.
+ -- index=others, the index of the received data.
+ if (frameIndex /= 0) and (frameIndex /= 70) then
+ -- A frame has been started and is not too long.
+
+ -- Check if the ackId is correct.
+ if (((frameIndex = 1) and (unsigned(rxData_i(31 downto 27)) = ackId)) or
+ (frameIndex /= 1)) then
+ -- This is the first data symbol containing the ackId which
+ -- is matching or receiving the rest of the frame.
+
+ -- Check if the packet ftype is allowed.
+ -- If the portEnable is deasserted only maintenance
+ -- packets are allowed.
+ if (((frameIndex = 1) and
+ ((portEnable_i = '1') or (rxData_i(19 downto 16) = FTYPE_MAINTENANCE_CLASS))) or
+ (frameIndex /= 1)) then
+ -- The packet is allowed.
+
+ -- Check if there is buffers available to store the new packet.
+ if(writeFrameFull_i = '0') then
+ -- There is buffering space available to store the new data.
+
+ -- Write the data to the frame FIFO.
+ writeContent_o <= '1';
+ writeContentData_o <= rxData_i;
+
+ -- Increment the number of received data symbols.
+ frameIndex <= frameIndex + 1;
+
+ -- Update the saved crc result with the output from the CRC calculation.
+ if (frameIndex = 1) then
+ -- Note that the ackId should not be included when the CRC
+ -- is calculated.
+ crc16Data <= "000000" & rxData_i(25 downto 0);
+ crc16Current <= (others => '1');
+ else
+ crc16Data <= rxData_i;
+ crc16Current <= crc16Next;
+ end if;
+ else
+ -- The packet buffer is full.
+ -- Let the link-partner resend the packet.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_RETRY & std_logic_vector(ackId) & "11111";
+ state <= STATE_INPUT_RETRY_STOPPED;
+ end if;
+ else
+ -- The non-maintenance packets are not allowed.
+ -- Send packet-not-accepted.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <=
+ STYPE0_PACKET_NOT_ACCEPTED & "00000" & PACKET_NOT_ACCEPTED_CAUSE_NON_MAINTENANCE_STOPPED;
+ state <= STATE_INPUT_ERROR_STOPPED;
+ end if;
+ else
+ -- The ackId is unexpected.
+ -- Send packet-not-accepted.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <=
+ STYPE0_PACKET_NOT_ACCEPTED & "00000" & PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID;
+ state <= STATE_INPUT_ERROR_STOPPED;
+ end if;
+ else
+ -- A frame has not been started or is too long.
+ -- Send packet-not-accepted.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_NOT_ACCEPTED & "00000" & PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR;
+ state <= STATE_INPUT_ERROR_STOPPED;
+ end if;
+ else
+ -- Idle sequence received.
+ -- Discard these.
+ end if;
+
+ -- Update to the next symbol.
+ rxRead <= '1';
+ else
+ -- No new symbol received.
+ -- Dont do anything.
+ end if;
+ else
+ -- The port has become uninitialized.
+ -- Go back to the uninitialized state.
+ state <= STATE_UNINITIALIZED;
+ end if;
+
+ when STATE_INPUT_RETRY_STOPPED =>
+ ---------------------------------------------------------------------
+ -- This state is entered when a frame could not be accepted. All
+ -- symbols except restart-from-retry and link-request are discarded.
+ -- A restart-from-retry triggers a state change into the normal
+ -- link-initialized state.
+ ---------------------------------------------------------------------
+
+ -- Check that the port is initialized.
+ if (portInitialized_i = '1') then
+ -- The port and link is initialized.
+
+ -- Check if a new symbol is ready to be read.
+ if (rxRead = '0') and (rxEmpty_i = '0') then
+ -- There is a new symbol to read.
+
+ -- Check the type of symbol.
+ if (rxControl_i = SYMBOL_CONTROL) then
+ -- This is a control symbol with or without a packet delimiter.
+
+ -- Check if the control symbol has a valid CRC-5.
+ if (crc5Calculated = crc5) then
+ -- The control symbol is correct.
+
+ -- Forward the stype0 part of the symbol to the transmitter.
+ txControlWrite_o <= '1';
+ txControlSymbol_o <= stype0 & parameter0 & parameter1;
+
+ -- Check the stype1 part.
+ case stype1 is
+
+ when STYPE1_RESTART_FROM_RETRY =>
+ -------------------------------------------------------------
+ -- The receiver indicates a restart from a retry sent
+ -- from us.
+ -------------------------------------------------------------
+
+ -- Abort the frame and reset frame reception.
+ frameIndex <= 0;
+ writeFrameAbort_o <= '1';
+
+ -- Go back to the normal operational state.
+ state <= STATE_NORMAL;
+
+ when STYPE1_LINK_REQUEST =>
+ -------------------------------------------------------------
+ -- Received a link-request.
+ -------------------------------------------------------------
+
+ -- Check the command part.
+ if (cmd = "100") then
+ -- Return input port status command.
+ -- This functions as a link-request(restart-from-error)
+ -- control symbol under error situations.
+
+ -- Send a link response containing an ok reply.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_LINK_RESPONSE & std_logic_vector(ackId) & "00100";
+ elsif (cmd = "011") then
+ -- Reset device command.
+ -- Discard this.
+ else
+ -- Unsupported command.
+ -- Discard this.
+ end if;
+
+ -- Abort the frame and reset frame reception.
+ frameIndex <= 0;
+ writeFrameAbort_o <= '1';
+
+ -- Go back to the normal operational state.
+ state <= STATE_NORMAL;
+
+ when others =>
+ -------------------------------------------------------------
+ --
+ -------------------------------------------------------------
+ -- Discard other control symbols.
+ null;
+
+ end case;
+ else
+ -- The control symbol contains a crc error.
+
+ -- Send a packet-not-accepted to indicate that a corrupted
+ -- control-symbol has been received and change state.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_NOT_ACCEPTED &
+ "00000" &
+ PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC;
+ state <= STATE_INPUT_ERROR_STOPPED;
+ end if;
+ elsif (rxControl_i = SYMBOL_DATA) then
+ -- This is a data symbol.
+ -- Discard all data symbols in this state.
+ else
+ -- Idle sequence received.
+ -- Discard other symbols.
+ end if;
+
+ -- Update to the next symbol.
+ rxRead <= '1';
+ else
+ -- No new symbol received.
+ -- Dont do anything.
+ end if;
+ else
+ -- The port has become uninitialized.
+ -- Go back to the uninitialized state.
+ state <= STATE_UNINITIALIZED;
+ end if;
+
+ when STATE_INPUT_ERROR_STOPPED =>
+ ---------------------------------------------------------------------
+ -- This state is entered when an error situation has occurred. When in this
+ -- state, all symbols should be discarded until a link-request-symbols has
+ -- been received. See section 5.13.2.6 in part 6 of the standard.
+ -- Note that it is only the input side of the port that are affected, not the
+ -- output side. Packets may still be transmitted and acknowledges should be
+ -- accepted.
+ ---------------------------------------------------------------------
+
+ -- Check that the port is initialized.
+ if (portInitialized_i = '1') then
+ -- The port and link is initialized.
+
+ -- Check if a new symbol is ready to be read.
+ if (rxRead = '0') and (rxEmpty_i = '0') then
+ -- There is a new symbol to read.
+
+ -- Check the type of symbol.
+ if (rxControl_i = SYMBOL_CONTROL) then
+ -- This is a control symbol with or without a packet delimiter.
+
+ -- Check if the control symbol has a valid CRC-5.
+ if (crc5Calculated = crc5) then
+ -- The control symbol is correct.
+
+ -- Forward the stype0 part of the symbol to the transmitter.
+ txControlWrite_o <= '1';
+ txControlSymbol_o <= stype0 & parameter0 & parameter1;
+
+ -- Check the stype1 part.
+ case stype1 is
+
+ when STYPE1_LINK_REQUEST =>
+ -------------------------------------------------------------
+ -- Received a link-request.
+ -------------------------------------------------------------
+
+ -- Check the command part.
+ -- REMARK: Should also send a status-control-symbol
+ -- directly following this symbol...
+ if (cmd = "100") then
+ -- Return input port status command.
+ -- This functions as a link-request(restart-from-error)
+ -- control symbol under error situations.
+
+ -- Send a link response containing an ok reply.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_LINK_RESPONSE & std_logic_vector(ackId) & "00101";
+ elsif (cmd = "011") then
+ -- Reset device command.
+ -- Discard this.
+ else
+ -- Unsupported command.
+ -- Discard this.
+ end if;
+
+ -- Abort the frame and reset frame reception.
+ frameIndex <= 0;
+ writeFrameAbort_o <= '1';
+
+ -- Go back to the normal operational state.
+ state <= STATE_NORMAL;
+
+ when others =>
+ -------------------------------------------------------------
+ --
+ -------------------------------------------------------------
+ -- Discard other control symbols.
+ null;
+
+ end case;
+ else
+ -- The control symbol contains a crc error.
+ -- Error is ignored in this state.
+ end if;
+ else
+ -- Other symbol received.
+ -- All other symbols are discarded in this state.
+ end if;
+
+ -- Update to the next symbol.
+ rxRead <= '1';
+ else
+ -- No new symbol received.
+ -- Dont do anything.
+ end if;
+ else
+ -- The port has become uninitialized.
+ -- Go back to the uninitialized state.
+ state <= STATE_UNINITIALIZED;
+ end if;
+
+ when others =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+ null;
+ end case;
+ end if;
+ end if;
+ end process;
+
+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;
1.0.1/rtl/vhdl/RioSerial.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/rtl/vhdl/RioPacketBuffer.vhd
===================================================================
--- 1.0.1/rtl/vhdl/RioPacketBuffer.vhd (nonexistent)
+++ 1.0.1/rtl/vhdl/RioPacketBuffer.vhd (revision 29)
@@ -0,0 +1,873 @@
+-------------------------------------------------------------------------------
+--
+-- 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.
+--
+-- Generic variables
+-- -----------------
+-- SIZE_ADDRESS_WIDTH - The number of frames in powers of two.
+-- CONTENT_ADDRESS_WIDTH - The total number of entries in the memory that can
+-- be used to store packet data.
+-- CONTENT_WIDTH - The width of the data to store as packet content in the memory.
+-- MAX_PACKET_SIZE - The number of entries that must be available for a new
+-- complete full sized packet to be received. This option is present to ensure
+-- that it is always possible to move a packet to the storage without being
+-- surprised that the storage is suddenly empty.
+-------------------------------------------------------------------------------
+entity RioPacketBuffer is
+ generic(
+ SIZE_ADDRESS_WIDTH : natural := 6;
+ CONTENT_ADDRESS_WIDTH : natural := 8;
+ CONTENT_WIDTH : natural := 32;
+ MAX_PACKET_SIZE : natural := 69);
+ 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(CONTENT_WIDTH-1 downto 0);
+ inboundReadFrameEmpty_o : out std_logic;
+ inboundReadFrame_i : in std_logic;
+ inboundReadFrameRestart_i : in std_logic;
+ inboundReadFrameAborted_o : out std_logic;
+ inboundReadFrameSize_o : out std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0);
+ inboundReadContentEmpty_o : out std_logic;
+ inboundReadContent_i : in std_logic;
+ inboundReadContentEnd_o : out std_logic;
+ inboundReadContentData_o : out std_logic_vector(CONTENT_WIDTH-1 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(CONTENT_WIDTH-1 downto 0);
+ outboundReadFrameEmpty_o : out std_logic;
+ outboundReadFrame_i : in std_logic;
+ outboundReadFrameRestart_i : in std_logic;
+ outboundReadFrameAborted_o : out std_logic;
+ outboundReadFrameSize_o : out std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0);
+ outboundReadContentEmpty_o : out std_logic;
+ outboundReadContent_i : in std_logic;
+ outboundReadContentEnd_o : out std_logic;
+ outboundReadContentData_o : out std_logic_vector(CONTENT_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for RioPacketBuffer.
+-------------------------------------------------------------------------------
+architecture RioPacketBufferImpl of RioPacketBuffer is
+
+ component PacketBufferContinous is
+ generic(
+ SIZE_ADDRESS_WIDTH : natural;
+ CONTENT_ADDRESS_WIDTH : natural;
+ CONTENT_WIDTH : natural;
+ MAX_PACKET_SIZE : 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(CONTENT_WIDTH-1 downto 0);
+
+ readFrameEmpty_o : out std_logic;
+ readFrame_i : in std_logic;
+ readFrameRestart_i : in std_logic;
+ readFrameAborted_o : out std_logic;
+ readFrameSize_o : out std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0);
+ readContentEmpty_o : out std_logic;
+ readContent_i : in std_logic;
+ readContentEnd_o : out std_logic;
+ readContentData_o : out std_logic_vector(CONTENT_WIDTH-1 downto 0));
+ end component;
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Outbound frame buffers.
+ -----------------------------------------------------------------------------
+ OutboundPacketBuffer: PacketBufferContinous
+ generic map(
+ SIZE_ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH,
+ CONTENT_ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH,
+ CONTENT_WIDTH=>CONTENT_WIDTH,
+ MAX_PACKET_SIZE=>MAX_PACKET_SIZE)
+ 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,
+ readFrameSize_o=>outboundReadFrameSize_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,
+ CONTENT_WIDTH=>CONTENT_WIDTH,
+ MAX_PACKET_SIZE=>MAX_PACKET_SIZE)
+ 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,
+ readFrameSize_o=>inboundReadFrameSize_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;
+ CONTENT_WIDTH : natural := 32;
+ MAX_PACKET_SIZE : natural := 69);
+ 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(CONTENT_WIDTH-1 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(CONTENT_WIDTH-1 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(CONTENT_WIDTH-1 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(CONTENT_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for RioPacketBufferWindow.
+-------------------------------------------------------------------------------
+architecture RioPacketBufferWindowImpl of RioPacketBufferWindow is
+
+ component PacketBufferContinous is
+ generic(
+ SIZE_ADDRESS_WIDTH : natural;
+ CONTENT_ADDRESS_WIDTH : natural;
+ CONTENT_WIDTH : natural;
+ MAX_PACKET_SIZE : 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(CONTENT_WIDTH-1 downto 0);
+
+ readFrameEmpty_o : out std_logic;
+ readFrame_i : in std_logic;
+ readFrameRestart_i : in std_logic;
+ readFrameAborted_o : out std_logic;
+ readFrameSize_o : out std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0);
+
+ readContentEmpty_o : out std_logic;
+ readContent_i : in std_logic;
+ readContentEnd_o : out std_logic;
+ readContentData_o : out std_logic_vector(CONTENT_WIDTH-1 downto 0));
+ end component;
+
+ component PacketBufferContinousWindow is
+ generic(
+ SIZE_ADDRESS_WIDTH : natural;
+ CONTENT_ADDRESS_WIDTH : natural;
+ CONTENT_WIDTH : natural;
+ MAX_PACKET_SIZE : 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(CONTENT_WIDTH-1 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(CONTENT_WIDTH-1 downto 0));
+ end component;
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Outbound frame buffers.
+ -----------------------------------------------------------------------------
+ OutboundPacketBuffer: PacketBufferContinousWindow
+ generic map(
+ SIZE_ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH,
+ CONTENT_ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH,
+ CONTENT_WIDTH=>CONTENT_WIDTH,
+ MAX_PACKET_SIZE=>MAX_PACKET_SIZE)
+ 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,
+ CONTENT_WIDTH=>CONTENT_WIDTH,
+ MAX_PACKET_SIZE=>MAX_PACKET_SIZE)
+ 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,
+ readFrameSize_o=>open,
+ 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;
+ CONTENT_WIDTH : natural;
+ MAX_PACKET_SIZE : 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(CONTENT_WIDTH-1 downto 0);
+
+ readFrameEmpty_o : out std_logic;
+ readFrame_i : in std_logic;
+ readFrameRestart_i : in std_logic;
+ readFrameAborted_o : out std_logic;
+ readFrameSize_o : out std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0);
+
+ readContentEmpty_o : out std_logic;
+ readContent_i : in std_logic;
+ readContentEnd_o : out std_logic;
+ readContentData_o : out std_logic_vector(CONTENT_WIDTH-1 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 < MAX_PACKET_SIZE)) 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';
+ readFrameSize_o <= std_logic_vector(readFrameEnd_p - memoryStart_p);
+
+ 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=>CONTENT_WIDTH)
+ 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;
+ CONTENT_WIDTH : natural;
+ MAX_PACKET_SIZE : 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(CONTENT_WIDTH-1 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(CONTENT_WIDTH-1 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 < MAX_PACKET_SIZE)) 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(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;
+ 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=>CONTENT_WIDTH)
+ 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;
1.0.1/rtl/vhdl/RioPacketBuffer.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/rtl/vhdl/RioPcsUart.vhd
===================================================================
--- 1.0.1/rtl/vhdl/RioPcsUart.vhd (nonexistent)
+++ 1.0.1/rtl/vhdl/RioPcsUart.vhd (revision 29)
@@ -0,0 +1,641 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- This file contains a PCS (Physical Control Sublayer) that can transfer
+-- RapidIO symbols accross a 2Mbit 8-bit UART transmission channel.
+-- The coding is similar to the coding used by PPP and uses flags (0x7e)
+-- and escape-sequences (0x7d) to encode special characters.
+--
+-- 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
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- RioPcsUart
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for RioPcsUart.
+-------------------------------------------------------------------------------
+entity RioPcsUart is
+ generic(
+ DIVISOR_WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ divisor_i : in std_logic_vector(DIVISOR_WIDTH-1 downto 0);
+
+ portInitialized_o : out std_logic;
+ outboundSymbolEmpty_i : in std_logic;
+ outboundSymbolRead_o : out std_logic;
+ outboundSymbol_i : in std_logic_vector(33 downto 0);
+ inboundSymbolFull_i : in std_logic;
+ inboundSymbolWrite_o : out std_logic;
+ inboundSymbol_o : out std_logic_vector(33 downto 0);
+
+ serial_o : out std_logic;
+ serial_i : in std_logic);
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for RioPcsUart.
+-------------------------------------------------------------------------------
+architecture RioPcsUartImpl of RioPcsUart is
+
+ component RioSymbolConverter is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ portInitialized_o : out std_logic;
+ outboundSymbolEmpty_i : in std_logic;
+ outboundSymbolRead_o : out std_logic;
+ outboundSymbol_i : in std_logic_vector(33 downto 0);
+ inboundSymbolFull_i : in std_logic;
+ inboundSymbolWrite_o : out std_logic;
+ inboundSymbol_o : out std_logic_vector(33 downto 0);
+
+ uartEmpty_i : in std_logic;
+ uartRead_o : out std_logic;
+ uartData_i : in std_logic_vector(7 downto 0);
+ uartFull_i : in std_logic;
+ uartWrite_o : out std_logic;
+ uartData_o : out std_logic_vector(7 downto 0));
+ end component;
+
+ component Uart is
+ generic(
+ DIVISOR_WIDTH : natural;
+ DATA_WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ divisor_i : in std_logic_vector(DIVISOR_WIDTH-1 downto 0);
+
+ serial_i : in std_logic;
+ serial_o : out std_logic;
+
+ empty_o : out std_logic;
+ read_i : in std_logic;
+ data_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ full_o : out std_logic;
+ write_i : in std_logic;
+ data_i : in std_logic_vector(DATA_WIDTH-1 downto 0));
+ end component;
+
+ signal uartEmpty : std_logic;
+ signal uartRead : std_logic;
+ signal uartReadData : std_logic_vector(7 downto 0);
+ signal uartFull : std_logic;
+ signal uartWrite : std_logic;
+ signal uartWriteData : std_logic_vector(7 downto 0);
+
+begin
+
+ SymbolConverter: RioSymbolConverter
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ portInitialized_o=>portInitialized_o,
+ outboundSymbolEmpty_i=>outboundSymbolEmpty_i,
+ outboundSymbolRead_o=>outboundSymbolRead_o, outboundSymbol_i=>outboundSymbol_i,
+ inboundSymbolFull_i=>inboundSymbolFull_i,
+ inboundSymbolWrite_o=>inboundSymbolWrite_o, inboundSymbol_o=>inboundSymbol_o,
+ uartEmpty_i=>uartEmpty, uartRead_o=>uartRead, uartData_i=>uartReadData,
+ uartFull_i=>uartFull, uartWrite_o=>uartWrite, uartData_o=>uartWriteData);
+
+ UartInst: Uart
+ generic map(DIVISOR_WIDTH=>DIVISOR_WIDTH, DATA_WIDTH=>8)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ divisor_i=>divisor_i,
+ serial_i=>serial_i, serial_o=>serial_o,
+ empty_o=>uartEmpty, read_i=>uartRead, data_o=>uartReadData,
+ full_o=>uartFull, write_i=>uartWrite, data_i=>uartWriteData);
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- This module encodes and decodes RapidIO symbols for transmission on a 8-bit
+-- UART using HDLC-like framing (see PPP).
+-- When an idle-symbol is received it will be preceeded by an idle link for a
+-- few micro seconds. This idle link time is used to synchronize the receiver
+-- in the link partner that needs to know when a character is starting and not.
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for RioSymbolConverter.
+-------------------------------------------------------------------------------
+entity RioSymbolConverter is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ portInitialized_o : out std_logic;
+ outboundSymbolEmpty_i : in std_logic;
+ outboundSymbolRead_o : out std_logic;
+ outboundSymbol_i : in std_logic_vector(33 downto 0);
+ inboundSymbolFull_i : in std_logic;
+ inboundSymbolWrite_o : out std_logic;
+ inboundSymbol_o : out std_logic_vector(33 downto 0);
+
+ uartEmpty_i : in std_logic;
+ uartRead_o : out std_logic;
+ uartData_i : in std_logic_vector(7 downto 0);
+ uartFull_i : in std_logic;
+ uartWrite_o : out std_logic;
+ uartData_o : out std_logic_vector(7 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for RioSymbolConverter.
+-------------------------------------------------------------------------------
+architecture RioSymbolConverterImpl of RioSymbolConverter is
+
+ -- Define the flag sequence and the control escape sequence.
+ constant FLAG_SEQUENCE : std_logic_vector(7 downto 0) := x"7e";
+ constant CONTROL_ESCAPE : std_logic_vector(7 downto 0) := x"7d";
+ constant SILENCE_TIME : natural := 4095;
+ constant IDLE_SYMBOL_TIME : natural := 256;
+ constant LINK_LOST_TIME : natural := 4095;
+
+ type TxStateType is (STATE_SILENCE, STATE_IDLE_0, STATE_IDLE_1,
+ STATE_BUSY_1, STATE_BUSY_2, STATE_SEND_FLAG);
+ signal txState : TxStateType;
+ signal txStateCounter : unsigned(1 downto 0);
+ signal outboundSymbolData : std_logic_vector(7 downto 0);
+
+ type RxStateType is (STATE_INIT, STATE_NORMAL);
+ signal rxState : RxStateType;
+ signal rxStateCounter : unsigned(1 downto 0);
+ signal escapeFound : std_logic;
+
+ signal txTimerReset : std_logic;
+ signal txTimerEnable : std_logic;
+ signal txTimerCounter : unsigned(11 downto 0);
+ signal silenceTxTimerDone : std_logic;
+ signal idleTxTimerDone : std_logic;
+
+ signal rxTimerReset : std_logic;
+ signal rxTimerEnable : std_logic;
+ signal rxTimerCounter : unsigned(11 downto 0);
+ signal lostRxTimerDone : std_logic;
+
+ signal uartWrite : std_logic;
+ signal uartRead : std_logic;
+
+begin
+
+ -- Set the port initialized once the receiver enters its normal state.
+ portInitialized_o <= '1' when (rxState = STATE_NORMAL) else '0';
+
+ -----------------------------------------------------------------------------
+ -- Timer functionallity.
+ -----------------------------------------------------------------------------
+
+ silenceTxTimerDone <= '1' when (txTimerCounter = SILENCE_TIME) else '0';
+ idleTxTimerDone <= '1' when (txTimerCounter = IDLE_SYMBOL_TIME) else '0';
+
+ process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ txTimerCounter <= (others => '0');
+ elsif (clk'event and clk = '1') then
+ if (txTimerReset = '1') then
+ txTimerCounter <= (others => '0');
+ elsif (txTimerEnable = '1') then
+ txTimerCounter <= txTimerCounter + 1;
+ end if;
+ end if;
+ end process;
+
+ lostRxTimerDone <= '1' when (rxTimerCounter = LINK_LOST_TIME) else '0';
+
+ process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ rxTimerCounter <= (others => '0');
+ elsif (clk'event and clk = '1') then
+ if (rxTimerReset = '1') then
+ rxTimerCounter <= (others => '0');
+ elsif (rxTimerEnable = '1') then
+ rxTimerCounter <= rxTimerCounter + 1;
+ end if;
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Link symbol encoder process.
+ -----------------------------------------------------------------------------
+ outboundSymbolData <= outboundSymbol_i(31 downto 24) when txStateCounter = 0 else
+ outboundSymbol_i(23 downto 16) when txStateCounter = 1 else
+ outboundSymbol_i(15 downto 8) when txStateCounter = 2 else
+ outboundSymbol_i(7 downto 0);
+
+ uartWrite_o <= uartWrite;
+ Outbound: process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ txState <= STATE_SILENCE;
+ txStateCounter <= (others => '0');
+
+ txTimerReset <= '0';
+ txTimerEnable <= '0';
+
+ outboundSymbolRead_o <= '0';
+
+ uartWrite <= '0';
+ uartData_o <= (others => '0');
+ elsif (clk'event and clk = '1') then
+ txTimerReset <= '0';
+ outboundSymbolRead_o <= '0';
+ uartWrite <= '0';
+
+ -- Check if the UART is ready for new data.
+ if (uartFull_i = '0') and (uartWrite = '0') then
+ -- The UART want new data to transmitt.
+
+ -- Check the transmission state.
+ case txState is
+
+ when STATE_SILENCE =>
+ -------------------------------------------------------------------
+ -- Wait for a while to let the linkpartner detect a link break.
+ -------------------------------------------------------------------
+ -- Check if the silence timer has expired.
+ if (silenceTxTimerDone = '1') then
+ -- Silence timer expired.
+ -- Reset the timer and proceed to transmitting symbols.
+ txTimerReset <= '1';
+ txTimerEnable <= '0';
+ txState <= STATE_IDLE_0;
+ else
+ txTimerEnable <= '1';
+ end if;
+
+ when STATE_IDLE_0 =>
+ -----------------------------------------------------------------
+ -- Wait for a new symbol to be received. An idle symbol is followed
+ -- by a small inter-character idle time to let the receiver in the
+ -- link partner synchronize itself to the link.
+ -----------------------------------------------------------------
+
+ -- Reset the state counter for the symbol generation.
+ txStateCounter <= "00";
+
+ -- Check if a new symbol is available.
+ if (outboundSymbolEmpty_i = '0') then
+ -- A new symbol is available.
+
+ -- Check if the new symbol is idle, control or data.
+ if (outboundSymbol_i(33 downto 32) /= SYMBOL_IDLE) then
+ -- Control or data symbol.
+ txState <= STATE_BUSY_1;
+ else
+ -- Send idle sequence.
+ txState <= STATE_IDLE_1;
+ end if;
+ else
+ -- No new symbols are ready.
+ -- Dont do anything.
+ end if;
+
+ when STATE_IDLE_1 =>
+ -------------------------------------------------------------------
+ -- Wait until the idle timer has expired to let the link be idle in
+ -- between idle symbols.
+ -------------------------------------------------------------------
+
+ -- Check if the idle timer has expired.
+ if (idleTxTimerDone = '1') then
+ -- Idle timer has expired.
+ -- Reset the timer and disable it.
+ txTimerReset <= '1';
+ txTimerEnable <= '0';
+
+ -- Write a flag to indicate idle link.
+ uartWrite <= '1';
+ uartData_o <= FLAG_SEQUENCE;
+
+ -- Get a new symbol.
+ outboundSymbolRead_o <= '1';
+ txState <= STATE_IDLE_0;
+ else
+ -- Idle timer has not expired yet.
+ txTimerEnable <= '1';
+ end if;
+
+ when STATE_BUSY_1 =>
+ -----------------------------------------------------------------
+ -- Encode a control or data symbol. If stuffing is needed the next
+ -- busy state is called.
+ -----------------------------------------------------------------
+
+ -- Check if the octet is a flag or escape character.
+ if ((outboundSymbolData = FLAG_SEQUENCE) or
+ (outboundSymbolData = CONTROL_ESCAPE)) then
+ -- Flag or escape octet.
+ uartWrite <= '1';
+ uartData_o <= CONTROL_ESCAPE;
+ txState <= STATE_BUSY_2;
+ else
+ -- Ordinary octet.
+
+ -- Write the octet to the uart.
+ uartWrite <= '1';
+ uartData_o <= outboundSymbolData;
+
+ -- Update to the next octet in the symbol.
+ txStateCounter <= txStateCounter + 1;
+
+ -- Check if the symbol has been sent.
+ if (txStateCounter = 3) then
+ -- Data symbol sent.
+ outboundSymbolRead_o <= '1';
+ txState <= STATE_IDLE_0;
+ elsif ((txStateCounter = 2) and
+ (outboundSymbol_i(33 downto 32) /= SYMBOL_DATA)) then
+ -- Control symbol sent.
+ txState <= STATE_SEND_FLAG;
+ else
+ -- Symbol not completly sent.
+ txState <= STATE_BUSY_1;
+ end if;
+ end if;
+
+ when STATE_BUSY_2 =>
+ -----------------------------------------------------------------
+ -- Byte stuff a flag or escape sequence found in the symbol data
+ -- content.
+ -----------------------------------------------------------------
+
+ -- Byte stuff the control character.
+ uartWrite <= '1';
+ uartData_o <= outboundSymbolData xor x"20";
+
+ -- Update to the next symbol.
+ txStateCounter <= txStateCounter + 1;
+
+ -- Check if the symbol has been sent.
+ if (txStateCounter = 3) then
+ -- Data symbol sent.
+ outboundSymbolRead_o <= '1';
+ txState <= STATE_IDLE_0;
+ elsif ((txStateCounter = 2) and
+ (outboundSymbol_i(33 downto 32) /= SYMBOL_DATA)) then
+ -- Control symbol sent.
+ txState <= STATE_SEND_FLAG;
+ else
+ -- Symbol not completly sent.
+ txState <= STATE_BUSY_1;
+ end if;
+
+ when STATE_SEND_FLAG =>
+ -----------------------------------------------------------------
+ -- Force a flag to be written to the link.
+ -----------------------------------------------------------------
+
+ uartWrite <= '1';
+ uartData_o <= FLAG_SEQUENCE;
+ outboundSymbolRead_o <= '1';
+ txState <= STATE_IDLE_0;
+
+ when others =>
+ -----------------------------------------------------------------
+ -- Unknown state.
+ -----------------------------------------------------------------
+ txState <= STATE_IDLE_0;
+
+ end case;
+ else
+ -- The UART is busy transmitting.
+ -- Wait for the UART to complete.
+ end if;
+ end if;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Link symbol decoder process.
+ -----------------------------------------------------------------------------
+ uartRead_o <= uartRead;
+ Inbound: process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ rxState <= STATE_INIT;
+ rxStateCounter <= (others => '0');
+ escapeFound <= '0';
+
+ rxTimerReset <= '0';
+ rxTimerEnable <= '0';
+
+ inboundSymbolWrite_o <= '0';
+ inboundSymbol_o <= (others => '0');
+
+ uartRead <= '0';
+ elsif (clk'event and clk = '1') then
+ rxTimerReset <= '0';
+ inboundSymbolWrite_o <= '0';
+ uartRead <= '0';
+
+ case rxState is
+
+ when STATE_INIT =>
+ -------------------------------------------------------------------
+ -- Wait for a flag to be received.
+ -------------------------------------------------------------------
+ -- Check if any new data is ready.
+ if (uartRead = '0') and (uartEmpty_i = '0') then
+ -- New data is ready from the uart.
+
+ -- Check if a flag has been received.
+ if (uartData_i = FLAG_SEQUENCE) then
+ -- A flag has been received.
+ -- Considder the port to be initialized.
+ rxState <= STATE_NORMAL;
+ rxStateCounter <= (others => '0');
+ escapeFound <= '0';
+ rxTimerReset <= '1';
+ rxTimerEnable <= '1';
+ uartRead <= '1';
+ else
+ -- Something that is not a flag has been received.
+ -- Discard the data and wait for a flag.
+ uartRead <= '1';
+ end if;
+ else
+ -- Waiting for inbound data.
+ -- Dont do anything.
+ end if;
+
+ when STATE_NORMAL =>
+ -------------------------------------------------------------------
+ -- Parse the incoming stream and create symbols.
+ -------------------------------------------------------------------
+
+ -- Check if the link lost timer has expired.
+ if (lostRxTimerDone = '1') then
+ -- The link lost timer has expired.
+ -- Reset the timer, disable it and go back to the initial state.
+ rxTimerReset <= '1';
+ rxTimerEnable <= '0';
+ rxState <= STATE_INIT;
+ else
+ -- The link lost timer has not expired.
+
+ -- Check if any new data is ready.
+ if (uartRead = '0') and (uartEmpty_i = '0') then
+ -- New data is ready from the uart.
+
+ -- Reset the link lost timer.
+ rxTimerReset <= '1';
+
+ -- Check if a flag has been received.
+ if (uartData_i /= FLAG_SEQUENCE) then
+ -- The received octet was not a flag.
+
+ -- Check if the octet was a contol character.
+ if (uartData_i /= CONTROL_ESCAPE) then
+ -- The octet was not a control character.
+
+ -- Check where in a symbol the reception is.
+ case rxStateCounter is
+
+ when "00" =>
+ inboundSymbol_o(33 downto 32) <= SYMBOL_IDLE;
+ if (escapeFound = '0') then
+ inboundSymbol_o(31 downto 24) <= uartData_i;
+ else
+ inboundSymbol_o(31 downto 24) <= uartData_i xor x"20";
+ end if;
+ rxStateCounter <= rxStateCounter + 1;
+
+ when "01" =>
+ inboundSymbol_o(33 downto 32) <= SYMBOL_IDLE;
+ if (escapeFound = '0') then
+ inboundSymbol_o(23 downto 16) <= uartData_i;
+ else
+ inboundSymbol_o(23 downto 16) <= uartData_i xor x"20";
+ end if;
+ rxStateCounter <= rxStateCounter + 1;
+
+ when "10" =>
+ inboundSymbol_o(33 downto 32) <= SYMBOL_CONTROL;
+ if (escapeFound = '0') then
+ inboundSymbol_o(15 downto 8) <= uartData_i;
+ else
+ inboundSymbol_o(15 downto 8) <= uartData_i xor x"20";
+ end if;
+ rxStateCounter <= rxStateCounter + 1;
+
+ when "11" =>
+ inboundSymbol_o(33 downto 32) <= SYMBOL_DATA;
+ if (escapeFound = '0') then
+ inboundSymbol_o(7 downto 0) <= uartData_i;
+ else
+ inboundSymbol_o(7 downto 0) <= uartData_i xor x"20";
+ end if;
+ rxStateCounter <= rxStateCounter + 1;
+ inboundSymbolWrite_o <= '1';
+
+ when others =>
+ rxStateCounter <= "00";
+
+ end case;
+
+ -- Read the octet from the uart.
+ uartRead <= '1';
+ escapeFound <= '0';
+ else
+ -- Control escape received.
+
+ -- Read the octet and indicate that an escape character has been received.
+ uartRead <= '1';
+ escapeFound <= '1';
+ end if;
+ else
+ -- Flag received.
+
+ -- Check if there are any unsent symbols pending.
+ if (rxStateCounter = 0) then
+ -- No pending symbol.
+ -- Send an idle symbol.
+ inboundSymbolWrite_o <= '1';
+ inboundSymbol_o(33 downto 32) <= SYMBOL_IDLE;
+ else
+ -- Pending symbol.
+ -- Send the pending symbol.
+ inboundSymbolWrite_o <= '1';
+ end if;
+
+ -- Read and discard the octet.
+ uartRead <= '1';
+ rxStateCounter <= "00";
+ end if;
+ else
+ -- Waiting for inbound data.
+ -- Dont do anything.
+ end if;
+ end if;
+
+ when others =>
+ -------------------------------------------------------------------
+ -- Unknown state.
+ -------------------------------------------------------------------
+ null;
+
+ end case;
+ end if;
+ end process;
+
+end architecture;
1.0.1/rtl/vhdl/RioPcsUart.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/rtl/vhdl/Uart.vhd
===================================================================
--- 1.0.1/rtl/vhdl/Uart.vhd (nonexistent)
+++ 1.0.1/rtl/vhdl/Uart.vhd (revision 29)
@@ -0,0 +1,349 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Generic UART with FIFO interface.
+--
+-- 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
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Uart implementation.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for Uart.
+-------------------------------------------------------------------------------
+entity Uart is
+ generic(
+ DIVISOR_WIDTH : natural;
+ DATA_WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ divisor_i : in std_logic_vector(DIVISOR_WIDTH-1 downto 0);
+
+ serial_i : in std_logic;
+ serial_o : out std_logic;
+
+ empty_o : out std_logic;
+ read_i : in std_logic;
+ data_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ full_o : out std_logic;
+ write_i : in std_logic;
+ data_i : in std_logic_vector(DATA_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for Uart.
+-------------------------------------------------------------------------------
+architecture UartImpl of Uart is
+ signal bitDuration : unsigned(DIVISOR_WIDTH-1 downto 0);
+ signal bitSample : unsigned(DIVISOR_WIDTH-1 downto 0);
+
+ type StateTypeRx is (STATE_INIT, STATE_IDLE,
+ STATE_START, STATE_DATA, STATE_STOP);
+ signal rxState : StateTypeRx;
+ signal rxShifter : std_logic_vector(DATA_WIDTH-1 downto 0);
+ signal rxCounter : unsigned(DIVISOR_WIDTH-1 downto 0);
+ signal rxBitCounter : natural range 0 to DATA_WIDTH-1;
+ signal rxComplete : std_logic;
+ signal rxData : std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ type StateTypeRxFifo is (STATE_EMPTY, STATE_WAITREAD);
+ signal rxFifoState : StateTypeRxFifo;
+
+ type StateTypeTx is (STATE_IDLE, STATE_SEND);
+ signal txState : StateTypeTx;
+ signal txShifter : std_logic_vector(DATA_WIDTH downto 0);
+ signal txCounter : unsigned(DIVISOR_WIDTH-1 downto 0);
+ signal txBitCounter : natural range 0 to DATA_WIDTH+1;
+
+begin
+
+ -- Setup the tick values when a bit is complete and when to sample it.
+ bitDuration <= unsigned(divisor_i);
+ bitSample <= '0' & unsigned(divisor_i(DIVISOR_WIDTH-1 downto 1));
+
+ -----------------------------------------------------------------------------
+ -- UART receiving process.
+ -----------------------------------------------------------------------------
+ Receiver: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ rxState <= STATE_INIT;
+ rxShifter <= (others => '0');
+ rxBitCounter <= 0;
+ rxCounter <= (others => '0');
+
+ rxComplete <= '0';
+ rxData <= (others => '0');
+ elsif (clk'event and (clk = '1')) then
+ rxComplete <= '0';
+
+ case rxState is
+
+ when STATE_INIT =>
+ ---------------------------------------------------------------------
+ -- Wait for the line to become idle.
+ ---------------------------------------------------------------------
+ if (serial_i = '1') then
+ rxState <= STATE_IDLE;
+ end if;
+
+ when STATE_IDLE =>
+ ---------------------------------------------------------------------
+ -- Wait for a long enough start pulse.
+ ---------------------------------------------------------------------
+ if (serial_i = '0') then
+ -- The serial input is zero, indicating a start bit.
+
+ -- Check how long it has been zero.
+ if (rxCounter = bitSample) then
+ -- It has been zero long enough.
+ -- Proceed to read the full start bit before starting to sample
+ -- the data.
+ rxState <= STATE_START;
+ else
+ -- Stay in this state until it has lasted long enough.
+ end if;
+
+ -- Update to next sampling interval.
+ rxCounter <= rxCounter + 1;
+ else
+ -- The serial input is not zero.
+ -- Restart the sampling interval.
+ rxCounter <= (others => '0');
+ end if;
+
+ when STATE_START =>
+ ---------------------------------------------------------------------
+ -- Wait for the startbit to end.
+ ---------------------------------------------------------------------
+ if (rxCounter = bitDuration) then
+ rxCounter <= (others => '0');
+ rxState <= STATE_DATA;
+ else
+ rxCounter <= rxCounter + 1;
+ end if;
+
+ when STATE_DATA =>
+ ---------------------------------------------------------------------
+ -- Sample data bits where it's appropriate.
+ ---------------------------------------------------------------------
+ if (rxCounter = bitDuration) then
+ -- End of bit.
+ -- Check if all the data bits has been read.
+ if (rxBitCounter = (DATA_WIDTH-1)) then
+ -- All data bits read.
+ -- Read the stop bit.
+ rxState <= STATE_STOP;
+ rxBitCounter <= 0;
+ else
+ -- Continue to read more data bits.
+ rxBitCounter <= rxBitCounter + 1;
+ end if;
+
+ -- Restart sampling interval.
+ rxCounter <= (others => '0');
+ elsif (rxCounter = bitSample) then
+ -- Sample the bit and continue to sample until the bit ends.
+ rxShifter <= serial_i & rxShifter((DATA_WIDTH-1) downto 1);
+ rxCounter <= rxCounter + 1;
+ else
+ -- Wait for the middle or the end of the data to be reached.
+ rxCounter <= rxCounter + 1;
+ end if;
+
+ when STATE_STOP =>
+ ---------------------------------------------------------------------
+ -- Sample stop bit where it's appropriate.
+ ---------------------------------------------------------------------
+ if (rxCounter = bitSample) then
+ -- Sample the stop bit.
+
+ -- Check if the stop bit is valid.
+ if (serial_i = '1') then
+ -- The stop bit is ok.
+ -- Forward the read data.
+ rxComplete <= '1';
+ rxData <= rxShifter;
+ else
+ -- The stop bit is not ok.
+ -- Do not forward the data character.
+ end if;
+
+ -- Reset sampling counter and go back to the init state.
+ rxState <= STATE_INIT;
+ rxCounter <= (others => '0');
+ else
+ -- Wait for the middle or the end of the data to be reached.
+ rxCounter <= rxCounter + 1;
+ end if;
+
+ when others =>
+ ---------------------------------------------------------------------
+ -- Undefined state.
+ ---------------------------------------------------------------------
+ rxState <= STATE_IDLE;
+ rxCounter <= (others => '0');
+
+ end case;
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- UART receiver fifo.
+ -----------------------------------------------------------------------------
+ ReceiverFifo: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ empty_o <= '1';
+ data_o <= (others => '0');
+ rxFifoState <= STATE_EMPTY;
+ elsif (clk'event and (clk = '1')) then
+ case rxFifoState is
+
+ when STATE_EMPTY =>
+ -- Wait for data to be forwarded from the UART receiver.
+ if (rxComplete = '1') then
+ -- Indicate there is data to read from.
+ empty_o <= '0';
+ data_o <= rxData;
+ rxFifoState <= STATE_WAITREAD;
+ else
+ -- Wait for data to be received.
+ end if;
+
+ when STATE_WAITREAD =>
+ -- Wait for the data to be read from the output port.
+ if (read_i = '1') then
+ -- The data has been read.
+ empty_o <= '1';
+ rxFifoState <= STATE_EMPTY;
+ end if;
+ -- Check if new data has been forwarded from the UART.
+ if (rxComplete = '1') then
+ -- New data has been forwarded without the output port being read.
+ -- Overrun. Data has been lost.
+ -- REMARK: Indicate this???
+ end if;
+
+ when others =>
+ -- Undefined state.
+ rxFifoState <= STATE_EMPTY;
+ end case;
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- UART transmitter process.
+ -----------------------------------------------------------------------------
+ Transmitter: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ txState <= STATE_IDLE;
+ txShifter <= (others => '0');
+ txBitCounter <= 0;
+ txCounter <= (others => '0');
+
+ full_o <= '0';
+ serial_o <= '1';
+ elsif (clk'event and (clk = '1')) then
+ case txState is
+
+ when STATE_IDLE =>
+ ---------------------------------------------------------------------
+ -- Wait for new data to be input on the input port.
+ ---------------------------------------------------------------------
+ if (write_i = '1') then
+ -- New data present.
+ full_o <= '1';
+ txShifter <= "1" & data_i;
+ txCounter <= (others => '0');
+ txBitCounter <= 0;
+ txState <= STATE_SEND;
+ serial_o <= '0';
+ end if;
+
+ when STATE_SEND =>
+ ---------------------------------------------------------------------
+ -- Wait for the bit to be completly transmitted.
+ ---------------------------------------------------------------------
+ if (txCounter = bitDuration) then
+ -- The bit has been sent.
+
+ -- Check if the full character has been sent.
+ if (txBitCounter = (DATA_WIDTH+1)) then
+ -- Character has been sent.
+ full_o <= '0';
+ txState <= STATE_IDLE;
+ else
+ -- Character has not been sent yet.
+ -- Send the next bit.
+ serial_o <= txShifter(0);
+ txShifter <= "0" & txShifter(DATA_WIDTH downto 1);
+ txBitCounter <= txBitCounter + 1;
+ end if;
+
+ -- Update to the next bit.
+ txCounter <= (others => '0');
+ else
+ -- Wait for the end of the bit.
+ txCounter <= txCounter + 1;
+ end if;
+
+ when others =>
+ ---------------------------------------------------------------------
+ -- Undefined state.
+ ---------------------------------------------------------------------
+ txState <= STATE_IDLE;
+
+ end case;
+ end if;
+ end process;
+
+end architecture;
+
1.0.1/rtl/vhdl/Uart.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/rtl/vhdl/srio_pcs_struct.vhd
===================================================================
--- 1.0.1/rtl/vhdl/srio_pcs_struct.vhd (nonexistent)
+++ 1.0.1/rtl/vhdl/srio_pcs_struct.vhd (revision 29)
@@ -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: 1.0.1/rtl/vhdl/RioWbBridge.vhd
===================================================================
--- 1.0.1/rtl/vhdl/RioWbBridge.vhd (nonexistent)
+++ 1.0.1/rtl/vhdl/RioWbBridge.vhd (revision 29)
@@ -0,0 +1,935 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Containing a bridge between a RapidIO network and a Wishbone bus. Packets
+-- NWRITE and NREAD are currently supported.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Nader Kardouni, nader.kardouni@se.transport.bombardier.com
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE. See the GNU Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.numeric_std.ALL;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+use work.rio_common.all;
+
+-------------------------------------------------------------------------------
+-- entity for RioWbBridge.
+-------------------------------------------------------------------------------
+Entity RioWbBridge is
+ generic(
+ DEVICE_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_REV : std_logic_vector(31 downto 0);
+ ASSY_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_REV : std_logic_vector(15 downto 0);
+ DEFAULT_BASE_DEVICE_ID : std_logic_vector(15 downto 0) := x"ffff");
+ port(
+ clk : in std_logic; -- Main clock 25MHz
+ areset_n : in std_logic; -- Asynchronous reset, active low
+
+ readFrameEmpty_i : in std_logic;
+ readFrame_o : out std_logic;
+ readContent_o : out std_logic;
+ readContentEnd_i : in std_logic;
+ readContentData_i : in std_logic_vector(31 downto 0);
+
+ writeFrameFull_i : in std_logic;
+ writeFrame_o : out std_logic;
+ writeFrameAbort_o : out std_logic;
+ writeContent_o : out std_logic;
+ writeContentData_o : out std_logic_vector(31 downto 0);
+
+ -- interface to the peripherals module
+ wbStb_o : out std_logic; -- strob signal, active high
+ wbWe_o : out std_logic; -- write signal, active high
+ wbData_o : out std_logic_vector(7 downto 0); -- master data bus
+ wbAdr_o : out std_logic_vector(25 downto 0); -- master address bus
+ wbErr_i : in std_logic; -- error signal, high active
+ wbAck_i : in std_logic; -- slave acknowledge
+ wbData_i : in std_logic_vector(7 downto 0) -- slave data bus
+ );
+end;
+
+-------------------------------------------------------------------------------
+-- Architecture for RioWbBridge.
+-------------------------------------------------------------------------------
+architecture rtl of RioWbBridge is
+
+ component Crc16CITT is
+ port(
+ d_i : in std_logic_vector(15 downto 0);
+ crc_i : in std_logic_vector(15 downto 0);
+ crc_o : out std_logic_vector(15 downto 0));
+ end component;
+
+ constant RST_LVL : std_logic := '0';
+ constant BERR_UNKNOWN_DATA : std_logic_vector(7 downto 0) := X"08"; -- not valid data
+ constant BERR_FRAME_SIZE : std_logic_vector(7 downto 0) := X"81"; -- Frame code size error
+ constant BERR_FRAME_CODE : std_logic_vector(7 downto 0) := X"80"; -- Frame code type error
+ constant BERR_NOT_RESPONSE : std_logic_vector(7 downto 0) := X"86"; -- Not response from the device
+
+ type state_type_RioBrige is (IDLE, WAIT_HEADER_0, HEADER_0, HEADER_1, CHECK_OPERATION,
+ READ_ADDRESS, READ_FROM_FIFO, CHECK_ERROR, WRITE_DATA,
+ WRITE_TO_WB, WAIT_IDLE, SEND_DONE_0, SEND_DONE_1,
+ SEND_DONE_2, READ_FROM_WB, APPEND_CRC,
+ SEND_TO_FIFO, SEND_ERROR, SEND_FRAME, APPEND_CRC_AND_SEND,
+ SEND_MAINTENANCE_READ_RESPONSE_0, SEND_MAINTENANCE_READ_RESPONSE_1,
+ SEND_MAINTENANCE_WRITE_RESPONSE_0, SEND_MAINTENANCE_WRITE_RESPONSE_1);
+ signal stateRB, nextStateRB : state_type_RioBrige;
+ type byteArray8 is array (0 to 7) of std_logic_vector(7 downto 0);
+ signal dataLane : byteArray8;
+-- type byteArray4 is array (0 to 3) of std_logic_vector(7 downto 0);
+-- signal dataLaneS : byteArray4;
+ signal pos, byteOffset : integer range 0 to 7;
+ signal numberOfByte, byteCnt, headLen : integer range 0 to 256;
+ signal endianMsb, reserved, ready : std_logic;
+ signal start : std_logic;
+ signal wdptr : std_logic;
+ signal wbStb : std_logic;
+ signal xamsbs : std_logic_vector(1 downto 0);
+ signal ftype : std_logic_vector(3 downto 0);
+ signal ttype : std_logic_vector(3 downto 0);
+ signal size : std_logic_vector(3 downto 0);
+ signal tid : std_logic_vector(7 downto 0);
+ signal tt : std_logic_vector(1 downto 0);
+ signal errorCode : std_logic_vector(7 downto 0);
+ signal sourceId : std_logic_vector(15 downto 0);
+ signal destinationId : std_logic_vector(15 downto 0);
+ signal writeContentData : std_logic_vector(31 downto 0);
+ signal crc16Current, crc16Temp, crc16Next: std_logic_vector(15 downto 0);
+ signal tempAddr : std_logic_vector(25 downto 0);
+ signal timeOutCnt : std_logic_vector(14 downto 0);
+
+ -- Configuration memory signal declaration.
+ signal configEnable : std_logic;
+ signal configWrite : std_logic;
+ signal configAddress : std_logic_vector(23 downto 0);
+ signal configDataWrite : std_logic_vector(31 downto 0);
+ signal configDataRead : std_logic_vector(31 downto 0);
+ signal componentTag : std_logic_vector(31 downto 0);
+ signal baseDeviceId : std_logic_vector(15 downto 0) := DEFAULT_BASE_DEVICE_ID;
+ signal hostBaseDeviceIdLocked : std_logic;
+ signal hostBaseDeviceId : std_logic_vector(15 downto 0) := (others => '1');
+
+begin
+ wbStb_o <= wbStb;
+ writeContentData_o <= writeContentData;
+
+ Crc16High: Crc16CITT
+ port map(
+ d_i=>writeContentData(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp);
+ Crc16Low: Crc16CITT
+ port map(
+ d_i=>writeContentData(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next);
+
+
+
+ -----------------------------------------------------------------------------
+ -- wbInterfaceCtrl
+ -- This process handle the Wishbone interface to the RioWbBridge module.
+ -----------------------------------------------------------------------------
+ wbInterfaceCtrl: process(clk, areset_n)
+ variable Temp : std_logic_vector(2 downto 0);
+ begin
+ if areset_n = RST_LVL then
+ start <= '0';
+ wdptr <= '0';
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteCnt <= 0;
+ headLen <= 0;
+ byteOffset <= 0;
+ readFrame_o <= '0';
+ readContent_o <= '0';
+ writeFrame_o <= '0';
+ writeContent_o <= '0';
+ writeFrameAbort_o <= '0';
+ configWrite <= '0';
+ configEnable <= '0';
+ ready <= '0';
+ endianMsb <= '0';
+ stateRB <= IDLE;
+ nextStateRB <= IDLE;
+ tt <= (others => '0');
+ tid <= (others => '0');
+ size <= (others => '0');
+ ttype <= (others => '0');
+ ftype <= (others => '0');
+ xamsbs <= (others => '0');
+ sourceId <= (others => '0');
+ configDataWrite <= (others => '0');
+ destinationId <= (others => '0');
+ errorCode <= (others => '0');
+ tempAddr <= (others => '0');
+ wbAdr_o <= (others => '0');
+ wbData_o <= (others => '0');
+ writeContentData <= (others => '0');
+ dataLane <= (others =>(others => '0'));
+-- dataLaneS <= (others =>(others => '0'));
+ crc16Current <= (others => '0');
+ timeOutCnt <= (others => '0');
+ Temp := (others => '0');
+ elsif clk'event and clk ='1' then
+
+ case stateRB is
+ when IDLE =>
+ if (readFrameEmpty_i = '0') and (writeFrameFull_i = '0') then
+ readContent_o <= '1';
+ byteCnt <= 0;
+ ready <= '0';
+ endianMsb <= '1';
+ timeOutCnt <= (others => '0');
+ crc16Current <= (others => '1');
+ stateRB <= WAIT_HEADER_0;
+ else
+ start <= '0';
+ readFrame_o <= '0';
+ readContent_o <= '0';
+ writeFrame_o <= '0';
+ writeContent_o <= '0';
+ writeFrameAbort_o <= '0';
+ errorCode <= (others => '0');
+ writeContentData <= (others => '0');
+ dataLane <= (others =>(others => '0'));
+-- dataLaneS <= (others =>(others => '0'));
+ Temp := (others => '0');
+ end if;
+
+ when WAIT_HEADER_0 =>
+ stateRB <= HEADER_0;
+
+ when HEADER_0 =>
+ readContent_o <= '1'; -- read the header (frame 0)
+ tt <= readContentData_i(21 downto 20);
+ ftype <= readContentData_i(19 downto 16);
+ destinationId <= readContentData_i(15 downto 0);
+ stateRB <= HEADER_1;
+
+ when HEADER_1 => -- read the header (frame 1)
+ readContent_o <= '1';
+ ttype <= readContentData_i(15 downto 12);
+ size <= readContentData_i(11 downto 8);
+ tid <= readContentData_i(7 downto 0);
+ sourceId <= readContentData_i(31 downto 16);
+ stateRB <= READ_ADDRESS;
+
+ when READ_ADDRESS =>
+ readContent_o <= '0';
+ wdptr <= readContentData_i(2);
+ xamsbs <= readContentData_i(1 downto 0);
+ tempAddr <= readContentData_i(25 downto 3) & "000"; -- Wishbone address bus is 26 bits width
+ configAddress <= readContentData_i(23 downto 0); -- this line is in case of maintenance pakage (config-offset(21-bits)+wdptr(1-bit)+rsv(2-bits))
+ stateRB <= CHECK_ERROR;
+
+ when CHECK_ERROR =>
+ byteOffset <= pos; -- first byte position in the first payload
+ tempAddr <= tempAddr + pos; -- first address
+ if readContentEnd_i = '1' then -- check if data not valid i the switch buffer
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteOffset <= 0;
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= BERR_UNKNOWN_DATA; -- not valid data
+ stateRB <= SEND_ERROR;
+
+ -- check if error in the frame size for write pakage
+ elsif (reserved = '1') and (ftype = FTYPE_WRITE_CLASS) then
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteOffset <= 0;
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= BERR_FRAME_SIZE; -- Frame code size error
+ stateRB <= SEND_ERROR;
+
+ -- type 5 pakage formate, NWRITE transaction (write to peripherals) read payload from the buffer
+ elsif (ftype = FTYPE_WRITE_CLASS) and (ttype = "0100") and (tt = "01") then
+ readContent_o <= '1';
+ stateRB <= READ_FROM_FIFO; -- read the payload
+ nextStateRB <= SEND_ERROR; -- this is in case not valid data in switch buffer
+ headLen <= 12;
+
+ -- Type 2 pakage formate, NREAD transaction, (read from peripherals) write payload to the buffer
+ elsif (ftype = FTYPE_REQUEST_CLASS) and (ttype = "0100") and (tt = "01") then
+ writeContent_o <= '1'; -- write the header-0 of the Read Response pakage
+ writeContentData(15 downto 0) <= sourceId; -- write to the source address
+ writeContentData(19 downto 16) <= "1101"; -- Response pakage type 13, ftype Response
+ writeContentData(21 downto 20) <= "01"; -- tt
+ writeContentData(31 downto 22) <= "0000000000"; -- acckId, vc, cfr, prio
+ stateRB <= SEND_DONE_0; --
+ headLen <= 8;
+
+ -- Type 8 pakage formate, maintenance Read request
+ elsif (ftype = FTYPE_MAINTENANCE_CLASS) and (ttype = TTYPE_MAINTENANCE_READ_REQUEST) and (tt = "01") then
+ configWrite <= '0'; -- read config operation
+ configEnable <= '1'; -- enable signal to the memoryConfig process
+ writeContent_o <= '1';
+ -- write the header-0 of the Read Response pakage
+ writeContentData(15 downto 0) <= sourceId; -- write to the source address, this is a response pakage
+ writeContentData(19 downto 16) <= FTYPE_MAINTENANCE_CLASS; -- ftype, maintenance
+ writeContentData(21 downto 20) <= "01"; -- tt
+ writeContentData(31 downto 22) <= "0000000000"; -- acckId, vc, cfr, prio
+ stateRB <= SEND_MAINTENANCE_READ_RESPONSE_0;
+
+ -- Type 8 pakage formate, maintenance Write request
+ elsif (ftype = FTYPE_MAINTENANCE_CLASS) and (ttype = TTYPE_MAINTENANCE_WRITE_REQUEST) and (tt = "01") then
+ configWrite <= '1'; -- write config operation
+ writeContent_o <= '1'; -- write the header-0
+ writeContentData(15 downto 0) <= sourceId; -- write to the source address, this is a response pakage
+ writeContentData(19 downto 16) <= FTYPE_MAINTENANCE_CLASS; -- ftype, maintenance
+ writeContentData(21 downto 20) <= "01"; -- tt
+ writeContentData(31 downto 22) <= "0000000000"; -- acckId, vc, cfr, prio
+ stateRB <= SEND_MAINTENANCE_WRITE_RESPONSE_0;
+
+ -- Error: unexpected ftype or ttype
+ else
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteOffset <= 0;
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= BERR_FRAME_CODE;
+ stateRB <= SEND_ERROR; -- next state after the dataLane is stored in the switch buffer
+ end if;
+
+ when SEND_MAINTENANCE_READ_RESPONSE_0 =>
+ byteCnt <= 0;
+ configEnable <= '0'; -- disable signal to the memoryConfig process
+ -- write the header-1 of the Read Response pakage
+ writeContentData(7 downto 0) <= tid;
+ writeContentData(11 downto 8) <= "0000"; -- size/status
+ writeContentData(15 downto 12) <= TTYPE_MAINTENANCE_READ_RESPONSE; -- transaction type, Maintenance Read Response
+ writeContentData(31 downto 16) <= baseDeviceId; -- destination address, because this is a response pakage
+ crc16Current <= crc16Next; -- first frame's CRC
+ stateRB <= SEND_MAINTENANCE_READ_RESPONSE_1;
+
+ when SEND_MAINTENANCE_READ_RESPONSE_1 =>
+ byteCnt <= byteCnt + 1; -- using byteCnt as a counter
+ if byteCnt = 0 then
+ writeContentData <= X"FF" & X"000000"; -- write the filed with HOP + reserved
+ crc16Current <= crc16Next; -- second frame's CRC
+ elsif byteCnt = 1 then
+ if configAddress(2) = '0' then -- check the wdptr bit in the config offset field
+ writeContentData <= configDataRead; -- write payload-0 with data if wdptr='0'
+ else
+ writeContentData <= (others => '0'); -- write zeros
+ end if;
+ crc16Current <= crc16Next; -- third frame's CRC
+ elsif byteCnt = 2 then
+ if configAddress(2) = '0' then -- check the wdptr bit in the config offset field
+ writeContentData <= (others => '0'); -- write zeros
+ else
+ writeContentData <= configDataRead; -- write payload-1 with data if wdptr='1'
+ end if;
+ crc16Current <= crc16Next; -- forth frame's CRC
+ elsif byteCnt = 3 then
+ writeContentData <= crc16Next & X"0000"; -- write the CRC field
+ else
+ writeContent_o <= '0';
+ stateRB <= SEND_FRAME;
+ end if;
+
+ when SEND_MAINTENANCE_WRITE_RESPONSE_0 =>
+ byteCnt <= 0;
+ readContent_o <= '1'; -- read the config offset
+ if configAddress(2) = '0' then -- check the wdptr bit in the config offset field
+ configDataWrite <= readContentData_i; -- copy payload-0 if wdptr='0'
+ else
+ configDataWrite <= configDataWrite; -- do nothing
+ end if;
+ writeContentData(7 downto 0) <= tid;
+ writeContentData(11 downto 8) <= "0000"; -- size/status
+ writeContentData(15 downto 12) <= TTYPE_MAINTENANCE_WRITE_RESPONSE; -- transaction type, Maintenance Write Response
+ writeContentData(31 downto 16) <= baseDeviceId; -- destination address, because this is a response pakage
+ crc16Current <= crc16Next; -- first frame's CRC
+ stateRB <= SEND_MAINTENANCE_WRITE_RESPONSE_1;
+
+ when SEND_MAINTENANCE_WRITE_RESPONSE_1 =>
+ byteCnt <= byteCnt + 1; -- using byteCnt as a counter
+ if byteCnt = 0 then
+ writeContentData <= X"FF" & X"000000"; -- write the filed with HOP + reserved
+ crc16Current <= crc16Next; -- second frame's CRC
+ elsif byteCnt = 1 then
+ configEnable <= '1'; -- enable signal to the memoryConfig process
+ writeContentData <= crc16Next & X"0000"; -- write the CRC field
+ if configAddress(2) = '0' then -- check the wdptr bit in the config offset field
+ configDataWrite <= configDataWrite; -- do nothing
+ else
+ configDataWrite <= readContentData_i; -- copy payload-1 if wdptr='1'
+ end if;
+ else
+ configEnable <= '0'; -- disable signal to the memoryConfig process
+ readContent_o <= '0'; -- at this point even the frame's CRC is read from the buffer
+ writeContent_o <= '0';
+ stateRB <= SEND_FRAME;
+ end if;
+
+ when SEND_DONE_0 =>
+ writeContent_o <= '1';
+ writeContentData(7 downto 0) <= tid;
+ writeContentData(11 downto 8) <= "0000"; -- size/status
+ writeContentData(15 downto 12) <= "1000"; -- ttype
+ writeContentData(31 downto 16) <= baseDeviceId;
+ crc16Current <= crc16Next; -- first frame's CRC
+ stateRB <= SEND_DONE_1;
+
+ when SEND_DONE_1 =>
+ byteCnt <= 0;
+ dataLane <= (others =>(others => '0'));
+ writeContent_o <= '0'; -- this line is to make sure that the CRC is complete read
+ crc16Current <= crc16Next; -- second frame's CRC
+ wbAdr_o <= tempAddr;
+ tempAddr <= tempAddr + 1;
+ wbStb <= '1';
+ wbWe_o <= '0';
+ byteOffset <= pos;
+ stateRB <= READ_FROM_WB;
+
+ when READ_FROM_WB =>
+ if wbAck_i = '1' then
+ timeOutCnt <= (others => '0'); -- reset the time out conter
+ if wbErr_i = '0' then -- check if no error occur
+ if (byteCnt < numberOfByte - 1) then -- check if reach the last data byte
+ byteCnt <= byteCnt + 1;
+ if (byteCnt + headLen = 80) then -- when current position in payload is a CRC position
+ dataLane(0) <= crc16Current(15 downto 8);
+ dataLane(1) <= crc16Current(7 downto 0);
+ dataLane(2) <= wbData_i;
+ byteOffset <= 3;
+ elsif byteOffset < 7 then
+ dataLane(byteOffset) <= wbData_i;
+ byteOffset <= byteOffset + 1;
+ else -- dataLane vector is ready to send to fifo
+ dataLane(7) <= wbData_i;
+ byteOffset <= 0; -- Here, sets byteOffset for other response
+ stateRB <= SEND_TO_FIFO;
+ nextStateRB <= READ_FROM_WB; --
+ end if;
+ else -- get last data from Wishbone
+ wbStb <= '0';
+ byteCnt <= 0; -- Here, using byteCnt and reset it for other response
+ dataLane(byteOffset) <= wbData_i;
+ stateRB <= APPEND_CRC_AND_SEND;
+ if byteOffset < 7 then -- checking for CRC appending position
+ byteOffset <= byteOffset + 1;
+ else
+ byteOffset <= 0;
+ end if;
+ end if;
+
+ -- when Wishbone error occur
+ else
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteOffset <= 0;
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= wbData_i;
+ stateRB <= SEND_ERROR;
+ end if;
+ else -- when no acknowledge received
+ if timeOutCnt(13) = '1' then -- when waiting more than 1 ms for response from the device
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteOffset <= 0;
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= BERR_NOT_RESPONSE;
+ stateRB <= SEND_ERROR;
+ else
+ timeOutCnt <= timeOutCnt + 1;
+ end if;
+ end if;
+
+ -- appending CRC and write to the fifo when frame is shorter then 80 bytes
+ when APPEND_CRC_AND_SEND =>
+ writeContent_o <= '0';
+ byteCnt <= byteCnt + 1;
+ -- check if frame is shorter than 80 bytes
+ if (numberOfByte < 65) then
+ -- Yes, frame is shorter then 80 bytes
+ if byteCnt = 0 then
+ -- first write the current double word to the fifo
+ -- then put the CRC in the next double word
+ byteOffset <= 0;
+ stateRB <= SEND_TO_FIFO;
+ nextStateRB <= APPEND_CRC_AND_SEND;
+ elsif byteCnt = 1 then
+ -- append the CRC
+ writeContent_o <= '1';
+ writeContentData <= crc16Current & X"0000";
+ else
+ stateRB <= SEND_FRAME; -- store in the switch buffer
+ end if;
+ else
+ --No, appending CRC and write to the fifo when frame is longer then 80 bytes
+ if byteCnt = 0 then
+ -- check if the last byte was placed in the second half of the double word,
+ -- in that case write the first word to the fifo.
+ writeContentData <= dataLane(0) & dataLane(1) & dataLane(2) & dataLane(3);
+ elsif byteCnt = 1 then
+ crc16Current <= crc16Temp; -- calcylate the crc for the 16 most significant bits
+ elsif byteCnt = 2 then
+ writeContent_o <= '1';
+ writeContentData <= dataLane(0) & dataLane(1) & crc16Current;
+ else
+ stateRB <= SEND_FRAME; -- store in the switch buffer
+ end if;
+ end if;
+
+
+ when SEND_TO_FIFO =>
+ if byteOffset = 0 then -- using byteOffset as a counter
+ byteOffset <= 1;
+ writeContent_o <= '1';
+ writeContentData <= dataLane(0) & dataLane(1) & dataLane(2) & dataLane(3);
+ elsif byteOffset = 1 then -- using byteOffset as a counter
+ byteOffset <= 2;
+ writeContent_o <= '0';
+ crc16Current <= crc16Next; -- calcylate the crc
+ elsif byteOffset = 2 then
+ byteOffset <= 3;
+ writeContent_o <= '1';
+ writeContentData <= dataLane(4) & dataLane(5) & dataLane(6) & dataLane(7);
+ elsif byteOffset = 3 then
+ crc16Current <= crc16Next; -- calcylate the crc
+ writeContent_o <= '0';
+ byteOffset <= 0;
+ stateRB <= nextStateRB;
+ dataLane <= (others =>(others => '0'));
+ end if;
+
+ when READ_FROM_FIFO =>
+ if (endianMsb = '1') then
+ if (readContentEnd_i = '0') then
+ endianMsb <= '0';
+ dataLane(0 to 3) <= (readContentData_i(31 downto 24), readContentData_i(23 downto 16),
+ readContentData_i(15 downto 8), readContentData_i(7 downto 0));
+ else
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteOffset <= 0;
+ readContent_o <= '0';
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= BERR_FRAME_SIZE;
+ stateRB <= SEND_ERROR;
+-- stateRB <= IDLE;
+ end if;
+ else
+ endianMsb <= '1';
+ readContent_o <= '0';
+ dataLane(4 to 7) <= (readContentData_i(31 downto 24), readContentData_i(23 downto 16),
+ readContentData_i(15 downto 8), readContentData_i(7 downto 0));
+ if ready = '1' then
+ stateRB <= nextStateRB;
+ else
+ stateRB <= WRITE_TO_WB;
+ end if;
+ end if;
+
+ when WRITE_TO_WB =>
+ if wbStb = '0' then
+ wbStb <= '1';
+ wbWe_o <= '1';
+ byteCnt <= 1;
+ byteOffset <= byteOffset + 1; -- increase number of counted byte
+ tempAddr <= tempAddr + 1; -- increase the memory sddress address
+ wbAdr_o <= tempAddr;
+ wbData_o <= dataLane(byteOffset);
+ else
+ if wbAck_i = '1' then
+ timeOutCnt <= (others => '0'); -- reset the time out conter
+ if wbErr_i = '0' then -- check the peripherals error signal
+ if byteCnt < numberOfByte then
+ tempAddr <= tempAddr + 1; -- increase the memory sddress address
+ wbAdr_o <= tempAddr;
+ wbData_o <= dataLane(byteOffset);
+ byteCnt <= byteCnt + 1; -- increase number of counted byte
+ if byteOffset < 7 then
+ if (byteCnt + headLen = 79) then -- check for the CRC-byte position 80 in the frame
+ byteOffset <= byteOffset + 3;
+ else
+ byteOffset <= byteOffset + 1;
+ end if;
+ else
+ if (byteCnt + headLen = 79) then -- check for the CRC-byte position 80 in the frame
+ byteOffset <= 2;
+ else
+ byteOffset <= 0;
+ end if;
+ if byteCnt < numberOfByte - 1 then
+ readContent_o <= '1';
+ stateRB <= READ_FROM_FIFO;
+ end if;
+ end if;
+ else -- no more data to send to the peripherals
+ wbStb <= '0';
+ wbWe_o <= '0';
+ ready <= '1';
+ stateRB <= SEND_FRAME;
+ end if;
+ else -- if the peripheral generates an error, send an error Response
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteOffset <= 0;
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= wbData_i;
+ stateRB <= SEND_ERROR;
+ end if;
+ else
+-- if readContentEnd_i = '1' then -- when unvalid data in the switch buffer
+-- wbStb <= '0';
+-- wbWe_o <= '0';
+-- readFrame_o <= '1';
+-- byteOffset <= 0;
+-- writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+-- errorCode <= BERR_FRAME_SIZE; -- more data content is expected, Frame size error
+-- stateRB <= SEND_ERROR;
+-- else
+ if timeOutCnt(13) = '1' then -- when waiting more than 1 ms for response from the device
+ wbStb <= '0';
+ wbWe_o <= '0';
+ readFrame_o <= '1';
+ byteOffset <= 0;
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= BERR_NOT_RESPONSE;
+ stateRB <= SEND_ERROR;
+ else
+ timeOutCnt <= timeOutCnt + 1;
+ end if;
+-- end if;
+ end if;
+ end if;
+
+ when SEND_ERROR => -- Generate a Response Class, an error pakage ftype=13, ttype=8, status="1111"
+ readFrame_o <= '0';
+ writeFrameAbort_o <= '0';
+ byteOffset <= byteOffset + 1;
+ if byteOffset = 0 then
+ writeContent_o <= '1'; -- start write to the buffer
+ crc16Current <= (others => '1');
+ writeContentData <= "00000000" & "00" & "01" & "1101" & sourceId;
+ elsif byteOffset = 1 then
+ writeContentData <= baseDeviceId & "1000" & "1111" & tid;
+ crc16Current <= crc16Next; -- first frame's CRC
+ elsif byteOffset = 2 then
+ writeContentData <= errorCode & x"000000";
+ crc16Current <= crc16Next; -- second frame's CRC
+ elsif byteOffset = 3 then
+ writeContentData <= x"00000000";
+ crc16Current <= crc16Next; -- third frame's CRC
+ elsif byteOffset = 4 then
+ writeContentData <= crc16Next & X"0000"; -- write the CRC field
+ else
+ writeContent_o <= '0';
+ writeFrame_o <= '1';
+ readFrame_o <= '1';
+ stateRB <= WAIT_IDLE;
+ end if;
+
+ when SEND_FRAME =>
+ if (ftype = FTYPE_WRITE_CLASS) and (ttype = TTYPE_NWRITE_TRANSACTION) and (tt = "01") then -- check what type of pakage we got
+ readFrame_o <= '1';
+ elsif (ftype = FTYPE_REQUEST_CLASS) and (ttype = TTYPE_NREAD_TRANSACTION) and (tt = "01") then -- write payload to the buffer is done
+ readFrame_o <= '1';
+ writeFrame_o <= '1';
+ else -- the operation was not valid
+ readFrame_o <= '1';
+ writeFrame_o <= '1';
+ end if;
+ stateRB <= WAIT_IDLE;
+
+ when WAIT_IDLE =>
+ readFrame_o <= '0';
+ writeFrame_o <= '0';
+ readContent_o <= '0'; -- this line is to make sure that the CRC is complete read
+ stateRB <= IDLE;
+
+ when others =>
+ stateRB <= IDLE;
+
+ end case;
+
+ end if;
+
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Configuration memory.
+ -----------------------------------------------------------------------------
+ memoryConfig : process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ configDataRead <= (others => '0');
+ baseDeviceId <= DEFAULT_BASE_DEVICE_ID;
+ componentTag <= (others => '0');
+ hostBaseDeviceIdLocked <= '0';
+ hostBaseDeviceId <= (others => '1');
+ elsif (clk'event and clk = '1') then
+
+ if (configEnable = '1') then
+ case (configAddress) is
+ when x"000000" =>
+ -- Device Identity CAR. Read-only.
+ configDataRead(31 downto 16) <= DEVICE_IDENTITY;
+ configDataRead(15 downto 0) <= DEVICE_VENDOR_IDENTITY;
+ when x"000004" =>
+ -- Device Information CAR. Read-only.
+ configDataRead(31 downto 0) <= DEVICE_REV;
+ when x"000008" =>
+ -- Assembly Identity CAR. Read-only.
+ configDataRead(31 downto 16) <= ASSY_IDENTITY;
+ configDataRead(15 downto 0) <= ASSY_VENDOR_IDENTITY;
+ when x"00000c" =>
+ -- Assembly Informaiton CAR. Read-only.
+ -- Extended features pointer to "0000".
+ configDataRead(31 downto 16) <= ASSY_REV;
+ configDataRead(15 downto 0) <= x"0000";
+ when x"000010" =>
+ -- Processing Element Features CAR. Read-only.
+ -- Bridge(31), Memory(30), Processor(29), Switch(28).
+ configDataRead(31) <= '1';
+ configDataRead(30 downto 4) <= (others => '0');
+ configDataRead(3) <= '1'; -- support 16 bits common transport large system
+ configDataRead(2 downto 0) <= "001"; -- support 34 bits address
+ when x"000018" =>
+ -- Source Operations CAR. Read-only.
+ configDataRead(31 downto 0) <= (others => '0');
+ when x"00001C" =>
+ -- Destination Operations CAR. Read-only.
+ configDataRead(31 downto 16) <= (others => '0');
+ configDataRead(15) <= '1';
+ configDataRead(14) <= '1';
+ configDataRead(13 downto 0) <= (others => '0');
+ when x"00004C" =>
+ -- Processing Element Logical Layer Control CSR.
+ configDataRead(31 downto 3) <= (others => '0');
+ configDataRead(2 downto 0) <= "001"; -- support 34 bits address
+ when x"000060" =>
+ -- Base Device ID CSR.
+ -- Only valid for end point devices.
+ if (configWrite = '1') then
+ baseDeviceId <= configDataWrite(15 downto 0);
+ else
+ configDataRead(15 downto 0) <= baseDeviceId;
+ end if;
+ when x"000068" =>
+ -- Host Base Device ID Lock CSR.
+ if (configWrite = '1') then
+ -- Check if this field has been written before.
+ if (hostBaseDeviceIdLocked = '0') then
+ -- The field has not been written.
+ -- Lock the field and set the host base device id.
+ hostBaseDeviceIdLocked <= '1';
+ hostBaseDeviceId <= configDataWrite(15 downto 0);
+ else
+ -- The field has been written.
+ -- Check if the written data is the same as the stored.
+ if (hostBaseDeviceId = configDataWrite(15 downto 0)) then
+ -- Same as stored, reset the value to its initial value.
+ hostBaseDeviceIdLocked <= '0';
+ hostBaseDeviceId <= (others => '1');
+ else
+ -- Not writing the same as the stored value.
+ -- Ignore the write.
+ end if;
+ end if;
+ else
+ configDataRead(31 downto 16) <= (others => '0');
+ configDataRead(15 downto 0) <= hostBaseDeviceId;
+ end if;
+ when x"00006C" =>
+ -- Component TAG CSR.
+ if (configWrite = '1') then
+ componentTag <= configDataWrite;
+ else
+ configDataRead <= componentTag;
+ end if;
+
+ when others =>
+ configDataRead <= (others => '0');
+ end case;
+ else
+ -- Config memory not enabled.
+ end if;
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- findInPayload
+ -- find out number of the bytes and first byte's position in the payload.
+ -----------------------------------------------------------------------------
+ findInPayload: process(wdptr, size)
+ begin
+ case size is
+ when "0000" =>
+ reserved <= '0';
+ numberOfByte <= 1;
+ if wdptr = '1' then
+ pos <= 4;
+ else
+ pos <= 0;
+ end if;
+ when "0001" =>
+ reserved <= '0';
+ numberOfByte <= 1;
+ if wdptr = '1' then
+ pos <= 5;
+ else
+ pos <= 1;
+ end if;
+ when "0010" =>
+ reserved <= '0';
+ numberOfByte <= 1;
+ if wdptr = '1' then
+ pos <= 6;
+ else
+ pos <= 2;
+ end if;
+ when "0011" =>
+ reserved <= '0';
+ numberOfByte <= 1;
+ if wdptr = '1' then
+ pos <= 7;
+ else
+ pos <= 3;
+ end if;
+ when "0100" =>
+ reserved <= '0';
+ numberOfByte <= 2;
+ if wdptr = '1' then
+ pos <= 4;
+ else
+ pos <= 0;
+ end if;
+ when "0101" =>
+ reserved <= '0';
+ numberOfByte <= 3;
+ if wdptr = '1' then
+ pos <= 5;
+ else
+ pos <= 0;
+ end if;
+ when "0110" =>
+ reserved <= '0';
+ numberOfByte <= 2;
+ if wdptr = '1' then
+ pos <= 6;
+ else
+ pos <= 2;
+ end if;
+ when "0111" =>
+ reserved <= '0';
+ numberOfByte <= 5;
+ if wdptr = '1' then
+ pos <= 3;
+ else
+ pos <= 0;
+ end if;
+ when "1000" =>
+ reserved <= '0';
+ numberOfByte <= 4;
+ if wdptr = '1' then
+ pos <= 4;
+ else
+ pos <= 0;
+ end if;
+ when "1001" =>
+ reserved <= '0';
+ numberOfByte <= 6;
+ if wdptr = '1' then
+ pos <= 2;
+ else
+ pos <= 0;
+ end if;
+ when "1010" =>
+ reserved <= '0';
+ numberOfByte <= 7;
+ if wdptr = '1' then
+ pos <= 1;
+ else
+ pos <= 0;
+ end if;
+ when "1011" =>
+ reserved <= '0';
+ if wdptr = '1' then
+ numberOfByte <= 16;
+ else
+ numberOfByte <= 8;
+ end if;
+ pos <= 0;
+ when "1100" =>
+ reserved <= '0';
+ if wdptr = '1' then
+ numberOfByte <= 64;
+ else
+ numberOfByte <= 32;
+ end if;
+ pos <= 0;
+ when "1101" =>
+ if wdptr = '1' then
+ reserved <= '0';
+ numberOfByte <= 128;
+ else
+ reserved <= '1';
+ numberOfByte <= 96;
+ end if;
+ pos <= 0;
+ when "1110" =>
+ if wdptr = '1' then
+ numberOfByte <= 192;
+ else
+ numberOfByte <= 160;
+ end if;
+ reserved <= '1';
+ pos <= 0;
+ when "1111" =>
+ if wdptr = '1' then
+ reserved <= '0';
+ numberOfByte <= 256;
+ else
+ reserved <= '1';
+ numberOfByte <= 224;
+ end if;
+ pos <= 0;
+ when others =>
+ reserved <= '1';
+ numberOfByte <= 0;
+ pos <= 0;
+ end case;
+ end process;
+
+end architecture;
1.0.1/rtl/vhdl/RioWbBridge.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/sw/stack/riostack.c
===================================================================
--- 1.0.1/sw/stack/riostack.c (nonexistent)
+++ 1.0.1/sw/stack/riostack.c (revision 29)
@@ -0,0 +1,8225 @@
+/*******************************************************************************
+ *
+ * RapidIO IP Library Core
+ *
+ * This file is part of the RapidIO IP library project
+ * http://www.opencores.org/cores/rio/
+ *
+ * Description:
+ * This file contains a software implementation of a RapidIO stack according to
+ * the 2.2 version, part 6, of the standard. Only short control symbols are
+ * supported.
+ *
+ * Symbols are in four flavors, idle, control, data and error. They are abstract
+ * and should be serialized by any implementation to be sent on a transmission
+ * channel. Error symbols are never generated by the stack and are used if the
+ * symbol decoder encounters an error that the stack should be notified of.
+ *
+ * Symbols are inserted into the stack by calling RIO_portAddSymbol() and symbols to
+ * transmit are fetched from the stack using RIO_portGetSymbol(). These two
+ * functions are the low-level interface towards a physical transmission channel.
+ * The function RIO_portSetStatus() is used to indicate to the stack that initial
+ * training of the symbol codec has been completed and that the transmission port
+ * is ready to accept other symbols than idle. The procedure is to set the port
+ * status to initialized once idle symbols are successfully received.
+ *
+ * On the high-level interface are rio_sendXXX() functions used to create and
+ * insert packets into the outbound transmission queue. The RIO_eventPoll()
+ * function is used to check if any packet is available for reading in the
+ * inbound reception queue. These packets are then accessed using
+ * rio_receiveXXX() functions.
+ *
+ * -----------------
+ * | OS dependent |
+ * | (your code) |
+ * -----------------
+ * |
+ * -----------------
+ * | RioStack |
+ * -----------------
+ * |
+ * -----------------
+ * | Symbol Codec |
+ * | (your code) |
+ * -----------------
+ * |
+ * -----------------
+ * | Port driver |
+ * -----------------
+ * |
+ * -----------------
+ * | Physical port |
+ * -----------------
+ *
+ * The symbol codec maps a RapidIO symbol to the physical transmission media.
+ *
+ * Some typical patterns to handle this stack are:
+ * Initialization:
+ * RIO_open(...);
+ * RIO_portSetTimeout(...);
+ * ...
+ *
+ * RIO_portSetStatus(1);
+ *
+ * Bottom-half traffic handling:
+ * RIO_portSetTime(...);
+ *
+ * RIO_portAddSymbol(...);
+ * s = RIO_portGetSymbol(...);
+ *
+ *
+ * Receiving packets:
+ * switch(RIO_eventPoll(...))
+ * {
+ * case RIO_EVENT_DOORBELL:
+ * RIO_receiveDoorbell(...);
+ * ...
+ * }
+ * RIO_packetRemove();
+ *
+ * Transmitting packets:
+ * if(RIO_sendAvailable(...))
+ * {
+ * RIO_sendDoorbell(...);
+ * }
+ * ...
+ *
+ * More details about the usage can be found in the module tests in the end of
+ * this file.
+ *
+ * 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
+ *
+ *******************************************************************************/
+
+/**
+ * \file riostack.c
+ */
+
+/*******************************************************************************
+ * Includes
+ *******************************************************************************/
+
+#include "riostack.h"
+
+
+/*lint -e961 Allow function like macros. */
+/*lint -e621 Long identifier names allowed to increase readability. */
+/*lint -w2 */
+
+
+/* lint --estring(960,17.4) It is not possible to implement a rio stack without some
+ * pointer arithmetic */
+
+/*******************************************************************************
+ * Local macro definitions
+ *******************************************************************************/
+
+/* Macro to update 5-bit ackId counters. */
+#define ACKID_INC(ackId) (((ackId)+1)&0x1f)
+
+/* Macros to get entries from a control symbol. */
+#define STYPE0_GET(data) ((uint8_t) (((data) >> 21) & 0x00000007u))
+#define PARAMETER0_GET(data) ((uint8_t) (((data) >> 16) & 0x00000001fu))
+#define PARAMETER1_GET(data) ((uint8_t) (((data) >> 11) & 0x00000001fu))
+#define STYPE1_GET(data) ((uint8_t) (((data) >> 8) & 0x00000007u))
+#define CMD_GET(data) ((uint8_t) (((data) >> 5) & 0x00000007u))
+#define CRC5_GET(data) ((uint8_t) (((data) >> 0) & 0x0000001fu))
+
+/* Macros to get entries from a packet in a buffer. */
+#define FTYPE_GET(p) (((p)[0] >> 16) & 0xf)
+#define DESTID_GET(p) ((p)[0] & 0xffff)
+#define SRCID_GET(p) (((p)[1] >> 16) & 0xffff)
+#define TRANSACTION_GET(p) (((p)[1] >> 12) & 0xf)
+#define MSGLEN_GET(p) TRANSACTION_GET(p)
+#define SSIZE_GET(p) (((p)[1] >> 8) & 0xf)
+#define LETTER_GET(p) (((p)[1] >> 6) & 0x3)
+#define MBOX_GET(p) (((p)[1] >> 4) & 0x3)
+#define MSGSEG_GET(p) ((p)[1] & 0xf)
+#define XMBOX_GET(p) MSGSEG_GET(p)
+#define RDSIZE_GET(p) SSIZE_GET(p)
+#define WRSIZE_GET(p) SSIZE_GET(p)
+#define TID_GET(p) ((p)[1] & 0xff)
+#define HOP_GET(p) (((p)[2] >> 24) & 0xff)
+#define CONFIG_OFFSET_GET(p) ((p)[2] & 0x00fffffcul)
+#define INFO_GET(p) (((p)[2] >> 16) & 0xffff)
+#define ADDRESS_GET(p) ((p)[2] & 0xfffffff8ul)
+#define WDPTR_GET(p) (((p)[2] >> 2) & 0x1)
+#define XAMBS_GET(p) ((p)[2] & 0x3)
+#define DOUBLE_WORD_MSB_GET(p, i) (p)[3+(2*i+0)]
+#define DOUBLE_WORD_LSB_GET(p, i) (p)[3+(2*i+1)]
+
+/* Transmitter frame states. */
+#define TX_FRAME_START ((uint8_t)0u)
+#define TX_FRAME_BODY ((uint8_t)1u)
+
+/* Control symbol constants. */
+#define STYPE0_PACKET_ACCEPTED ((uint8_t)0x00u)
+#define STYPE0_PACKET_RETRY ((uint8_t)0x01u)
+#define STYPE0_PACKET_NOT_ACCEPTED ((uint8_t)0x02u)
+#define STYPE0_RESERVED ((uint8_t)0x03u)
+#define STYPE0_STATUS ((uint8_t)0x04u)
+#define STYPE0_VC_STATUS ((uint8_t)0x05u)
+#define STYPE0_LINK_RESPONSE ((uint8_t)0x06u)
+#define STYPE0_IMPLEMENTATION_DEFINED ((uint8_t)0x07u)
+#define STYPE1_START_OF_PACKET ((uint8_t)0x00u)
+#define STYPE1_STOMP ((uint8_t)0x01u)
+#define STYPE1_END_OF_PACKET ((uint8_t)0x02u)
+#define STYPE1_RESTART_FROM_RETRY ((uint8_t)0x03u)
+#define STYPE1_LINK_REQUEST ((uint8_t)0x04u)
+#define STYPE1_MULTICAST_EVENT ((uint8_t)0x05u)
+#define STYPE1_RESERVED ((uint8_t)0x06u)
+#define STYPE1_NOP ((uint8_t)0x07u)
+
+/* Packet ftype constants. */
+#define FTYPE_REQUEST 0x2
+#define FTYPE_WRITE 0x5
+#define FTYPE_MAINTENANCE 0x8
+#define FTYPE_DOORBELL 0xa
+#define FTYPE_MESSAGE 0xb
+#define FTYPE_RESPONSE 0xd
+
+/* Transaction constants. */
+#define TRANSACTION_MAINT_READ_REQUEST 0
+#define TRANSACTION_MAINT_WRITE_REQUEST 1
+#define TRANSACTION_MAINT_READ_RESPONSE 2
+#define TRANSACTION_MAINT_WRITE_RESPONSE 3
+#define TRANSACTION_WRITE_NWRITE 4
+#define TRANSACTION_WRITE_NWRITER 5
+#define TRANSACTION_REQUEST_NREAD 4
+#define TRANSACTION_RESPONSE_NO_PAYLOAD 0
+#define TRANSACTION_RESPONSE_MESSAGE_RESPONSE 1
+#define TRANSACTION_RESPONSE_WITH_PAYLOAD 8
+
+/* Maintenance transaction lengths. */
+#define MAINTENANCE_TRANSACTION_READ_REQUEST_SIZE ((uint32_t) 4ul)
+#define MAINTENANCE_TRANSACTION_WRITE_REQUEST_SIZE ((uint32_t) 6ul)
+#define MAINTENANCE_TRANSACTION_READ_RESPONSE_SIZE ((uint32_t) 6ul)
+#define MAINTENANCE_TRANSACTION_WRITE_RESPONSE_SIZE ((uint32_t) 4ul)
+
+/* Constants used to forward different errors to the link partner. */
+#define PACKET_NOT_ACCEPTED_CAUSE_RESERVED 0u
+#define PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID 1u
+#define PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC 2u
+#define PACKET_NOT_ACCEPTED_CAUSE_NON_MAINTENANCE 3u
+#define PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC 4u
+#define PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER 5u
+#define PACKET_NOT_ACCEPTED_CAUSE_NO_RESOURCE 6u
+#define PACKET_NOT_ACCEPTED_CAUSE_DESCRAMBLER 7u
+#define PACKET_NOT_ACCEPTED_CAUSE_GENERAL 31u
+
+/* Constants used to request link-responses. */
+#define LINK_REQUEST_RESET_DEVICE 3u
+#define LINK_REQUEST_INPUT_STATUS 4u
+
+/* Constants used to forward a port status in a link-resonse. */
+#define LINK_RESPONSE_PORT_STATUS_ERROR 2u
+#define LINK_RESPONSE_PORT_STATUS_RETRY_STOPPED 4u
+#define LINK_RESPONSE_PORT_STATUS_ERROR_STOPPED 5u
+#define LINK_RESPONSE_PORT_STATUS_OK 16u
+
+/*******************************************************************************
+ * Local typedefs
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Global declarations
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Local declarations
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes
+ *******************************************************************************/
+
+/* Helper functions for protocol events. */
+static void handleStatus(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus);
+static void handlePacketAccepted(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus);
+static void handlePacketRetry(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus);
+static void handlePacketNotAccepted(RioStack_t *stack, const uint8_t arbitrary, const uint8_t cause);
+static void handleLinkResponse(RioStack_t *stack, const uint8_t ackId, const uint8_t portStatus);
+static void handleStartOfPacket(RioStack_t *stack);
+static void handleEndOfPacket(RioStack_t *stack);
+static void handleLinkRequest(RioStack_t *stack, uint8_t cmd);
+static void handleNewPacketStart(RioStack_t *stack);
+static void handleNewPacketEnd(RioStack_t *stack);
+
+/* I/O logical layer maintenance packet functions. */
+static void sendMaintenanceReadRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t offset);
+static void receiveMaintenanceReadRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *offset);
+static void sendMaintenanceReadResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t data);
+static void receiveMaintenanceReadResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *data);
+static void sendMaintenanceWriteRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t offset, const uint32_t data );
+static void receiveMaintenanceWriteRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *offset, uint32_t *data );
+static void sendMaintenanceWriteResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount);
+static void receiveMaintenanceWriteResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount);
+
+/* I/O logical layer packet functions. */
+static void sendNwrite( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer,
+ const uint8_t ack);
+static uint16_t receiveNwrite( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint32_t *address, const uint16_t dataLength, uint8_t *data );
+static void sendNread( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint32_t address, const uint16_t dataLength);
+static void receiveNread( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint32_t *address, uint16_t *dataLength);
+static void sendResponseDonePayload( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer);
+static uint16_t receiveResponseDonePayload( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ const uint32_t address, const uint16_t dataLength, uint8_t *data );
+static void sendResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t status);
+static void receiveResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid);
+
+/* Message passing logical layer packet functions. */
+static void sendDoorbell( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint16_t info );
+static void receiveDoorbell( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint16_t *info);
+static void sendMessage( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
+ const uint16_t bufferSize, const uint8_t* bufferData);
+static uint16_t receiveMessage( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox,
+ const uint16_t dataLength, uint8_t *data );
+static void sendMessageResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
+ const uint8_t status);
+static void receiveMessageResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox);
+
+/* Functions to help transfer data bytes to and from a packet payload. */
+static uint16_t getPacketPayload(uint32_t *packet, const uint16_t payloadOffset, const uint16_t dataOffset,
+ const uint16_t dataSize, uint8_t *data);
+static uint16_t setPacketPayload(uint32_t *packet, const uint16_t payloadOffset, const uint16_t dataOffset,
+ const uint16_t dataSize, const uint8_t *data);
+
+/* Functions to help in conversions between rdsize/wrsize and size/offset. */
+static uint16_t rdsizeGet(const uint32_t address, const uint16_t size);
+static uint16_t wrsizeGet(const uint32_t address, const uint16_t size);
+static void rdsizeToOffset(uint8_t wrsize, uint8_t wdptr, uint8_t *offset, uint16_t *size);
+static void wrsizeToOffset(uint8_t wrsize, uint8_t wdptr, uint8_t *offset, uint16_t *size);
+
+/**
+ * \brief Create a control symbol.
+ *
+ * \param[in] stype0 The stype0 value.
+ * \param[in] parameter0 The parameter0 value.
+ * \param[in] parameter1 The parameter1 value.
+ * \param[in] stype1 The stype1 value.
+ * \param[in] cmd The cmd value.
+ * \param[out] None
+ * \return The control symbol that were created from the input parameters.
+ *
+ * This function creates a control symbol with the specified arguments and
+ * calculates a CRC-5 checksum according to the standard specification.
+ */
+static RioSymbol CreateControlSymbol( const uint8_t stype0,
+ const uint8_t parameter0, const uint8_t parameter1,
+ const uint8_t stype1, const uint8_t cmd);
+
+/**
+ * \brief Function to calculate ITU-CRC5, polynom=0x15.
+ *
+ * \param[in] data The data of a control symbol.
+ * \param[in] crc The crc to initiate the result with.
+ * \return A new CRC-5 value.
+ */
+static uint8_t Crc5( const uint32_t data, const uint8_t crc);
+
+/**
+ * \brief Function to calculate CITT-CRC16, polynom=0x1021.
+ *
+ * \param[in] data The data to calculate CRC-16 on.
+ * \param[in] crc The crc to initiate the result with.
+ * \param[out] None
+ * \return A new CRC-16 value.
+ *
+ * This function calculates and returns a new CRC-16 value based on
+ * new data and a previous CRC-16 value.
+ */
+static uint16_t Crc16( const uint16_t data, const uint16_t crc);
+
+/**
+ * \brief Function to calculate CITT-CRC16, polynom=0x1021.
+ *
+ * \param[in] data The data to calculate CRC-16 on.
+ * \param[in] crc The crc to initiate the result with.
+ * \param[out] None
+ * \return A new CRC-16 value.
+ *
+ * This function calculates and returns a new CRC-16 value based on
+ * new data and a previous CRC-16 value.
+ */
+static uint16_t Crc32( const uint32_t data, uint16_t crc);
+
+/**
+ * \brief Create a queue with a specified size and a buffer attached to it.
+ *
+ * \param[in] The number of entries in the queue.
+ * \param[in] A pointer to the buffer to store the content in.
+ * \return A queue with the specified size and where new data will be stored
+ * to the specified buffer.
+ */
+static Queue_t QueueCreate( const uint8_t size, uint32_t *buffer);
+
+/**
+ * \brief Get number of available elements.
+ *
+ * \param[in] q The queue to operate on.
+ * \return The number of free packet buffers in the queue.
+ */
+static uint8_t QueueAvailable( const Queue_t q );
+
+/**
+ * \brief Get if the queue is empty or not.
+ *
+ * \param[in] q The queue to operate on.
+ * \return Non-zero if the queue is empty.
+ */
+static bool_t QueueEmpty( const Queue_t q);
+
+/**
+ * \brief Get the length of a queue.
+ *
+ * \param[in] q The queue to operate on.
+ * \return The number of elements in the queue.
+ */
+static uint8_t QueueLength( const Queue_t q);
+
+/**
+ * \brief Add a new element to the queue.
+ *
+ * \param[in] q The queue to operate on.
+ * \return A queue with one added element.
+ */
+static Queue_t QueueEnqueue( Queue_t q);
+
+/**
+ * \brief Remove an element from the queue.
+ *
+ * \param[in] q The queue to operate on.
+ * \return A queue with on removed element.
+ */
+static Queue_t QueueDequeue( Queue_t q);
+
+/**
+ * \brief Check if the readout window is empty.
+ *
+ * \param[in] q The queue to operate on.
+ * \return If the readout window is empty.
+ */
+static bool_t QueueWindowEmpty( const Queue_t q);
+
+/**
+ * \brief Reset the window to none.
+ *
+ * \param[in] q The queue to operate on.
+ * \return The updated Queue_t structure.
+ */
+static Queue_t QueueWindowReset(Queue_t q);
+
+/**
+ * \brief Increase the window to the next pending element.
+ *
+ * \param[in] q The queue to operate on.
+ * \return The updated Queue_t structure.
+ */
+static Queue_t QueueWindowNext(Queue_t q);
+
+/**
+ * \brief Set actual size of the newest element.
+ *
+ * \param[in] q The queue to operate on.
+ * \param[in] size The size to set the newest content size to.
+ */
+static void QueueSetSize( Queue_t q, const uint32_t size);
+
+/**
+ * \brief Set content at a specified index in the newest element.
+ *
+ * \param[in] q The queue to operate on.
+ * \param[in] index posititon into the element
+ * \param[in] content The content to set at the specified index in the newest queue element.
+ */
+static void QueueSetContent( Queue_t q, const uint32_t index, const uint32_t content);
+
+/**
+ * \brief Get the size of the newest element.
+ *
+ * \param[in] q The queue to operate on.
+ * \return The size of the currently pending element.
+ */
+static uint32_t QueueGetBackSize( Queue_t q);
+
+/**
+ * \brief Get a pointer to the buffer of the newest element.
+ *
+ * \param[in] q The queue to operate on.
+ * \return A pointer to the content.
+ */
+static uint32_t *QueueGetBackBuffer( Queue_t q );
+
+/**
+ * \brief Get the size of the oldest element.
+ * \param[in] q The queue to operate on.
+ * \return The size of the element.
+ */
+static uint32_t QueueGetFrontSize( Queue_t q );
+
+/**
+ * \brief Get the content of the oldest element at specified index.
+ * \param[in] q The queue to operate on.
+ * \param[in] index The index into the element to get the content from.
+ * \return content of element at index position.
+ */
+static uint32_t QueueGetFrontContent( Queue_t q, const uint32_t index);
+
+/**
+ * \brief Get a pointer to the buffer of the oldest element.
+ *
+ * \param[in] q The queue to operate on.
+ * \return A pointer to the content.
+ */
+static uint32_t *QueueGetFrontBuffer( Queue_t q );
+
+
+
+/*******************************************************************************
+ * Global functions
+ *******************************************************************************/
+
+
+void RIO_open( RioStack_t *stack, const RioStackObserver_t *observer, const void *private,
+ const uint32_t rxPacketBufferSize, uint32_t *rxPacketBuffer,
+ const uint32_t txPacketBufferSize, uint32_t *txPacketBuffer,
+ const uint16_t configDeviceVendorId, const uint16_t configDeviceId, const uint32_t configDeviceRevisionId,
+ const uint16_t configAssyVendorId, const uint16_t configAssyId, const uint16_t configAssyRevisionId,
+ const uint16_t configBaseDeviceId )
+{
+ /* Port time and timeout limit. */
+ stack->portTime = 0u;
+ stack->portTimeout = 1000u;
+
+ /* Setup the receiver. */
+ stack->rxState = RX_STATE_UNINITIALIZED;
+ stack->rxCounter = 0u;
+ stack->rxCrc = 0xffffu;
+ stack->rxStatusReceived = 0u;
+ stack->rxAckId = 0u;
+ stack->rxAckIdAcked = 0u;
+ stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_RESERVED;
+ stack->rxQueue = QueueCreate((uint8_t) (rxPacketBufferSize/RIO_BUFFER_SIZE), rxPacketBuffer);
+
+ /* Setup the transmitter. */
+ stack->txState = TX_STATE_UNINITIALIZED;
+ stack->txCounter = 0u;
+ stack->txStatusCounter = 0u;
+ stack->txFrameState = TX_FRAME_START;
+ stack->txAckId = 0u;
+ stack->txAckIdWindow = 0u;
+ stack->txQueue = QueueCreate((uint8_t) (txPacketBufferSize/RIO_BUFFER_SIZE), txPacketBuffer);
+
+ /* Set our own device address to use in the packets. */
+ stack->deviceIdentity = configDeviceId;
+ stack->deviceVendorIdentity = configDeviceVendorId;
+ stack->deviceRev = configDeviceRevisionId;
+ stack->assyIdentity = configAssyId;
+ stack->assyVendorIdentity = configAssyVendorId;
+ stack->assyRev = configAssyRevisionId;
+ stack->baseDeviceId = configBaseDeviceId;
+
+ /* Initialize the host base lock CSR. */
+ stack->hostBaseDeviceIdLock = 0xfffffffful;
+ stack->componentTag = 0ul;
+
+ /* Bits that are updated by the configuration procedure. */
+ stack->host = 0u;
+ stack->masterEnable = 0u;
+ stack->discovered = 0u;
+
+ /* Setup status counters for inbound direction. */
+ stack->statusInboundPacketComplete = 0ul;
+ stack->statusInboundPacketRetry = 0ul;
+ stack->statusInboundErrorControlCrc = 0ul;
+ stack->statusInboundErrorPacketAckId = 0ul;
+ stack->statusInboundErrorPacketCrc = 0ul;
+ stack->statusInboundErrorIllegalCharacter = 0ul;
+ stack->statusInboundErrorGeneral = 0ul;
+ stack->statusInboundErrorPacketUnsupported = 0ul;
+
+ /* Setup status counters for outbound direction. */
+ stack->statusOutboundPacketComplete = 0ul;
+ stack->statusOutboundPacketRetry = 0ul;
+ stack->statusOutboundErrorTimeout = 0ul;
+ stack->statusOutboundErrorPacketAccepted = 0ul;
+ stack->statusOutboundErrorPacketRetry = 0ul;
+
+ /* Setup status counters for potential problems on the link-partner. */
+ stack->statusPartnerLinkRequest = 0ul;
+ stack->statusPartnerErrorControlCrc = 0ul;
+ stack->statusPartnerErrorPacketAckId = 0ul;
+ stack->statusPartnerErrorPacketCrc = 0ul;
+ stack->statusPartnerErrorIllegalCharacter = 0ul;
+ stack->statusPartnerErrorGeneral = 0ul;
+
+ /* Set callback structure. */
+ stack->observer = observer;
+
+ /* Set pointer to user private data. */
+ stack->private = private;
+}
+
+
+/*******************************************************************************************
+ * Stack status functions.
+ * Note that status counters are access directly in the stack-structure.
+ *******************************************************************************************/
+
+RioStatusType RIO_getStatus( RioStack_t *stack )
+{
+ RioStatusType status;
+
+
+ /* Check if both receiver and transmitter is up and running. */
+ if((stack->rxState == RX_STATE_LINK_INITIALIZED) &&
+ (stack->txState == TX_STATE_LINK_INITIALIZED))
+ {
+ /* Both receiver and transmitter is up. */
+
+ /* Check if it is allowed to act as a master on the bus. */
+ if(stack->masterEnable)
+ {
+ /* Allowed to act as master. */
+ status = RIO_STATUS_OPERATIONAL;
+ }
+ else
+ {
+ /* Not allowed to act as master. */
+ /* The enumeration process has not been completed yet. */
+ status = RIO_STATUS_ENUMERATION;
+ }
+ }
+ else
+ {
+ /* The link is not up yet. */
+ status = RIO_STATUS_UNINITIALIZED;
+ }
+
+ return status;
+}
+
+
+uint8_t RIO_outboundQueueLength( RioStack_t *stack )
+{
+ return QueueLength(stack->txQueue);
+}
+
+
+uint8_t RIO_inboundQueueLength( RioStack_t *stack )
+{
+ return QueueLength(stack->rxQueue);
+}
+
+
+/*******************************************************************************************
+ * Packet reception functions.
+ *******************************************************************************************/
+
+RioEventType RIO_eventPoll( RioStack_t *stack )
+{
+ RioEventType event;
+ uint32_t *packet;
+ uint32_t ftype;
+ uint32_t transaction;
+
+
+ /* Check if there are any new packets in the inbound queue. */
+ if(!QueueEmpty(stack->rxQueue))
+ {
+ /* There are new pending packets. */
+
+ /* Get the packet and its ftype. */
+ packet = QueueGetFrontBuffer(stack->rxQueue);
+ ftype = FTYPE_GET(packet);
+ transaction = TRANSACTION_GET(packet);
+
+ /* Check the type of packets, i.e. read the ftype. */
+ switch(ftype)
+ {
+ case FTYPE_REQUEST:
+ /* Request class. */
+
+ /* Check transaction type. */
+ switch(transaction)
+ {
+ case TRANSACTION_REQUEST_NREAD:
+ /* Supported NREAD request. */
+ event = RIO_EVENT_NREAD;
+ break;
+
+ default:
+ /* Unsupported request transaction. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ break;
+ }
+ break;
+
+ case FTYPE_WRITE:
+ /* Write class. */
+
+ /* Check transaction type. */
+ switch(transaction)
+ {
+ case TRANSACTION_WRITE_NWRITE:
+ /* NWRITE transaction. */
+ if(QueueGetFrontSize(stack->rxQueue) >= 6ul)
+ {
+ /* Supported NWRITE request. */
+ event = RIO_EVENT_NWRITE;
+ }
+ else
+ {
+ /* Unsupported size. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ }
+ break;
+
+ case TRANSACTION_WRITE_NWRITER:
+ /* NWRITE_R transaction. */
+ if(QueueGetFrontSize(stack->rxQueue) >= 6ul)
+ {
+ /* Supported NWRITE_R request. */
+ event = RIO_EVENT_NWRITE_R;
+ }
+ else
+ {
+ /* Unsupported size. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ }
+ break;
+
+ default:
+ /* Unsupported write transaction. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ break;
+ }
+ break;
+
+ case FTYPE_MAINTENANCE:
+ /* Maintenance class. */
+
+ /* Check transaction type. */
+ /* Normally, only responses could be received here unless the stack is compiled as transparent.
+ Maintenance requests are answered by the portAddSymbol() function. */
+ switch(transaction)
+ {
+ case TRANSACTION_MAINT_READ_REQUEST:
+ /* Maintenance read request transaction. */
+ if(QueueGetFrontSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_READ_REQUEST_SIZE)
+ {
+ /* Supported maintenance read response. */
+ event = RIO_EVENT_MAINT_READ_REQUEST;
+ }
+ else
+ {
+ /* Unsupported maintenance read request. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ }
+ break;
+
+ case TRANSACTION_MAINT_WRITE_REQUEST:
+ /* Maintenance write request transaction. */
+ if(QueueGetFrontSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_WRITE_REQUEST_SIZE)
+ {
+ /* Supported maintenance write request. */
+ event = RIO_EVENT_MAINT_WRITE_REQUEST;
+ }
+ else
+ {
+ /* Unsupported maintenance write response. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ }
+ break;
+
+ case TRANSACTION_MAINT_READ_RESPONSE:
+ /* Maintenance read response transaction. */
+ if(QueueGetFrontSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_READ_RESPONSE_SIZE)
+ {
+ /* Supported maintenance read response. */
+ event = RIO_EVENT_MAINT_READ_RESPONSE;
+ }
+ else
+ {
+ /* Unsupported maintenance read response. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ }
+ break;
+
+ case TRANSACTION_MAINT_WRITE_RESPONSE:
+ /* Maintenance write response transaction. */
+ if(QueueGetFrontSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_WRITE_RESPONSE_SIZE)
+ {
+ /* Supported maintenance write response. */
+ event = RIO_EVENT_MAINT_WRITE_RESPONSE;
+ }
+ else
+ {
+ /* Unsupported maintenance write response. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ }
+ break;
+
+ default:
+ /* Unsupported maintenance transaction. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ break;
+ }
+ break;
+
+ case FTYPE_DOORBELL:
+ /* Doorbell class. */
+
+ /* Check size of message. */
+ if(QueueGetFrontSize(stack->rxQueue) == 3ul)
+ {
+ /* Supported doorbell. */
+ event = RIO_EVENT_DOORBELL;
+ }
+ else
+ {
+ /* Unsupported doorbell request. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ }
+ break;
+
+ case FTYPE_MESSAGE:
+ /* Message class. */
+
+ /* Check msglen to see if this packet continues. */
+ if(MSGLEN_GET(packet) == 0ul)
+ {
+ /* Single-packet message. */
+ event = RIO_EVENT_MESSAGE;
+ }
+ else
+ {
+ /* Unsupported message type. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ }
+ break;
+
+ case FTYPE_RESPONSE:
+ /* Response class. */
+
+ /* Check transaction field. */
+ switch(transaction)
+ {
+ case TRANSACTION_RESPONSE_NO_PAYLOAD:
+ /* Response transaction without payload. */
+
+ /* Check status field. */
+ switch(QueueGetFrontContent(stack->rxQueue, 1ul) & 0x00000f00ul)
+ {
+ case 0x00000000:
+ event = RIO_EVENT_RESPONSE_DONE;
+ break;
+ case 0x00000300:
+ event = RIO_EVENT_RESPONSE_RETRY;
+ break;
+ case 0x00000700:
+ event = RIO_EVENT_RESPONSE_ERROR;
+ break;
+ default:
+ /* Unsupported response status. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ break;
+ }
+ break;
+
+ case TRANSACTION_RESPONSE_MESSAGE_RESPONSE:
+ /* Message response transaction. */
+
+ /* Check status field. */
+ switch(QueueGetFrontContent(stack->rxQueue, 1ul) & 0x00000f00ul)
+ {
+ case 0x00000000:
+ event = RIO_EVENT_MESSAGE_RESPONSE_DONE;
+ break;
+ case 0x00000300:
+ event = RIO_EVENT_MESSAGE_RESPONSE_RETRY;
+ break;
+ case 0x00000700:
+ event = RIO_EVENT_MESSAGE_RESPONSE_ERROR;
+ break;
+ default:
+ /* Unsupported message response status. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ break;
+ }
+ break;
+
+ case TRANSACTION_RESPONSE_WITH_PAYLOAD:
+ /* Response with payload transaction. */
+
+ /* Check status field. */
+ switch(QueueGetFrontContent(stack->rxQueue, 1ul) & 0x00000f00ul)
+ {
+ case 0x00000000:
+ event = RIO_EVENT_RESPONSE_DONE_PAYLOAD;
+ break;
+ case 0x00000300:
+ event = RIO_EVENT_RESPONSE_RETRY;
+ break;
+ case 0x00000700:
+ event = RIO_EVENT_RESPONSE_ERROR;
+ break;
+ default:
+ /* Unsupported response with payload status. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ break;
+ }
+ break;
+
+ default:
+ /* Unsupported response transaction. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ break;
+ }
+ break;
+
+ default:
+ /* Unsupported class. */
+ /* REMARK: Throw these away for now. */
+ stack->statusInboundErrorPacketUnsupported++;
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+ event = RIO_EVENT_NONE;
+ break;
+ }
+ }
+ else
+ {
+ /* No pending events available. */
+ event = RIO_EVENT_NONE;
+ }
+
+ return event;
+}
+
+
+void RIO_packetRemove( RioStack_t *stack )
+{
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+}
+
+
+bool_t RIO_sendAvailable( RioStack_t *stack, const uint16_t size )
+{
+ /* Return if there are buffers available and if the requested size is less
+ than or equal to the maximum payload that fits into one packet. */
+ return (bool_t) (stack->masterEnable && (size <= 256u) && (QueueAvailable(stack->txQueue) > 0u));
+}
+
+
+uint32_t RIO_packetGet( RioStack_t *stack, uint32_t length, uint32_t *dest)
+{
+ uint32_t i;
+ uint32_t size;
+ uint32_t *src;
+
+
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ /* Get the size and a pointer to the raw packet. */
+ size = QueueGetFrontSize(stack->rxQueue);
+ src = QueueGetFrontBuffer(stack->rxQueue);
+
+ ASSERT((length >= size), "Too short destination packet.");
+
+ /* Copy the packet to the destination packet pointer. */
+ for(i = 0; i < size; i++)
+ {
+ dest[i] = src[i];
+ }
+
+ /* Remove the packet from the queue. */
+ stack->rxQueue = QueueDequeue(stack->rxQueue);
+
+ /* Return the size of the copied packet. */
+ return size;
+}
+
+
+void RIO_packetSet( RioStack_t *stack, uint32_t length, uint32_t *src)
+{
+ uint32_t i;
+ uint32_t *dest;
+
+
+ ASSERT((QueueAvailable(stack->txQueue) > 0), "Writing to full transmission queue.");
+ ASSERT((length < RIO_PACKET_SIZE), "Writing a too large packet.");
+
+ /* Set the size of the new packet. */
+ QueueSetSize(stack->txQueue, length);
+
+ /* Get a pointer to the destination packet in the transmission queue. */
+ dest = QueueGetBackBuffer(stack->txQueue);
+
+ /* Copy the packet into the transmission queue. */
+ for(i = 0; i < length; i++)
+ {
+ dest[i] = src[i];
+ }
+
+ /* Make sure the ackId field of the copied packet is reset. */
+ /* Unless this is done, the ackId field of the transmitted packet may be corrupted. */
+ dest[0] &= 0x03ffffff;
+
+ /* Enqueue the new packet. */
+ stack->txQueue = QueueEnqueue(stack->txQueue);
+}
+
+/*******************************************************************************************
+ * Configuration-space access methods.
+ *******************************************************************************************/
+
+uint32_t RIO_readConfig( RioStack_t *stack, const uint32_t offset )
+{
+ uint32_t data;
+
+ /* Check the area of the access. */
+ if(offset < 0x10000ul)
+ {
+ /* Access is in not in implementation-defined space. */
+
+ /* Check offset and return. */
+ switch(offset)
+ {
+ case DEVICE_IDENTITY_CAR:
+ data = (uint32_t)stack->deviceIdentity << 16;
+ data |= stack->deviceVendorIdentity;
+ break;
+ case DEVICE_INFORMATION_CAR:
+ data = stack->deviceRev;
+ break;
+ case ASSEMBLY_IDENTITY_CAR:
+ data = (uint32_t)stack->assyIdentity << 16;
+ data |= stack->assyVendorIdentity;
+ break;
+ case ASSEMBLY_INFORMATION_CAR:
+ data = (uint32_t)stack->assyRev << 16;
+ data |= EXTENDED_FEATURES_OFFSET;
+ break;
+ case PROCESSING_ELEMENT_FEATURES_CAR:
+ /* Indicate processor with extended features
+ and 34-bit address support. */
+ /* Supports common transport large systems. */
+ data = 0x20000019ul;
+ break;
+ case SOURCE_OPERATIONS_CAR:
+ /* Supporting doorbells and data messages. */
+ data = 0x00000c00ul;
+ break;
+ case DESTINATION_OPERATIONS_CAR:
+ /* Supporting doorbells and data messages. */
+ data = 0x00000c00ul;
+ break;
+ case PROCESSING_ELEMENT_LOGICAL_LAYER_CONTROL_CSR:
+ /* Supports 34-bit addresses. */
+ data = 0x00000001ul;
+ break;
+ case BASE_DEVICE_ID_CSR:
+ data = stack->baseDeviceId;
+ break;
+ case HOST_BASE_DEVICE_ID_LOCK_CSR:
+ data = stack->hostBaseDeviceIdLock & (uint32_t)0x0000fffful;
+ break;
+ case COMPONENT_TAG_CSR:
+ data = stack->componentTag;
+ break;
+ case LP_SERIAL_REGISTER_BLOCK_HEADER(EXTENDED_FEATURES_OFFSET):
+ /* Indicate Generic end point device and no more extended features. */
+ data = 0x00000001ul;
+ break;
+ case PORT_LINK_TIMEOUT_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
+ /* REMARK: Implement this... */
+ data = 0x00000000ul;
+ break;
+ case PORT_RESPONSE_TIMEOUT_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
+ /* REMARK: Implement this... */
+ data = 0x00000000ul;
+ break;
+ case PORT_GENERAL_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
+ /* Return the host, master enable bit and the discovered bit. */
+ data = ((uint32_t) stack->host) << 31;
+ data |= ((uint32_t) stack->masterEnable) << 30;
+ data |= ((uint32_t) stack->discovered) << 29;
+ break;
+ case PORT_N_LOCAL_ACKID_CSR(EXTENDED_FEATURES_OFFSET, 0u):
+ data = ((uint32_t) stack->rxAckId) << 24;
+ data |= ((uint32_t) stack->txAckId) << 8;
+ data |= ((uint32_t) stack->txAckIdWindow);
+ break;
+ case PORT_N_ERROR_AND_STATUS_CSR(EXTENDED_FEATURES_OFFSET, 0u):
+ /* Indicate the port status here. */
+ if((stack->txState == TX_STATE_LINK_INITIALIZED) &&
+ (stack->rxState == RX_STATE_LINK_INITIALIZED))
+ {
+ /* Port ok. */
+ data = 0x00000002ul;
+ }
+ else
+ {
+ /* Port not ok. */
+ data = 0x00000001ul;
+ }
+ break;
+ default:
+ data = 0x00000000ul;
+ break;
+ }
+ }
+ else
+ {
+ /* Access is in implementation-defined space. */
+
+ /* Check if there are any registered callback. */
+ if((stack->observer != NULL) &&
+ (stack->observer->configRead != NULL))
+ {
+ /* Call the observer callback to handle the access. */
+ data = stack->observer->configRead(stack, offset - 0x00010000ul);
+ }
+ else
+ {
+ data = 0x00000000ul;
+ }
+ }
+
+ return data;
+}
+
+
+void RIO_writeConfig( RioStack_t *stack, const uint32_t offset, const uint32_t data)
+{
+ /* Check the area of the access. */
+ if(offset < 0x00010000ul)
+ {
+ /* Access is not in implementation-defined space. */
+
+ /* Check offset and execute request. */
+ switch(offset)
+ {
+ case BASE_DEVICE_ID_CSR:
+ stack->baseDeviceId = (uint16_t) data;
+ break;
+ case HOST_BASE_DEVICE_ID_LOCK_CSR:
+ if (stack->hostBaseDeviceIdLock == 0xfffffffful)
+ {
+ stack->hostBaseDeviceIdLock = (uint16_t)data;
+ }
+ else
+ {
+ if ((stack->hostBaseDeviceIdLock & (uint32_t)0x0000fffful) ==
+ (data & (uint32_t)0x0000fffful))
+ {
+ stack->hostBaseDeviceIdLock = 0xfffffffful;
+ }
+ else
+ {
+ /* Ignore the write. */
+ }
+ }
+ break;
+ case COMPONENT_TAG_CSR:
+ stack->componentTag = data;
+ break;
+ case PORT_LINK_TIMEOUT_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
+ /* REMARK: Implement this... */
+ break;
+ case PORT_RESPONSE_TIMEOUT_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
+ /* REMARK: Implement this... */
+ break;
+ case PORT_GENERAL_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
+ /* Return host, master enable bit and discovered bit. */
+ stack->host = (uint8_t)(data >> 31) & 1u;
+ stack->masterEnable = (uint8_t)(data >> 30) & 1u;
+ stack->discovered = (uint8_t)(data >> 29) & 1u;
+ break;
+ case PORT_N_LOCAL_ACKID_CSR(EXTENDED_FEATURES_OFFSET, 0u):
+ if(data & 0x80000000)
+ {
+ while(!QueueEmpty(stack->txQueue))
+ {
+ stack->txQueue = QueueDequeue(stack->txQueue);
+ }
+ }
+ stack->rxAckId = (uint8_t) ((data >> 24) & 0x1f);
+ stack->txAckId = (uint8_t) ((data >> 8) & 0x1f);
+ stack->txAckIdWindow = (uint8_t) (data & 0x1f);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ /* Access is in implementation-defined space. */
+
+ /* Check if there are any registered callback. */
+ if((stack->observer != NULL) &&
+ (stack->observer->configWrite != NULL))
+ {
+ /* Call the observer callback to handle the access. */
+ stack->observer->configWrite(stack, offset - 0x00010000ul, data);
+ }
+ else
+ {
+ /* Dont do anything. */
+ }
+ }
+}
+
+
+/*******************************************************************************************
+ * Logical I/O MAINTENANCE-READ functions.
+ *******************************************************************************************/
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendMaintenanceReadRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t offset)
+{
+ sendMaintenanceReadRequest(stack, destid, srcid, tid, hopCount, offset);
+}
+#else
+void RIO_sendMaintenanceReadRequest( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t offset)
+{
+ sendMaintenanceReadRequest(stack, destid, stack->baseDeviceId, tid, hopCount, offset);
+}
+#endif
+
+#ifdef RIO_TRANSPARENT
+void RIO_receiveMaintenanceReadRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *offset)
+{
+ receiveMaintenanceReadRequest( stack, destid, srcid, tid, hopCount, offset);
+}
+#else
+void RIO_receiveMaintenanceReadRequest( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *offset)
+{
+ receiveMaintenanceReadRequest( stack, srcid, srcid, tid, hopCount, offset);
+}
+#endif
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendMaintenanceReadResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t data)
+{
+ sendMaintenanceReadResponse(stack, destid, srcid, tid, hopCount, data);
+}
+#else
+void RIO_sendMaintenanceReadResponse( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t data)
+{
+ sendMaintenanceReadResponse(stack, destid, stack->baseDeviceId, tid, hopCount, data);
+}
+#endif
+
+#ifdef RIO_TRANSPARENT
+void RIO_receiveMaintenanceReadResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *data)
+{
+ receiveMaintenanceReadResponse(stack, destid, srcid, tid, hopCount, data);
+}
+#else
+void RIO_receiveMaintenanceReadResponse( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *data)
+{
+ receiveMaintenanceReadResponse(stack, srcid, srcid, tid, hopCount, data);
+}
+#endif
+
+/*******************************************************************************************
+ * Logical I/O MAINTENANCE-WRITE functions.
+ *******************************************************************************************/
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendMaintenanceWriteRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t offset, const uint32_t data )
+{
+ sendMaintenanceWriteRequest(stack, destid, srcid, tid, hopCount, offset, data);
+}
+#else
+void RIO_sendMaintenanceWriteRequest( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t offset, const uint32_t data )
+{
+ sendMaintenanceWriteRequest(stack, destid, stack->baseDeviceId, tid, hopCount, offset, data);
+}
+#endif
+
+#ifdef RIO_TRANSPARENT
+void RIO_receiveMaintenanceWriteRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *offset, uint32_t *data )
+{
+ receiveMaintenanceWriteRequest(stack, destid, srcid, tid, hopCount, offset, data);
+}
+#else
+void RIO_receiveMaintenanceWriteRequest( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *offset, uint32_t *data )
+{
+ receiveMaintenanceWriteRequest(stack, srcid, srcid, tid, hopCount, offset, data);
+}
+#endif
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendMaintenanceWriteResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount)
+{
+ sendMaintenanceWriteResponse(stack, destid, srcid, tid, hopCount);
+}
+#else
+void RIO_sendMaintenanceWriteResponse( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint8_t hopCount)
+{
+ sendMaintenanceWriteResponse(stack, destid, stack->baseDeviceId, tid, hopCount);
+}
+#endif
+
+#ifdef RIO_TRANSPARENT
+void RIO_receiveMaintenanceWriteResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount)
+{
+ receiveMaintenanceWriteResponse(stack, destid, srcid, tid, hopCount);
+}
+#else
+void RIO_receiveMaintenanceWriteResponse( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount)
+{
+ receiveMaintenanceWriteResponse(stack, srcid, srcid, tid, hopCount);
+}
+#endif
+
+/*******************************************************************************************
+ * Logical I/O NWRITE/NWRITER functions.
+ *******************************************************************************************/
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendNwrite( RioStack_t *stack, const uint16_t destid, const uint16_t srcid,
+ const uint32_t address, const uint16_t size, const uint8_t *data)
+{
+ sendNwrite(stack, destid, srcid, 0, address, size, data, 0u);
+}
+#else
+void RIO_sendNwrite( RioStack_t *stack, const uint16_t destid,
+ const uint32_t address, const uint16_t size, const uint8_t *data)
+{
+ sendNwrite(stack, destid, stack->baseDeviceId, 0, address, size, data, 0u);
+}
+#endif
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendNwriteR( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint32_t address, const uint16_t size, const uint8_t *data)
+{
+ sendNwrite(stack, destid, srcid, tid, address, size, data, 1u);
+}
+#else
+void RIO_sendNwriteR( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint32_t address, const uint16_t size, const uint8_t *data)
+{
+ sendNwrite(stack, destid, stack->baseDeviceId, tid, address, size, data, 1u);
+}
+#endif
+
+#ifdef RIO_TRANSPARENT
+uint16_t RIO_receiveNwrite( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint32_t *address, const uint16_t dataLength, uint8_t *data )
+{
+ return receiveNwrite(stack, destid, srcid, tid, address, dataLength, data);
+}
+#else
+uint16_t RIO_receiveNwrite( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ uint32_t *address, const uint16_t dataLength, uint8_t *data )
+{
+ return receiveNwrite(stack, srcid, srcid, tid, address, dataLength, data);
+}
+#endif
+
+/*******************************************************************************************
+ * Logical I/O NREAD functions.
+ *******************************************************************************************/
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendNread( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint32_t address, const uint16_t dataLength)
+{
+ sendNread(stack, destid, srcid, tid, address, dataLength);
+}
+#else
+void RIO_sendNread( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint32_t address, const uint16_t dataLength)
+{
+ sendNread(stack, destid, stack->baseDeviceId, tid, address, dataLength);
+}
+#endif
+
+#ifdef RIO_TRANSPARENT
+void RIO_receiveNread( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint32_t *address, uint16_t *dataLength)
+{
+ receiveNread( stack, destid, srcid, tid, address, dataLength);
+}
+#else
+void RIO_receiveNread( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ uint32_t *address, uint16_t *dataLength)
+{
+ receiveNread( stack, srcid, srcid, tid, address, dataLength);
+}
+#endif
+
+/*******************************************************************************************
+ * Logical I/O RESPONSE-DONE-PAYLOAD, RESPONSE-DONE, RESPONSE-RETRY and RESPONSE-ERROR
+ * functions.
+ *******************************************************************************************/
+
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendResponseDonePayload( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer)
+{
+ sendResponseDonePayload(stack, destid, srcid, tid, address, bufferSize, buffer);
+}
+#else
+void RIO_sendResponseDonePayload( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer)
+{
+ sendResponseDonePayload(stack, destid, stack->baseDeviceId, tid, address, bufferSize, buffer);
+}
+#endif
+
+#ifdef RIO_TRANSPARENT
+uint16_t RIO_receiveResponseDonePayload( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ const uint32_t address, const uint16_t dataLength, uint8_t *data )
+{
+ return receiveResponseDonePayload(stack, destid, srcid, tid, address, dataLength, data);
+}
+#else
+uint16_t RIO_receiveResponseDonePayload( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ const uint32_t address, const uint16_t dataLength, uint8_t *data )
+{
+ return receiveResponseDonePayload(stack, srcid, srcid, tid, address, dataLength, data);
+}
+#endif
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendResponseDone( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid)
+{
+ sendResponse(stack, destid, srcid, tid, 0x0u);
+}
+#else
+void RIO_sendResponseDone( RioStack_t *stack, const uint16_t destid, const uint8_t tid)
+{
+ sendResponse(stack, destid, stack->baseDeviceId, tid, 0x0u);
+}
+#endif
+
+
+#ifdef RIO_TRANSPARENT
+void RIO_receiveResponseDone( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid)
+{
+ receiveResponse(stack, destid, srcid, tid);
+}
+#else
+void RIO_receiveResponseDone( RioStack_t *stack, uint16_t *srcid, uint8_t *tid)
+{
+ receiveResponse(stack, srcid, srcid, tid);
+}
+#endif
+
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendResponseRetry( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid )
+{
+ sendResponse(stack, destid, srcid, tid, 0x3u);
+}
+#else
+void RIO_sendResponseRetry( RioStack_t *stack, const uint16_t destid, const uint8_t tid )
+{
+ sendResponse(stack, destid, stack->baseDeviceId, tid, 0x3u);
+}
+#endif
+
+
+#ifdef RIO_TRANSPARENT
+void RIO_receiveResponseRetry( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid)
+{
+ receiveResponse(stack, destid, srcid, tid);
+}
+#else
+void RIO_receiveResponseRetry( RioStack_t *stack, uint16_t *srcid, uint8_t *tid)
+{
+ receiveResponse(stack, srcid, srcid, tid);
+}
+#endif
+
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendResponseError( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid)
+{
+ sendResponse(stack, destid, srcid, tid, 0x7u);
+}
+#else
+void RIO_sendResponseError( RioStack_t *stack, const uint16_t destid, const uint8_t tid)
+{
+ sendResponse(stack, destid, stack->baseDeviceId, tid, 0x7u);
+}
+#endif
+
+
+#ifdef RIO_TRANSPARENT
+void RIO_receiveResponseError( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid)
+{
+ receiveResponse(stack, destid, srcid, tid);
+}
+#else
+void RIO_receiveResponseError( RioStack_t *stack, uint16_t *srcid, uint8_t *tid)
+{
+ receiveResponse(stack, srcid, srcid, tid);
+}
+#endif
+
+
+
+/*******************************************************************************************
+ * Logical message passing DOORBELL and MESSAGE functions.
+ *******************************************************************************************/
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendDoorbell( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint16_t info )
+{
+ sendDoorbell(stack, destid, srcid, tid, info);
+}
+#else
+void RIO_sendDoorbell( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint16_t info )
+{
+ sendDoorbell(stack, destid, stack->baseDeviceId, tid, info);
+}
+#endif
+
+#ifdef RIO_TRANSPARENT
+void RIO_receiveDoorbell( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint16_t *info)
+{
+ receiveDoorbell(stack, destid, srcid, tid, info);
+}
+#else
+void RIO_receiveDoorbell( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ uint16_t *info)
+{
+ receiveDoorbell(stack, srcid, srcid, tid, info);
+}
+#endif
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendMessage( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
+ const uint16_t bufferSize, const uint8_t* bufferData)
+{
+ sendMessage(stack, destid, srcid, mailbox, bufferSize, bufferData);
+}
+#else
+void RIO_sendMessage( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox,
+ const uint16_t bufferSize, const uint8_t* bufferData)
+{
+ sendMessage(stack, destid, stack->baseDeviceId, mailbox, bufferSize, bufferData);
+}
+#endif
+
+#ifdef RIO_TRANSPARENT
+uint16_t RIO_receiveMessage( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox,
+ const uint16_t dataLength, uint8_t *data )
+{
+ return receiveMessage(stack, destid, srcid, mailbox, dataLength, data);
+}
+#else
+uint16_t RIO_receiveMessage( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox,
+ const uint16_t dataLength, uint8_t *data )
+{
+ return receiveMessage(stack, srcid, srcid, mailbox, dataLength, data);
+}
+#endif
+
+/*******************************************************************************************
+ * Logical message passing MESSAGE-RESPONSE functions.
+ *******************************************************************************************/
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendMessageResponseDone( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox)
+{
+ sendMessageResponse(stack, destid, srcid, mailbox, 0x0u);
+}
+#else
+void RIO_sendMessageResponseDone( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox)
+{
+ sendMessageResponse(stack, destid, stack->baseDeviceId, mailbox, 0x0u);
+}
+#endif
+
+
+#ifdef RIO_TRANSPARENT
+void RIO_receiveMessageResponseDone( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox)
+{
+ receiveMessageResponse(stack, destid, srcid, mailbox);
+}
+#else
+void RIO_receiveMessageResponseDone( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox)
+{
+ receiveMessageResponse(stack, srcid, srcid, mailbox);
+}
+#endif
+
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendMessageResponseRetry( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox)
+{
+ sendMessageResponse(stack, destid, srcid, mailbox, 0x3u);
+}
+#else
+void RIO_sendMessageResponseRetry( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox)
+{
+ sendMessageResponse(stack, destid, stack->baseDeviceId, mailbox, 0x3u);
+}
+#endif
+
+
+#ifdef RIO_TRANSPARENT
+void RIO_receiveMessageResponseRetry( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox)
+{
+ receiveMessageResponse(stack, destid, srcid, mailbox);
+}
+#else
+void RIO_receiveMessageResponseRetry( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox)
+{
+ receiveMessageResponse(stack, srcid, srcid, mailbox);
+}
+#endif
+
+
+#ifdef RIO_TRANSPARENT
+void RIO_sendMessageResponseError( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox)
+{
+ sendMessageResponse(stack, destid, srcid, mailbox, 0x7u);
+}
+#else
+void RIO_sendMessageResponseError( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox)
+{
+ sendMessageResponse(stack, destid, stack->baseDeviceId, mailbox, 0x7u);
+}
+#endif
+
+
+#ifdef RIO_TRANSPARENT
+void RIO_receiveMessageResponseError( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox)
+{
+ receiveMessageResponse(stack, destid, srcid, mailbox);
+}
+#else
+void RIO_receiveMessageResponseError( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox)
+{
+ receiveMessageResponse(stack, srcid, srcid, mailbox);
+}
+#endif
+
+
+void RIO_portSetStatus( RioStack_t *stack, const uint8_t initialized)
+{
+ /* REMARK: Clean the queues here as well??? */
+ if (initialized)
+ {
+ stack->rxState = RX_STATE_PORT_INITIALIZED;
+ stack->rxCounter = 0u;
+ stack->rxCrc = 0xffffu;
+ stack->rxStatusReceived = 0;
+ stack->rxAckId = 0u;
+ stack->rxAckIdAcked = 0u;
+ stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_RESERVED;
+
+ stack->txState = TX_STATE_PORT_INITIALIZED;
+ stack->txCounter = 0u;
+ stack->txStatusCounter = 0u;
+ stack->txFrameState = TX_FRAME_START;
+ stack->txAckId = 0u;
+ stack->txAckIdWindow = 0u;
+ }
+ else
+ {
+ stack->rxState = RX_STATE_UNINITIALIZED;
+ stack->txState = TX_STATE_UNINITIALIZED;
+ }
+}
+
+
+void RIO_portSetTime( RioStack_t *stack, const uint32_t time)
+{
+ stack->portTime = time;
+}
+
+
+void RIO_portSetTimeout( RioStack_t *stack, const uint32_t time)
+{
+ stack->portTimeout = time;
+}
+
+
+void RIO_portAddSymbol( RioStack_t *stack, const RioSymbol s)
+{
+ uint8_t stype0;
+ uint8_t parameter0;
+ uint8_t parameter1;
+ uint8_t stype1;
+
+
+ switch(stack->rxState)
+ {
+ case RX_STATE_PORT_INITIALIZED:
+ /******************************************************************************
+ * PORT_INITIALIZED
+ * This state is entered to initialize the link. Only status-control-symbols
+ * are accepted in this state. When 7 error-free, i.e. with CRC5 correct, status
+ * control symbols has been received, change state to linkInitialized.
+ ******************************************************************************/
+
+ /* Check the type of symbol. */
+ if(s.type == RIO_SYMBOL_TYPE_CONTROL)
+ {
+ /* This is a control symbol. */
+
+ /* Check that the control symbol contains no errors. */
+ if(Crc5(s.data, 0x1fu) == (s.data & 0x1ful))
+ {
+ /* Error-free control symbol. */
+
+ /* Check if the symbol is a status symbol. */
+ stype0 = STYPE0_GET(s.data);
+ if(stype0 == STYPE0_STATUS)
+ {
+ /* Status symbol received. */
+
+ /* Indicate an error-free status has been received. */
+ stack->rxStatusReceived = 1;
+
+ /* Check if enough status control symbols has been received. */
+ if(stack->rxCounter == 7u)
+ {
+ /* Enough correct status control symbols has been received without
+ errors in between. */
+
+ /* Setup the transmitter with the content of the symbol. */
+ stack->txAckId = PARAMETER0_GET(s.data);
+ stack->txAckIdWindow = stack->txAckId;
+ stack->txBufferStatus = PARAMETER1_GET(s.data);
+
+ /* Set the transmitter in its normal operational mode. */
+ stack->rxState = RX_STATE_LINK_INITIALIZED;
+ stack->rxCounter = 0u;
+ DEBUG_STATE("rx:normal");
+ }
+ else
+ {
+ /* Count the number of consequitive error-free status control symbols
+ that has been received. */
+ stack->rxCounter++;
+ }
+ }
+ else
+ {
+ /* The received symbol is not a status symbol. */
+ /* Discard it. */
+ }
+ }
+ else
+ {
+ /* CRC error in control symbol. */
+ /* Restart counting error-free status-control-symbols. */
+ stack->rxCounter = 0u;
+ }
+ }
+ else
+ {
+ /* Not a control symbol. */
+ /* Discard the symbol. */
+ }
+
+ break;
+
+ case RX_STATE_LINK_INITIALIZED:
+ /******************************************************************************
+ * LINK_INITIALIZED
+ * The normal state. Accept packets and forward them.
+ ******************************************************************************/
+
+ /* Check the type of symbol. */
+ switch(s.type)
+ {
+ case RIO_SYMBOL_TYPE_CONTROL:
+ /**************************************************************************
+ * This is a control symbol.
+ **************************************************************************/
+
+ /* Check if the CRC is correct. */
+ if(Crc5(s.data, 0x1fu) == (s.data & (uint8_t)0x1ful))
+ {
+ /* The CRC is correct. */
+
+ /* Get the content of the control symbol. */
+ stype0 = STYPE0_GET(s.data);
+ parameter0 = PARAMETER0_GET(s.data);
+ parameter1 = PARAMETER1_GET(s.data);
+ stype1 = STYPE1_GET(s.data);
+
+ /**********************************************************************************
+ * Check the stype0 part of the symbol.
+ * Note that errors in this should trigger OUTPUT_ERROR_STOPPED.
+ **********************************************************************************/
+ switch(stype0)
+ {
+ case STYPE0_STATUS:
+ /* A status containing the current ackId and the buffer status has been
+ received. */
+ handleStatus(stack, parameter0, parameter1);
+ break;
+
+ case STYPE0_PACKET_ACCEPTED:
+ /* A packet has been accepted by the link partner. */
+ handlePacketAccepted(stack, parameter0, parameter1);
+ break;
+
+ case STYPE0_PACKET_RETRY:
+ /* The link partner wants us to initiate a restart of the received ackId. */
+ handlePacketRetry(stack, parameter0, parameter1);
+ break;
+
+ case STYPE0_PACKET_NOT_ACCEPTED:
+ /* The link partner indicates that a packet has been rejected. */
+ handlePacketNotAccepted(stack, parameter0, parameter1);
+ break;
+
+ case STYPE0_LINK_RESPONSE:
+ /* The link partner has sent a response to a link-request. */
+ handleLinkResponse(stack, parameter0, parameter1);
+ break;
+
+ case STYPE0_VC_STATUS:
+ case STYPE0_RESERVED:
+ case STYPE0_IMPLEMENTATION_DEFINED:
+ default:
+ /* Unsupported symbol received. */
+ /* Discard them. */
+ break;
+ }
+
+ /**********************************************************************************
+ * Check the stype1 part of the symbol.
+ * Note that errors in this should trigger INPUT_ERROR_STOPPED.
+ **********************************************************************************/
+ switch(stype1)
+ {
+ case STYPE1_START_OF_PACKET:
+ /* Start of a new packet. */
+ handleStartOfPacket(stack);
+ break;
+
+ case STYPE1_END_OF_PACKET:
+ /* Ending a packet. */
+ handleEndOfPacket(stack);
+ break;
+
+ case STYPE1_STOMP:
+ /* Cancel the currently received frame. */
+ stack->rxCounter = 0;
+ break;
+
+ case STYPE1_RESTART_FROM_RETRY:
+ /* Cancel the currently received frame when in this state. */
+ stack->rxCounter = 0;
+ break;
+
+ case STYPE1_LINK_REQUEST:
+ /* A link-request has been received. */
+ handleLinkRequest(stack, CMD_GET(s.data));
+ break;
+
+ case STYPE1_NOP:
+ /* No operation symbol. */
+ /* Discard these. */
+ break;
+
+ case STYPE1_MULTICAST_EVENT:
+ case STYPE1_RESERVED:
+ default:
+ /* Unsupported symbol received. */
+ /* Discard them. */
+ break;
+ }
+ }
+ else
+ {
+ /* The control symbol CRC is incorrect. */
+ /* Corrupted control symbol. Discard the symbol and enter the input-error-stopped state. */
+ stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
+ stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
+ stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC;
+ stack->statusInboundErrorControlCrc++;
+ DEBUG_STATE("rx:error-stopped");
+ }
+ break;
+
+ case RIO_SYMBOL_TYPE_DATA:
+ /**************************************************************************
+ * This is a data symbol.
+ **************************************************************************/
+
+ /* Check if a packet has been started and that it is not too long. */
+ if ((stack->rxCounter >= 1u) && (stack->rxCounter <= RIO_PACKET_SIZE))
+ {
+ /* A packet has been started. */
+
+ /* Check if the ackId is correct on the first part of the packet. */
+ if ((stack->rxCounter > 1u) ||
+ ((stack->rxCounter == 1u) && (((uint8_t)(s.data >> 27)) == stack->rxAckId)))
+ {
+ /* The ackId is the expected one. */
+
+ /* Check if this is the first symbol of a packet. */
+ if (stack->rxCounter == 1u)
+ {
+ /* This is the first symbol of the packet. */
+ /* Start to calculate the CRC of the packet. */
+ /* Note that the ackId should not be included in the CRC calculation. */
+ stack->rxCrc = Crc32(s.data & (uint32_t)0x03fffffful, 0xffffu);
+ }
+ else
+ {
+ /* This is not the first symbol. */
+ /* Continue to calculate the CRC of the packet. */
+ stack->rxCrc = Crc32(s.data, stack->rxCrc);
+ }
+
+ /* Save the new data in the packet queue and update the reception counter. */
+ QueueSetContent(stack->rxQueue, (uint32_t)stack->rxCounter - (uint32_t)1ul, s.data);
+ stack->rxCounter++;
+ }
+ else
+ {
+ DEBUG_FRAMING_RX("error=%u %u", stack->rxAckId, s.data>>27);
+
+ /* The ackId is not correct. */
+ /* Packet error. Enter input-error-stopped state. */
+ stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
+ stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
+ stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID;
+ stack->statusInboundErrorPacketAckId++;
+ DEBUG_STATE("rx:error-stopped");
+ }
+ }
+ else
+ {
+ /* No packet has been started or the packet is too long. */
+ /* Packet error. Enter input-error-stopped state. */
+ stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
+ stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
+ stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_GENERAL;
+ stack->statusInboundErrorGeneral++;
+ DEBUG_STATE("rx:error-stopped");
+ }
+ break;
+
+ case RIO_SYMBOL_TYPE_ERROR:
+ /**************************************************************************
+ * The decoder has received a erronous symbol.
+ **************************************************************************/
+
+ /* Idle symbol error. Place the receiver in input-error-stopped state. */
+ stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
+ stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
+ stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER;
+ stack->statusInboundErrorIllegalCharacter++;
+ DEBUG_STATE("rx:error-stopped");
+ break;
+
+ case RIO_SYMBOL_TYPE_IDLE:
+ default:
+ /**************************************************************************
+ * Idle symbol or unsupported symbol.
+ **************************************************************************/
+
+ /* Discard these for now. */
+ break;
+ }
+ break;
+
+ case RX_STATE_INPUT_RETRY_STOPPED:
+ /******************************************************************************
+ * INPUT_RETRY_STOPPED
+ * This state is entered when no more buffers was available and a packet was
+ * received. When in this state, all packets should be discarded until a
+ * RESTART-FROM-RETRY symbol is received. See section 5.9.1.4 of the standard.
+ * Note that it is only the input side of the port that are affected, not the
+ * output side. Packets may still be transmitted and acknowledges should be
+ * accepted.
+ ******************************************************************************/
+
+ /* Check the type of symbol. */
+ switch(s.type)
+ {
+ case RIO_SYMBOL_TYPE_CONTROL:
+ /* This is a control symbol. */
+
+ /* Check if the CRC is correct. */
+ if(Crc5(s.data, 0x1fu) == (s.data & (uint8_t)0x1ful))
+ {
+ /* The CRC is correct. */
+
+ /* Get the content of the control symbol. */
+ stype0 = STYPE0_GET(s.data);
+ parameter0 = PARAMETER0_GET(s.data);
+ parameter1 = PARAMETER1_GET(s.data);
+ stype1 = STYPE1_GET(s.data);
+
+ /* Check the stype0 part of the symbol. */
+ switch(stype0)
+ {
+ case STYPE0_STATUS:
+ /* A status containing the current ackId and the buffer status has been
+ received. */
+ handleStatus(stack, parameter0, parameter1);
+ break;
+
+ case STYPE0_PACKET_ACCEPTED:
+ /* A packet has been accepted by the link partner. */
+ handlePacketAccepted(stack, parameter0, parameter1);
+ break;
+
+ case STYPE0_PACKET_RETRY:
+ /* The link partner wants us to initiate a restart of the received ackId. */
+ handlePacketRetry(stack, parameter0, parameter1);
+ break;
+
+ case STYPE0_PACKET_NOT_ACCEPTED:
+ /* The link partner indicates that a packet has been rejected. */
+ handlePacketNotAccepted(stack, parameter0, parameter1);
+ break;
+
+ case STYPE0_LINK_RESPONSE:
+ /* The link partner has sent a response to a link-request. */
+ handleLinkResponse(stack, parameter0, parameter1);
+ break;
+
+ case STYPE0_VC_STATUS:
+ case STYPE0_RESERVED:
+ case STYPE0_IMPLEMENTATION_DEFINED:
+ default:
+ /* Unsupported symbol received. */
+ /* Discard them. */
+ break;
+ }
+
+ /* Check the stype1 part of the symbol. */
+ switch(stype1)
+ {
+ case STYPE1_START_OF_PACKET:
+ /* Starting new frames are ignored in this state. */
+ break;
+
+ case STYPE1_END_OF_PACKET:
+ /* Ending new frames are ignored in this state. */
+ break;
+
+ case STYPE1_STOMP:
+ /* Restarting frames are ignored in this state. */
+ break;
+
+ case STYPE1_RESTART_FROM_RETRY:
+ /* The link partner has confirmed our packet-retry-symbol. */
+ /* Go back to the normal state and reset the frame reception. */
+ stack->rxState = RX_STATE_LINK_INITIALIZED;
+ stack->rxCounter = 0u;
+ DEBUG_STATE("rx:normal(restart)");
+ break;
+
+ case STYPE1_LINK_REQUEST:
+ /* A link-request has been received. */
+ handleLinkRequest(stack, CMD_GET(s.data));
+ stack->rxState = RX_STATE_LINK_INITIALIZED;
+ DEBUG_STATE("rx:normal(link-req)");
+ break;
+
+ case STYPE1_NOP:
+ /* No operation symbol. */
+ /* Discard these. */
+ break;
+
+ case STYPE1_MULTICAST_EVENT:
+ case STYPE1_RESERVED:
+ default:
+ /* Unsupported symbol received. */
+ /* Discard them. */
+ break;
+ }
+ }
+ else
+ {
+ /* The control symbol CRC is incorrect. */
+ /* Corrupted control symbol. Discard the symbol and enter the input-error-stopped state. */
+ stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
+ stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
+ stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC;
+ stack->statusInboundErrorControlCrc++;
+ DEBUG_STATE("rx:error-stopped");
+ }
+ break;
+
+ case RIO_SYMBOL_TYPE_ERROR:
+ /* Idle symbol error. Place the receiver in input-error-stopped state. */
+ stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
+ stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
+ stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER;
+ stack->statusInboundErrorIllegalCharacter++;
+ DEBUG_STATE("rx:error-stopped");
+ break;
+
+ case RIO_SYMBOL_TYPE_DATA:
+ case RIO_SYMBOL_TYPE_IDLE:
+ default:
+ /* Data or idle symbol. */
+ /* Discard these in this state. */
+ break;
+ }
+ break;
+
+ case RX_STATE_INPUT_ERROR_STOPPED:
+ /******************************************************************************
+ * INPUT_ERROR_STOPPED
+ * This state is entered when an error situation has occurred. When in this
+ * state, all symbols should be discarded until a link-request-symbols has
+ * been received. See section 5.13.2.6 in part 6 of the standard.
+ * Note that it is only the input side of the port that are affected, not the
+ * output side. Packets may still be transmitted and acknowledges should be
+ * accepted.
+ ******************************************************************************/
+
+ /* Check the type of symbol. */
+ switch(s.type)
+ {
+ case RIO_SYMBOL_TYPE_CONTROL:
+ /* This is a control symbol. */
+
+ /* Check if the CRC is correct. */
+ if(Crc5(s.data, 0x1fu) == (s.data & (uint8_t)0x1ful))
+ {
+ /* The CRC is correct. */
+
+ /* Get the content of the control symbol. */
+ stype0 = STYPE0_GET(s.data);
+ parameter0 = PARAMETER0_GET(s.data);
+ parameter1 = PARAMETER1_GET(s.data);
+ stype1 = STYPE1_GET(s.data);
+
+ /* Check the stype0 part of the symbol. */
+ switch(stype0)
+ {
+ case STYPE0_STATUS:
+ /* A status containing the current ackId and the buffer status has been
+ received. */
+ handleStatus(stack, parameter0, parameter1);
+ break;
+
+ case STYPE0_PACKET_ACCEPTED:
+ /* A packet has been accepted by the link partner. */
+ handlePacketAccepted(stack, parameter0, parameter1);
+ break;
+
+ case STYPE0_PACKET_RETRY:
+ /* The link partner wants us to initiate a restart of the received ackId. */
+ handlePacketRetry(stack, parameter0, parameter1);
+ break;
+
+ case STYPE0_PACKET_NOT_ACCEPTED:
+ /* The link partner indicates that a packet has been rejected. */
+ handlePacketNotAccepted(stack, parameter0, parameter1);
+ break;
+
+ case STYPE0_LINK_RESPONSE:
+ /* The link partner has sent a response to a link-request. */
+ handleLinkResponse(stack, parameter0, parameter1);
+ break;
+
+ case STYPE0_VC_STATUS:
+ case STYPE0_RESERVED:
+ case STYPE0_IMPLEMENTATION_DEFINED:
+ default:
+ /* Unsupported symbol received. */
+ /* Discard them. */
+ break;
+ }
+
+ /* Check the stype1 part of the symbol. */
+ switch(stype1)
+ {
+ case STYPE1_START_OF_PACKET:
+ /* Starting new frames are ignored in this state. */
+ break;
+
+ case STYPE1_END_OF_PACKET:
+ /* Ending new frames are ignored in this state. */
+ break;
+
+ case STYPE1_STOMP:
+ /* Restarting frames are ignored in this state. */
+ break;
+
+ case STYPE1_RESTART_FROM_RETRY:
+ /* Restart-from-retry are ignored in this state. */
+ break;
+
+ case STYPE1_LINK_REQUEST:
+ /* This is the symbol we have been waiting for. */
+ /* Force the transmitter to send a link-response and go back into the normal
+ operational state. */
+ /* The transmitter will always send a status as the first symbol after this. */
+ handleLinkRequest(stack, CMD_GET(s.data));
+ stack->rxState = RX_STATE_LINK_INITIALIZED;
+ DEBUG_STATE("rx:normal(link-req)");
+ break;
+
+ case STYPE1_NOP:
+ /* No operation symbol. */
+ /* Discard these. */
+ break;
+
+ case STYPE1_MULTICAST_EVENT:
+ case STYPE1_RESERVED:
+ default:
+ /* Unsupported symbol received. */
+ /* Discard them. */
+ break;
+ }
+ }
+ else
+ {
+ /* The CRC is incorrect. */
+ /* Discard these in this state. */
+ }
+ break;
+
+ case RIO_SYMBOL_TYPE_DATA:
+ case RIO_SYMBOL_TYPE_IDLE:
+ case RIO_SYMBOL_TYPE_ERROR:
+ default:
+ /* Data, idle or error symbol. */
+ /* Discard these in this state. */
+ break;
+ }
+ break;
+
+ case RX_STATE_UNINITIALIZED:
+ default:
+ /******************************************************************************
+ * Wait for the port to be initialized.
+ ******************************************************************************/
+
+ /* Discard all incoming symbols. */
+ break;
+ }
+}
+
+
+
+RioSymbol RIO_portGetSymbol( RioStack_t *stack )
+{
+ RioSymbol s;
+
+
+ switch(stack->txState)
+ {
+ case TX_STATE_PORT_INITIALIZED:
+ /******************************************************************************
+ * PORT_INITIALIZED
+ * This state is entered to initialize the link. Send status-control-symbols
+ * once in a while until the receiver has received enough error-free status-
+ * control-symbols and we have transmitted enough status-control-symbols. Once
+ * an error-free status-control-symbol has been received, the statuses are
+ * transmitted more frequently to decrease the time for the link to be
+ * initialized.
+ ******************************************************************************/
+
+ /* Check if an idle symbol or a status control symbol should be sent. */
+ if(((stack->rxStatusReceived == 0) && (stack->txCounter == 255u)) ||
+ ((stack->rxStatusReceived == 1) && (stack->txCounter >= 15u)))
+ {
+ /* A control symbol should be sent. */
+
+ /* Create a new status symbol and reset the transmission counter. */
+ stack->txCounter = 0u;
+ s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
+ STYPE1_NOP, 0u);
+
+ /* Check if the receiver has received any error-free status and that we
+ have sent at least 15 status control symbols. */
+ if((stack->rxStatusReceived == 1) && (stack->txStatusCounter < 15u))
+ {
+ /* Has not sent enough status control symbols. */
+ stack->txStatusCounter++;
+ }
+ else
+ {
+ /* Has sent enough status control symbols. */
+ /* Dont do anything. */
+ }
+ }
+ else
+ {
+ /* Idle symbol should be sent. */
+ s.type = RIO_SYMBOL_TYPE_IDLE;
+ stack->txCounter++;
+ }
+
+ /* Check if we are ready to set the transmitter in a link initialized state. */
+ if ((stack->rxState == RX_STATE_LINK_INITIALIZED) && (stack->txStatusCounter == 15u))
+ {
+ /* Ready to go to link initialized. */
+ stack->txState = TX_STATE_LINK_INITIALIZED;
+ stack->txFrameState = TX_FRAME_START;
+ stack->txStatusCounter = 0u;
+ DEBUG_STATE("tx:normal");
+ }
+ else
+ {
+ /* Not ready to go to link initialized. */
+ /* Dont do anything. */
+ }
+
+ break;
+
+ case TX_STATE_LINK_INITIALIZED:
+ /******************************************************************************
+ * LINK_INITIALIZED
+ * The normal state. Accept packets and forward them. Send acknowledges when
+ * the receiver has received complete packets.
+ ******************************************************************************/
+
+ /* Check if the receiver wants to acknowledge a packet. */
+ if(stack->rxAckId == stack->rxAckIdAcked)
+ {
+ /* The receiver does not want to acknowledge a packet. */
+
+ /* Check if there are any outstanding packets and if it has timed out. */
+ if((stack->txAckId == stack->txAckIdWindow) ||
+ ((stack->portTime - stack->txFrameTimeout[stack->txAckId]) < stack->portTimeout))
+ {
+ /* There are no outstanding packets or there has been no timeout. */
+
+ /* Check if a packet is ongoing. */
+ if(stack->txFrameState == TX_FRAME_BODY)
+ {
+ /* A packet transmission is ongoing. */
+
+ /* Check if the packet has been completly sent. */
+ if(stack->txCounter != QueueGetFrontSize(stack->txQueue))
+ {
+ /* The packet has not been completly sent. */
+
+ /* Create a new data symbol to transmit. */
+ s.type = RIO_SYMBOL_TYPE_DATA;
+ s.data = QueueGetFrontContent(stack->txQueue, (uint32_t)stack->txCounter);
+
+ /* Check if this is the first symbol in a packet. */
+ if (stack->txCounter == 0u)
+ {
+ /* Place the correct ackId in the right place. */
+ s.data |= (uint32_t)stack->txAckIdWindow << 27;
+ }
+ else
+ {
+ /* Dont do anything. */
+ }
+
+ /* Update the transmission counter. */
+ stack->txCounter++;
+
+ /* A status control symbol was not sent. Update the status counter. */
+ stack->txStatusCounter++;
+ }
+ else
+ {
+ /* The packet has been sent. */
+
+ /* Save the timeout time and update to the next ackId. */
+ stack->txFrameTimeout[stack->txAckIdWindow] = stack->portTime;
+ stack->txAckIdWindow = ACKID_INC(stack->txAckIdWindow);
+ stack->txQueue = QueueWindowNext(stack->txQueue);
+
+ /* Check if there are more packets pending to be sent. */
+ /* Also check that there are buffer available at the receiver and that not too many
+ packets are outstanding. */
+ if(!QueueWindowEmpty(stack->txQueue) && (stack->txBufferStatus > 0) &&
+ (((stack->txAckIdWindow - stack->txAckId) & 0x1f) != 31))
+ {
+ /* More pending packets. */
+ DEBUG_FRAMING_TX("cont=%i", stack->txAckIdWindow);
+ /* Create a control symbol to signal that the new packet has started. */
+ s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
+ STYPE1_START_OF_PACKET, 0u);
+
+ /* Restart transmission counter. */
+ stack->txCounter = 0;
+ }
+ else
+ {
+ /* No more pending packets. */
+ DEBUG_FRAMING_TX("end=%i", stack->txAckIdWindow);
+ /* Create a control symbol to signal that the packet has ended. */
+ s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
+ STYPE1_END_OF_PACKET, 0u);
+
+ /* Go back to wait for a new frame. */
+ stack->txFrameState = TX_FRAME_START;
+ }
+
+ /* A status control symbol has been sent. Reset the status counter. */
+ stack->txStatusCounter = 0u;
+ }
+ }
+ else
+ {
+ /* No packet is being sent. */
+
+ /* Check if there are any pending packets to start sending. */
+ /* Also check that there are buffer available at the receiver and that not too many
+ packets are outstanding. */
+ if(!QueueWindowEmpty(stack->txQueue) && (stack->txBufferStatus > 0) &&
+ (((stack->txAckIdWindow - stack->txAckId) & 0x1f) != 31))
+ {
+ /* There is a pending packet to send. */
+ DEBUG_FRAMING_TX("start=%i", stack->txAckIdWindow);
+ /* Send a start-of-packet control symbol to start to send the packet. */
+ s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
+ STYPE1_START_OF_PACKET, 0u);
+ stack->txFrameState = TX_FRAME_BODY;
+ stack->txCounter = 0u;
+
+ /* A status control symbol has been sent. Reset the status counter. */
+ stack->txStatusCounter = 0u;
+ }
+ else
+ {
+ /* There are no pending packets to send. */
+
+ /* Check if a status control symbol must be transmitted. */
+ if(stack->txStatusCounter < 255u)
+ {
+ /* Not required to send a status control symbol. */
+
+ /* Send an idle-symbol. */
+ s.type = RIO_SYMBOL_TYPE_IDLE;
+ stack->txStatusCounter++;
+ }
+ else
+ {
+ /* Must send a status control symbol. */
+
+ /* Create a status control symbol. */
+ s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
+ STYPE1_NOP, 0u);
+
+ /* A status control symbol has been sent. Reset the status counter. */
+ stack->txStatusCounter = 0u;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* There has been a timeout. */
+ /* A packet has been sent but no packet-accepted has been received. */
+ DEBUG_FRAMING_TX("timeout=%i", stack->txAckId);
+ /* Send link-request-symbol (input-status). */
+ s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
+ STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
+
+ /* Save the time when this was transmitted. */
+ stack->txFrameTimeout[stack->txAckId] = stack->portTime;
+
+ /* Remember that this symbol has been transmitted. */
+ stack->txCounter = 1;
+
+ /* Go into the output error stopped state. */
+ stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
+ stack->statusOutboundErrorTimeout++;
+ DEBUG_STATE("tx:error-stopped");
+ }
+ }
+ else
+ {
+ /* The receiver wants us to send an acknowledgement. */
+ s = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, stack->rxAckIdAcked, QueueAvailable(stack->rxQueue),
+ STYPE1_NOP, 0u);
+ stack->rxAckIdAcked = ACKID_INC(stack->rxAckIdAcked);
+
+ /* A status control symbol was not sent. Update the status counter. */
+ stack->txStatusCounter++;
+ }
+ break;
+
+ case TX_STATE_SEND_PACKET_RETRY:
+ /******************************************************************************
+ * SEND_PACKET_RETRY
+ * This state is set by the receiver to force a packet-retry-symbol to be
+ * transmitted.
+ ******************************************************************************/
+
+ /* Check if the receiver wants to acknowledge a packet. */
+ /* This must be done first or we will get an error for a missmatching
+ ackId in the link-partner. */
+ if(stack->rxAckId == stack->rxAckIdAcked)
+ {
+ /* No pending acknowledge. */
+
+ /* Send a packet-retry symbol to tell the link partner to retry the last frame. */
+ s = CreateControlSymbol(STYPE0_PACKET_RETRY, stack->rxAckId, QueueAvailable(stack->rxQueue),
+ STYPE1_NOP, 0u);
+
+ /* Proceed with normal transmission. */
+ stack->txState = TX_STATE_LINK_INITIALIZED;
+
+ /* A status control symbol was not sent. Update the status counter. */
+ stack->txStatusCounter++;
+ }
+ else
+ {
+
+ /* The receiver wants us to send an acknowledgement. */
+ s = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, stack->rxAckIdAcked, QueueAvailable(stack->rxQueue),
+ STYPE1_NOP, 0u);
+ stack->rxAckIdAcked = ACKID_INC(stack->rxAckIdAcked);
+
+ /* A status control symbol was not sent. Update the status counter. */
+ stack->txStatusCounter++;
+ }
+ break;
+
+ case TX_STATE_SEND_PACKET_NOT_ACCEPTED:
+ /******************************************************************************
+ * SEND_PACKET_NOT_ACCEPTED
+ * This state is set by the receiver to force a packet-not-accepted-symbol to be
+ * transmitted.
+ ******************************************************************************/
+
+ /* Send a packet-not-accepted symbol to indicate an error on the link. */
+ s = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, stack->rxErrorCause,
+ STYPE1_NOP, 0u);
+
+ /* Proceed with normal transmission. */
+ stack->txState = TX_STATE_LINK_INITIALIZED;
+
+ /* A status control symbol was not sent. Update the status counter. */
+ stack->txStatusCounter++;
+ break;
+
+ case TX_STATE_SEND_LINK_RESPONSE:
+ /******************************************************************************
+ * SEND_LINK_RESPONSE
+ * This state is set by the receiver to force a link-response-symbol to be
+ * transmitted.
+ ******************************************************************************/
+
+ DEBUG_FRAMING_RX("link-res:%u", stack->rxAckId);
+
+ /* Check the state of the receiver. */
+ /* REMARK: If a link-request gives this response and a link-request also makes the receiver
+ enter the normal operational state, none of these states except the normal state will ever
+ be used... */
+ if((stack->rxState == RX_STATE_LINK_INITIALIZED) || (stack->rxState == RX_STATE_PORT_INITIALIZED))
+ {
+ /* Normal state. */
+ s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_OK,
+ STYPE1_NOP, 0u);
+ }
+ else if(stack->rxState == RX_STATE_INPUT_RETRY_STOPPED)
+ {
+ /* Input-retry-stopped state. */
+ s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_RETRY_STOPPED,
+ STYPE1_NOP, 0u);
+ }
+ else if(stack->rxState == RX_STATE_INPUT_ERROR_STOPPED)
+ {
+ /* Input-error-stopped state. */
+ s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_ERROR_STOPPED,
+ STYPE1_NOP, 0u);
+ }
+ else
+ {
+ /* Not in the defined states. */
+ s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_ERROR,
+ STYPE1_NOP, 0u);
+ }
+
+ /* Proceed with normal transmission. */
+ stack->txState = TX_STATE_LINK_INITIALIZED;
+
+ /* Force a status to be transmitted the next time to comply to the input-error-stopped
+ state rules. */
+ stack->txStatusCounter = 255;
+ break;
+
+ case TX_STATE_OUTPUT_RETRY_STOPPED:
+ /******************************************************************************
+ * OUTPUT_RETRY_STOPPED
+ * This state is entered when the link-partner has transmitted a
+ * packet-retry-symbol. The packet-retry-symbol is acknowledged by sending a
+ * restart-from-retry-symbol.
+ * This state follows 5.9.1.5 in part 6.
+ ******************************************************************************/
+
+ /* Send a restart-from-retry symbol to acknowledge. */
+ s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
+ STYPE1_RESTART_FROM_RETRY, 0u);
+
+ /* Restart the current frame and proceed with normal operation. */
+ stack->txFrameState = TX_FRAME_START;
+ stack->txState = TX_STATE_LINK_INITIALIZED;
+ stack->txCounter = 0;
+ DEBUG_STATE("tx:normal");
+
+ /* Discard all packets that has not received a matching packet-accepted. */
+ stack->txAckIdWindow = stack->txAckId;
+ stack->txQueue = QueueWindowReset(stack->txQueue);
+
+ /* A status control symbol was sent. Reset the status counter. */
+ stack->txStatusCounter = 0;
+ break;
+
+ case TX_STATE_OUTPUT_ERROR_STOPPED:
+ /******************************************************************************
+ * OUTPUT_ERROR_STOPPED
+ * This state is entered when the link partner has encountered any problem
+ * which is indicated by sending a packet-not-accepted symbol or if a packet
+ * timeout has expired. The error condition is acknowledged by sending a
+ * link-request-symbol and then wait for a link-response reply.
+ * This state follows 5.13.2.7 in part 6.
+ ******************************************************************************/
+
+ /* Check if a link-request-symbol has been transmitted. */
+ if(stack->txCounter == 0)
+ {
+ /* A link-request-symbol has not been transmitted. */
+
+ /* Send link-request-symbol (input-status). */
+ s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
+ STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
+
+ /* Save the time when this was transmitted. */
+ stack->txFrameTimeout[stack->txAckId] = stack->portTime;
+
+ /* Remember that this symbol has been transmitted. */
+ stack->txCounter = 1;
+ }
+ else
+ {
+ /* A link-request-symbol has been transmitted. */
+
+ /* Check if the link partner reply has timed out. */
+ if((stack->portTime - stack->txFrameTimeout[stack->txAckId]) < stack->portTimeout)
+ {
+ /* No timeout. */
+
+ /* A link-request-symbol has been transmitted. */
+ /* Send only idle-symbols until the link-response is received. */
+ s.type = RIO_SYMBOL_TYPE_IDLE;
+ }
+ else
+ {
+ /* Link response timeout. */
+
+ /* Check if the link-partner has not responded for too many times. */
+ if(stack->txCounter < 5)
+ {
+ /* Not too many timeouts. */
+ /* Retry and send a new link-request. */
+
+ /* Send link-request-symbol (input-status). */
+ s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
+ STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
+
+ /* Save the time when this was transmitted. */
+ stack->txFrameTimeout[stack->txAckId] = stack->portTime;
+
+ /* Increment the number of times we have retransmitted the link-request. */
+ stack->txCounter++;
+ }
+ else
+ {
+ /* The link partner has not answered for too many times. */
+ /* Give up and set the state to uninitialized. */
+ stack->txState = TX_STATE_UNINITIALIZED;
+ s.type = RIO_SYMBOL_TYPE_IDLE;
+ ASSERT0("No link-response received, giving up.");
+ }
+ }
+ }
+ break;
+
+ case TX_STATE_UNINITIALIZED:
+ default:
+ /******************************************************************************
+ * Wait for the port to be initialized.
+ ******************************************************************************/
+
+ /* Send only idle symbols. */
+ s.type = RIO_SYMBOL_TYPE_IDLE;
+ break;
+ }
+
+ /* Return the created symbol. */
+ return s;
+}
+
+/*******************************************************************************
+ * Deprecated functions
+ *******************************************************************************/
+
+uint8_t RIO_packetTid( RioStack_t *stack )
+{
+ ASSERT(!QueueEmpty(stack->rxQueue) , "Reading from empty reception queue.");
+
+ return (uint8_t) (QueueGetFrontContent(stack->rxQueue, 1ul) & 0xfful);
+}
+
+
+uint16_t RIO_packetDestination( RioStack_t *stack )
+{
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ return (uint16_t) (QueueGetFrontContent(stack->rxQueue, 0ul));
+}
+
+
+uint16_t RIO_packetSource( RioStack_t *stack )
+{
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ return (uint16_t) (QueueGetFrontContent(stack->rxQueue, 1ul) >> 16);
+}
+
+
+uint8_t RIO_readMaintenanceReadRequestHop( RioStack_t *stack )
+{
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ return (QueueGetFrontContent(stack->rxQueue, 2ul) >> 24);
+}
+
+uint32_t RIO_readMaintenanceReadRequestOffset( RioStack_t *stack )
+{
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ return (QueueGetFrontContent(stack->rxQueue, 2ul) & 0x00fffffcul);
+}
+
+uint8_t RIO_readMaintenanceReadResponseHop( RioStack_t *stack )
+{
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ return (QueueGetFrontContent(stack->rxQueue, 2ul) >> 24);
+}
+
+uint32_t RIO_readMaintenanceReadResponse( RioStack_t *stack )
+{
+ uint32_t readData;
+
+
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ /* There is no way of knowing where the data is positioned. */
+ /* Bit-or the two words together since one of the words are zero. */
+ readData = QueueGetFrontContent(stack->rxQueue, 3ul);
+ readData |= QueueGetFrontContent(stack->rxQueue, 4ul);
+ return readData;
+}
+
+uint8_t RIO_readMaintenanceWriteRequestHop( RioStack_t *stack )
+{
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ return (QueueGetFrontContent(stack->rxQueue, 2ul) >> 24);
+}
+
+uint32_t RIO_readMaintenanceWriteRequestOffset( RioStack_t *stack )
+{
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ return (QueueGetFrontContent(stack->rxQueue, 2ul) & 0x00fffffcul);
+}
+
+uint32_t RIO_readMaintenanceWriteRequestData( RioStack_t *stack )
+{
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ return (QueueGetFrontContent(stack->rxQueue, 3ul) | QueueGetFrontContent(stack->rxQueue, 4ul));
+}
+
+uint8_t RIO_readMaintenanceWriteResponseHop( RioStack_t *stack )
+{
+ return (uint8_t) (QueueGetFrontContent(stack->rxQueue, 2ul) >> 24);
+}
+
+
+
+void RIO_sendNwrite8( RioStack_t *stack, const uint16_t destid, const uint32_t address,
+ const uint8_t data)
+{
+ sendNwrite(stack, destid, stack->baseDeviceId, 0, address, 1, &data, 0u);
+}
+
+
+void RIO_sendNwriteR8( RioStack_t *stack, const uint16_t destid, const uint8_t tid, const uint32_t address,
+ const uint8_t data)
+{
+ sendNwrite(stack, destid, stack->baseDeviceId, tid, address, 1, &data, 1u);
+}
+
+
+uint32_t RIO_readNwriteAddress8( RioStack_t *stack )
+{
+ uint32_t address;
+
+
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ /* Assemble the address from the wrsize field and the address itself to get a byte address. */
+ address = (QueueGetFrontContent(stack->rxQueue, 1ul) >> 8) & (uint32_t)0x00000003ul;
+ address |= QueueGetFrontContent(stack->rxQueue, 2ul) & (uint32_t)0xfffffffcul;
+
+ return address;
+}
+
+
+uint8_t RIO_readNwriteSize8( RioStack_t *stack )
+{
+ uint8_t wrsize;
+ uint8_t n;
+
+
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ /* Get the wrsize field from the packet and check its value. */
+ wrsize = (uint8_t) ((QueueGetFrontContent(stack->rxQueue, 1ul) >> 8) & (uint32_t)0xful);
+ switch(wrsize)
+ {
+ case 0:
+ /* Reading one byte. */
+ n = 1u;
+ break;
+ case 1:
+ /* Reading one byte. */
+ n = 1u;
+ break;
+ case 2:
+ /* Reading one byte. */
+ n = 1u;
+ break;
+ case 3:
+ /* Reading one byte. */
+ n = 1u;
+ break;
+ default:
+ /* Unsupported. */
+ n = 0u;
+ break;
+ }
+
+ return n;
+}
+
+
+uint8_t RIO_readNwritePayload8( RioStack_t *stack )
+{
+ uint8_t returnValue;
+ uint32_t readData;
+
+
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ /* Since there is no way of knowing where the byte will be placed,
+ OR all bytes in the payload and return it. */
+ readData = QueueGetFrontContent(stack->rxQueue, 3ul);
+ returnValue = (uint8_t) (readData >> 24);
+ returnValue |= (uint8_t) (readData >> 16);
+ returnValue |= (uint8_t) (readData >> 8);
+ returnValue |= (uint8_t) (readData);
+ readData = QueueGetFrontContent(stack->rxQueue, 4ul);
+ returnValue |= (uint8_t) (readData >> 24);
+ returnValue |= (uint8_t) (readData >> 16);
+ returnValue |= (uint8_t) (readData >> 8);
+ returnValue |= (uint8_t) (readData);
+
+ return returnValue;
+}
+
+void RIO_sendNread8( RioStack_t *stack, const uint16_t destid, const uint8_t tid, const uint32_t address)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = ((uint32_t) 0x0012ul) << 16;
+ content |= (uint32_t) destid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 0ul, content);
+
+ /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
+ content = ((uint32_t) stack->baseDeviceId) << 16;
+ content |= ((uint32_t) 0x4ul) << 12;
+ content |= (address & (uint32_t)0x00000003ul) << 8;
+ content |= (uint32_t) tid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 1ul, content);
+
+ /* address(28:0)|wdptr|xamsbs(1:0) */
+ /* xamsbs cannot be used if the address is a word. */
+ content = address & (uint32_t)0xfffffffcul;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 2ul, content);
+
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ QueueSetContent(stack->txQueue, 3ul, content);
+
+ /* Set the size of the packet and place it in the queue. */
+ QueueSetSize(stack->txQueue, 4ul);
+ stack->txQueue = QueueEnqueue(stack->txQueue);
+}
+
+
+uint32_t RIO_readNreadAddress8( RioStack_t *stack )
+{
+ uint32_t address;
+
+
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ /* Assemble the address from the rdsize field and the address itself to get a byte address. */
+ address = (QueueGetFrontContent(stack->rxQueue, 1ul) >> 8) & (uint32_t)0x00000003ul;
+ address |= QueueGetFrontContent(stack->rxQueue, 2ul) & (uint32_t)0xfffffffcul;
+
+ return address;
+}
+
+
+uint8_t RIO_readNreadSize8( RioStack_t *stack )
+{
+ uint8_t rdsize;
+ uint8_t n;
+
+
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ /* Get the rdsize field from the packet and check its value. */
+ rdsize = (uint8_t) ((QueueGetFrontContent(stack->rxQueue, 1ul) >> 8) & (uint32_t)0xful);
+ switch(rdsize)
+ {
+ case 0:
+ /* Reading one byte. */
+ n = 1u;
+ break;
+ case 1:
+ /* Reading one byte. */
+ n = 1u;
+ break;
+ case 2:
+ /* Reading one byte. */
+ n = 1u;
+ break;
+ case 3:
+ /* Reading one byte. */
+ n = 1u;
+ break;
+ default:
+ /* Unsupported. */
+ n = 0u;
+ break;
+ }
+
+ return n;
+}
+
+
+void RIO_sendMessage8( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox, const uint16_t size, const uint8_t* data)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+ uint32_t packetIndex;
+ uint32_t dataIndex;
+
+
+ ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
+ ASSERT((size <= 256), "Packet sizes over 256 are currently unsupported.");
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = ((uint32_t) 0x001bul) << 16;
+ content |= (uint32_t) destid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 0ul, content);
+
+ /* sourceId(15:0)|msglen(3:0)|ssize(3:0)|letter(1:0|mbox(1:0)|xmbox(3:0) */
+ content = ((uint32_t) stack->baseDeviceId) << 16;
+ if(size <= 8u)
+ {
+ content |= ((uint32_t) 0x09ul) << 8;
+ }
+ else if(size <= 16u)
+ {
+ content |= ((uint32_t) 0x0aul) << 8;
+ }
+ else if(size <= 32u)
+ {
+ content |= ((uint32_t) 0x0bul) << 8;
+ }
+ else if(size <= 64u)
+ {
+ content |= ((uint32_t) 0x0cul) << 8;
+ }
+ else if(size <= 128u)
+ {
+ content |= ((uint32_t) 0x0dul) << 8;
+ }
+ else
+ {
+ content |= ((uint32_t) 0x0eul) << 8;
+ }
+ content |= ((uint32_t)mailbox & (uint32_t)0xfu) << 4;
+ content |= ((uint32_t)mailbox) >> 4;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 1ul, content);
+
+ /* double-word0...double-wordN */
+ dataIndex = 0;
+ packetIndex = 8;
+ while(dataIndex < size)
+ {
+ content <<= 8;
+ if(packetIndex == 80)
+ {
+ content |= crc >> 8;
+ }
+ else if(packetIndex == 81)
+ {
+ content |= crc & 0xff;
+ }
+ else
+ {
+ content |= data[dataIndex++];
+ }
+
+ if((packetIndex & 0x3) == 3)
+ {
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, packetIndex>>2, content);
+ }
+
+ packetIndex++;
+ }
+
+ /* Pad the data to an even double word. */
+ while((dataIndex & 0x7) != 0)
+ {
+ content <<= 8;
+ dataIndex++;
+
+ if((packetIndex & 0x3) == 3)
+ {
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, packetIndex>>2, content);
+ }
+
+ packetIndex++;
+ }
+
+ /* Check where the CRC should be placed. */
+ if((packetIndex & 0x3) == 0)
+ {
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ }
+ else
+ {
+ /* double-wordN-LSB|crc(15:0) */
+ content &= 0x0000ffff;
+ crc = Crc16(content, crc);
+ content <<= 16;
+ content |= crc;
+ }
+
+ /* Set the crc. */
+ QueueSetContent(stack->txQueue, packetIndex>>2, content);
+
+ /* Set the size of the packet and place it in the queue. */
+ QueueSetSize(stack->txQueue, 1+(packetIndex>>2));
+ stack->txQueue = QueueEnqueue(stack->txQueue);
+}
+
+
+uint8_t RIO_readMessageMbox( RioStack_t *stack )
+{
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue." );
+
+ return (uint8_t) ((QueueGetFrontContent(stack->rxQueue, 1ul) >> 4) & (uint32_t)0xful);
+}
+
+
+uint16_t RIO_readMessageSize8( RioStack_t *stack )
+{
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ return (uint16_t) (4ul*(QueueGetFrontSize(stack->rxQueue) - 3ul));
+}
+
+
+/*lint -save -e613 */
+void RIO_readMessagePayload8( RioStack_t *stack, uint8_t* buffer )
+{
+ uint32_t size;
+ uint32_t dataIndex;
+ uint32_t packetIndex;
+ uint32_t content = 0;;
+
+
+ ASSERT((buffer != NULL), "Buffer is not allocated.");
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ /* Move bytes from inbound packet queue into the user buffer. */
+ /* Long messages contain a CRC in byte 80-81, this is removed when the buffer
+ is copied. */
+ size = QueueGetFrontSize(stack->rxQueue);
+ dataIndex = 0;
+ packetIndex = 8;
+ while((packetIndex>>2) < size)
+ {
+ /* Check if a new word should be read from the inbound queue. */
+ if((packetIndex & 0x3) == 0)
+ {
+ /* Get a new word. */
+ content = QueueGetFrontContent(stack->rxQueue, packetIndex>>2);
+ }
+ else
+ {
+ /* Update the current word. Remove the MSB, it has already be moved
+ to the user buffer. */
+ content <<= 8;
+ }
+
+ /* Check if the current byte is CRC. */
+ if((packetIndex != 80) && (packetIndex != 81))
+ {
+ /* Not CRC. */
+ /* Move the byte to the user buffer. */
+ buffer[dataIndex++] = (content >> 24);
+ }
+
+ /* Increment to the next position in the packet. */
+ packetIndex++;
+ }
+}
+/*lint -restore */
+
+uint16_t RIO_readDoorbellInfo( RioStack_t *stack )
+{
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ return (uint16_t) (QueueGetFrontContent(stack->rxQueue, 2ul) >> 16);
+}
+
+
+void RIO_sendResponseDone8( RioStack_t *stack, const uint16_t destid, const uint8_t tid, const uint32_t address, const uint8_t data)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x001dul << 16;
+ content |= (uint32_t) destid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 0ul, content);
+
+ /* sourceId(15:0)|transaction(3:0)|status(3:0)|targetTID(7:0) */
+ content = ((uint32_t) stack->baseDeviceId) << 16;
+ content |= (uint32_t)0x80ul << 8;
+ content |= (uint32_t) tid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 1ul, content);
+
+ /* double-word 0 */
+ switch(address & 0x7ul)
+ {
+ case 0:
+ /* MSB byte. */
+ content = ((uint32_t) data) << 24;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 2ul, content);
+ content = 0x00000000ul;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 3ul, content);
+ break;
+ case 1:
+ content = ((uint32_t) data) << 16;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 2ul, content);
+ content = 0x00000000ul;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 3ul, content);
+ break;
+ case 2:
+ content = ((uint32_t) data) << 8;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 2ul, content);
+ content = 0x00000000ul;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 3ul, content);
+ break;
+ case 3:
+ content = ((uint32_t) data);
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 2ul, content);
+ content = 0x00000000ul;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 3ul, content);
+ break;
+ case 4:
+ content = 0x00000000ul;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 2ul, content);
+ content = ((uint32_t) data) << 24;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 3ul, content);
+ break;
+ case 5:
+ content = 0x00000000ul;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 2ul, content);
+ content = ((uint32_t) data) << 16;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 3ul, content);
+ break;
+ case 6:
+ content = 0x00000000ul;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 2ul, content);
+ content = ((uint32_t) data) << 8;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 3ul, content);
+ break;
+ default:
+ /* LSB byte. */
+ content = 0x00000000ul;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 2ul, content);
+ content = ((uint32_t) data);
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 3ul, content);
+ break;
+ }
+
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ QueueSetContent(stack->txQueue, 4ul, content);
+
+ /* Set the size of the packet and place it in the queue. */
+ QueueSetSize(stack->txQueue, 5ul);
+ stack->txQueue = QueueEnqueue(stack->txQueue);
+}
+
+
+uint8_t RIO_readResponseDone8( RioStack_t *stack )
+{
+ uint8_t returnValue;
+ uint32_t readData;
+
+
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ /* Since there is no way of knowing where the byte will be placed,
+ OR all bytes in the reply and return it. */
+ readData = QueueGetFrontContent(stack->rxQueue, 2ul);
+ returnValue = (uint8_t) (readData >> 24);
+ returnValue |= (uint8_t) (readData >> 16);
+ returnValue |= (uint8_t) (readData >> 8);
+ returnValue |= (uint8_t) (readData);
+ readData = QueueGetFrontContent(stack->rxQueue, 3ul);
+ returnValue |= (uint8_t) (readData >> 24);
+ returnValue |= (uint8_t) (readData >> 16);
+ returnValue |= (uint8_t) (readData >> 8);
+ returnValue |= (uint8_t) (readData);
+
+ return returnValue;
+}
+
+
+
+/*******************************************************************************
+ * Local functions
+ *******************************************************************************/
+
+
+static void handleStatus(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus)
+{
+ /* Update the buffer status of the link partner. */
+ (void) ackId;
+ stack->txBufferStatus = bufferStatus;
+}
+
+
+static void handlePacketAccepted(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus)
+{
+ /* Check if an acknowledge is expected and that it is for a transmitted packet. */
+ if((stack->txAckId != stack->txAckIdWindow) && (ackId == stack->txAckId))
+ {
+ DEBUG_FRAMING_TX("ack=%i", ackId);
+ /* Acknowledge for a recently transmitted packet received. */
+ /* Remove the packet from the outbound queue and restart the transmission for
+ a new packet. */
+ stack->txQueue = QueueDequeue(stack->txQueue);
+ stack->txAckId = ACKID_INC(stack->txAckId);
+ stack->statusOutboundPacketComplete++;
+ }
+ else
+ {
+ DEBUG_FRAMING_TX("*ack=%i", ackId);
+ /* Acknowledge for an unexpected ackId or not waiting for an acknowledge. */
+ /* Link protocol violation. Discard the symbol and enter the output-error-stopped state. */
+ stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
+ stack->txCounter = 0u;
+ stack->statusOutboundErrorPacketAccepted++;
+ DEBUG_STATE("tx:error-stopped");
+ }
+
+ /* Update the buffer status of the link partner. */
+ stack->txBufferStatus = bufferStatus;
+}
+
+
+static void handlePacketRetry(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus)
+{
+ /* Check if the retried packet ackId is acceptable. */
+ if(ackId == stack->txAckId)
+ {
+ DEBUG_FRAMING_TX("retry=%u", ackId);
+ /* The request for retry is for the current packet. */
+ /* Force the transmitter to send a RESTART-FROM-RETRY symbol. */
+ stack->txState = TX_STATE_OUTPUT_RETRY_STOPPED;
+ stack->statusOutboundPacketRetry++;
+ DEBUG_STATE("tx:retry-stopped");
+ }
+ else
+ {
+ DEBUG_FRAMING_TX("*retry=%u %u", ackId, stack->txAckId);
+ /* Link protocol violation. Discard the symbol and enter the output-error-stopped state. */
+ stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
+ stack->txCounter = 0u;
+ stack->statusOutboundErrorPacketRetry++;
+ DEBUG_STATE("tx:error-stopped");
+ }
+
+ /* Update the buffer status of the link partner. */
+ stack->txBufferStatus = bufferStatus;
+}
+
+
+static void handlePacketNotAccepted(RioStack_t *stack, const uint8_t arbitrary, const uint8_t cause)
+{
+ (void) arbitrary;
+
+ /* Force the transmitter to enter output-error-stopped state. */
+ stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
+ stack->txCounter = 0u;
+
+ /* Record the type of error that caused the packet to not being accepted. */
+ switch(cause)
+ {
+ case PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID:
+ stack->statusPartnerErrorPacketAckId++;
+ break;
+ case PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC:
+ stack->statusPartnerErrorControlCrc++;
+ break;
+ case PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC:
+ stack->statusPartnerErrorPacketCrc++;
+ break;
+ case PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER:
+ stack->statusPartnerErrorIllegalCharacter++;
+ break;
+ default:
+ stack->statusPartnerErrorGeneral++;
+ break;
+ }
+
+ DEBUG_STATE("tx:error-stopped");
+}
+
+
+static void handleLinkResponse(RioStack_t *stack, const uint8_t ackId, const uint8_t portStatus)
+{
+ uint8_t window;
+ uint8_t windowReceived;
+
+
+ (void) portStatus;
+
+ /* Check if this symbols is expected. */
+ if(stack->txState == TX_STATE_OUTPUT_ERROR_STOPPED)
+ {
+ DEBUG_FRAMING_TX("link-res:%u %u %u", stack->txAckIdWindow, stack->txAckId, ackId);
+
+ /* Calculate the number of packets that has not received an acknowledge on our side and
+ on the link-partner side. */
+ window = (stack->txAckIdWindow - stack->txAckId) & 0x1f;
+ windowReceived = (ackId - stack->txAckId) & 0x1f;
+
+ /* Check if the link-partners response is acceptable. */
+ if(windowReceived <= window)
+ {
+ /* A link-response is expected. */
+ DEBUG_STATE("tx:recover");
+
+ /* Remove entries in the queue that the link-partner has sent acknowledges for that has been lost. */
+ while(stack->txAckId != ackId)
+ {
+ stack->txQueue = QueueDequeue(stack->txQueue);
+ stack->txAckId = ACKID_INC(stack->txAckId);
+ stack->statusOutboundPacketComplete++;
+ }
+
+ /* Set the transmission window to the resend packets that has not been received. */
+ stack->txQueue = QueueWindowReset(stack->txQueue);
+ stack->txAckIdWindow = ackId;
+ stack->txFrameState = TX_FRAME_START;
+
+ /* Set the transmitter back into normal operation. */
+ stack->txState = TX_STATE_LINK_INITIALIZED;
+ }
+ else
+ {
+ /* The link-partner response is unacceptable. */
+ /* Recovery is not possible. */
+ stack->txState = TX_STATE_UNINITIALIZED;
+ ASSERT0("Unrecoverable protocol error.");
+ }
+ }
+ else
+ {
+ /* Not expecting a link-response. */
+ /* Just discard this symbol. */
+ /* REMARK: Add status counter here??? */
+ }
+}
+
+
+static void handleStartOfPacket(RioStack_t *stack)
+{
+ /* Check if a packet is already started. */
+ if(stack->rxCounter != 0u)
+ {
+ /* Packet has already started. */
+ /* This indicates an implicit end-of-packet symbol and signals the previous packet as ready. */
+ DEBUG_FRAMING_RX("cont=%u", stack->rxAckId);
+
+ /* Check the packet crc. */
+ if(stack->rxCrc == 0x0000u)
+ {
+ /* The packet has a correct CRC. */
+
+ /* Check if the packet is long enough to contain a complete packet. */
+ if(stack->rxCounter > 3u)
+ {
+ /* Packet long enough to process. */
+
+ /* Process the newly received packet and start a new one. */
+ handleNewPacketEnd(stack);
+ handleNewPacketStart(stack);
+ }
+ else
+ {
+ /* The packet has a valid CRC but is too short. */
+ /* Packet error. Enter input-error-stopped state. */
+ stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
+ stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
+ stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_GENERAL;
+ stack->statusInboundErrorGeneral++;
+ DEBUG_STATE("rx:error-stopped");
+ }
+ }
+ else
+ {
+ /* The packet has an invalid CRC. */
+ /* Packet error. Enter input-error-stopped state. */
+ stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
+ stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
+ stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
+ stack->statusInboundErrorPacketCrc++;
+ DEBUG_STATE("rx:error-stopped");
+ }
+ }
+ else
+ {
+ /* Packet has not already started. */
+ DEBUG_FRAMING_RX("start=%u", stack->rxAckId);
+ handleNewPacketStart(stack);
+ }
+}
+
+
+static void handleEndOfPacket(RioStack_t *stack)
+{
+ DEBUG_FRAMING_RX("end=%u", stack->rxAckId);
+
+ /* Check if the CRC is correct. */
+ if(stack->rxCrc == 0x0000u)
+ {
+ /* The packet has a correct CRC. */
+
+ /* Check if the packet is long enough to contain a complete packet. */
+ if(stack->rxCounter > 3u)
+ {
+ /* Packet long enough to process. */
+
+ /* Process the newly received packet. */
+ handleNewPacketEnd(stack);
+ }
+ else
+ {
+ /* The packet has a valid CRC but is too short. */
+ /* Packet error. Enter input-error-stopped state. */
+ stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
+ stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
+ stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_GENERAL;
+ stack->statusInboundErrorGeneral++;
+ DEBUG_STATE("rx:error-stopped");
+ }
+ }
+ else
+ {
+ /* The packet has an invalid CRC. */
+ /* Packet error. Enter input-error-stopped state. */
+ stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
+ stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
+ stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
+ stack->statusInboundErrorPacketCrc++;
+ DEBUG_STATE("rx:error-stopped");
+ }
+}
+
+
+static void handleNewPacketStart(RioStack_t *stack)
+{
+ /* Check if there are buffers available to store the new frame. */
+ if (QueueAvailable(stack->rxQueue) > 0u)
+ {
+ /* There are buffers available to accept the new packet. */
+
+ /* Update the reception counter to indicate the frame has started. */
+ stack->rxCounter = 1;
+ }
+ else
+ {
+ /* There are no buffers available. */
+ /* Go to input retry stopped state. */
+ DEBUG_FRAMING_RX("retry=%u", stack->rxAckId);
+ stack->statusInboundPacketRetry++;
+ stack->txState = TX_STATE_SEND_PACKET_RETRY;
+ stack->rxState = RX_STATE_INPUT_RETRY_STOPPED;
+ DEBUG_STATE("rx:retry-stopped");
+ }
+}
+
+
+static void handleNewPacketEnd(RioStack_t *stack)
+{
+ uint32_t *packet;
+ uint32_t ftype;
+ uint32_t transaction;
+
+
+ /* Save the size of the packet. */
+ QueueSetSize(stack->rxQueue, (uint32_t)stack->rxCounter - (uint32_t)1ul);
+
+ /* Get the packet and information about its type. */
+ packet = QueueGetBackBuffer(stack->rxQueue);
+ ftype = FTYPE_GET(packet);
+ transaction = TRANSACTION_GET(packet);
+
+#ifdef RIO_TRANSPARENT
+ /* Always forward the packet to the top of the stack. */
+ stack->rxQueue = QueueEnqueue(stack->rxQueue);
+#else
+ /* Check if the packet should be forwarded to the top of the stack. */
+ if ((QueueGetBackSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_READ_REQUEST_SIZE) &&
+ (ftype == FTYPE_MAINTENANCE) && (transaction == TRANSACTION_MAINT_READ_REQUEST))
+ {
+ /* Received maintenance read request. */
+ /* Send a maintenance read response. This packet is aimed at the stack, it should
+ not be forwarded. */
+ /* Note that only single word accesses are supported. */
+ RIO_sendMaintenanceReadResponse(stack, SRCID_GET(packet),TID_GET(packet), 0xff,
+ RIO_readConfig(stack, CONFIG_OFFSET_GET(packet)));
+ }
+ else if ((QueueGetBackSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_WRITE_REQUEST_SIZE) &&
+ (ftype == FTYPE_MAINTENANCE) && (transaction == TRANSACTION_MAINT_WRITE_REQUEST))
+ {
+ /* Received maintenance write request. */
+ /* Send a maintenance write response. This packet is aimed at the stack, it should
+ not be forwarded. */
+ /* Note that only single word accesses are supported. */
+ RIO_writeConfig(stack, CONFIG_OFFSET_GET(packet),
+ DOUBLE_WORD_MSB_GET(packet, 0) | DOUBLE_WORD_LSB_GET(packet, 0));
+ RIO_sendMaintenanceWriteResponse(stack, SRCID_GET(packet), TID_GET(packet), 0xff);
+ }
+ else
+ {
+ /* Forward this packet to the top of the stack. */
+ stack->rxQueue = QueueEnqueue(stack->rxQueue);
+ }
+#endif
+ /* Reset the reception counter. */
+ stack->rxCounter = 0u;
+
+ /* Update the ackId for the receiver. */
+ stack->rxAckId = ACKID_INC(stack->rxAckId);
+
+ /* Update status counter. */
+ stack->statusInboundPacketComplete++;
+}
+
+
+static void handleLinkRequest(RioStack_t *stack, uint8_t cmd)
+{
+ /* Check the command of the link-request. */
+ if(cmd == LINK_REQUEST_INPUT_STATUS)
+ {
+ /* Input-status requested. */
+ /* Return input port status. */
+
+ /* Force the transmitter to send a link-response-symbol. */
+ stack->txState = TX_STATE_SEND_LINK_RESPONSE;
+ }
+ else if(cmd == LINK_REQUEST_RESET_DEVICE)
+ {
+ /* Reset-device requested. */
+ /* REMARK: Support this??? */
+ }
+ else
+ {
+ /* Unrecognized command. */
+ /* Dont do anything. */
+ }
+
+ /* Always cancel an ongoing frame when a link-request has been received. */
+ stack->rxCounter = 0;
+
+ /* Receiving this indicates the link partner having encountered a potential problem. */
+ /* Count the number of times this happens. */
+ stack->statusPartnerLinkRequest++;
+}
+
+
+static void sendMaintenanceReadRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t offset)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x0018ul << 16;
+ content |= (uint32_t) destid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 0ul, content);
+
+ /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
+ content = ((uint32_t) srcid) << 16;
+ content |= (uint32_t) 0x08ul << 8;
+ content |= (uint32_t) tid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 1ul, content);
+
+ /* hopcount(7:0)|configOffset(20:0)|wdptr|reserved(1:0) */
+ content = ((uint32_t) hopCount) << 24;
+ content |= offset & (uint32_t) 0x00fffffcul;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 2ul, content);
+
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ QueueSetContent(stack->txQueue, 3ul, content);
+
+ /* Set the size of the packet and place it in the queue. */
+ QueueSetSize(stack->txQueue, 4ul);
+ stack->txQueue = QueueEnqueue(stack->txQueue);
+}
+
+static void receiveMaintenanceReadRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *offset)
+{
+ uint32_t *packet;
+
+
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ packet = QueueGetFrontBuffer(stack->rxQueue);
+
+ *destid = DESTID_GET(packet);
+ *srcid = SRCID_GET(packet);
+ *tid = TID_GET(packet);
+ *hopCount = HOP_GET(packet);
+ *offset = CONFIG_OFFSET_GET(packet);
+}
+
+static void sendMaintenanceReadResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t data)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ /* REMARK: What should we do if there are no buffers available to send the packet... */
+ ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = (uint32_t)0x0018ul << 16;
+ content |= (uint32_t) destid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 0ul, content);
+
+ /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
+ content = (uint32_t) srcid << 16;
+ content |= (uint32_t) 0x28ul << 8;
+ content |= (uint32_t) tid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 1ul, content);
+
+ /* hopcount(7:0)|reserved(23:0) */
+ content = (uint32_t) (hopCount << 24);
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 2ul, content);
+
+ /* double-word 0 */
+ /* Send the data in both words since this function cannot know the offset the request was sent to. */
+ content = data;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 3ul, content);
+ content = data;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 4ul, content);
+
+ /* crc(15:0)|pad(15:0) */
+ content = (uint32_t)crc << 16;
+ QueueSetContent(stack->txQueue, 5ul, content);
+
+ /* Set the size of the packet and place it in the queue. */
+ QueueSetSize(stack->txQueue, 6ul);
+ stack->txQueue = QueueEnqueue(stack->txQueue);
+}
+
+static void receiveMaintenanceReadResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *data)
+{
+ uint32_t *packet;
+
+
+ ASSERT((data != NULL), "Buffer is not allocated.");
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ packet = QueueGetFrontBuffer(stack->rxQueue);
+
+ *destid = DESTID_GET(packet);
+ *srcid = SRCID_GET(packet);
+ *tid = TID_GET(packet);
+ *hopCount = HOP_GET(packet);
+ *data = DOUBLE_WORD_MSB_GET(packet, 0) | DOUBLE_WORD_LSB_GET(packet, 0);
+}
+
+static void sendMaintenanceWriteRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t offset, const uint32_t data )
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x0018ul << 16;
+ content |= (uint32_t) destid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 0ul, content);
+
+ /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
+ content = ((uint32_t) srcid) << 16;
+ content |= (uint32_t)0x18ul << 8;
+ content |= (uint32_t) tid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 1ul, content);
+
+ /* hopcount(7:0)|configOffset(20:0)|wdptr|reserved(1:0) */
+ content = ((uint32_t) hopCount) << 24;
+ content |= offset & (uint32_t)0x00fffffcul;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 2ul, content);
+
+ /* double-word 0 */
+ /* Note that both words are filled in to avoid looking at the offset. The receiver will not
+ look at the other part anyway. The standard does not say anything about the value of the padding. */
+ content = data;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 3ul, content);
+ content = data;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 4ul, content);
+
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ QueueSetContent(stack->txQueue, 5ul, content);
+
+ /* Set the size of the packet and place it in the queue. */
+ QueueSetSize(stack->txQueue, 6ul);
+ stack->txQueue = QueueEnqueue(stack->txQueue);
+}
+
+static void receiveMaintenanceWriteRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *offset, uint32_t *data )
+{
+ uint32_t *packet;
+
+
+ ASSERT((data != NULL), "Buffer is not allocated.");
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ packet = QueueGetFrontBuffer(stack->rxQueue);
+
+ *destid = DESTID_GET(packet);
+ *srcid = SRCID_GET(packet);
+ *tid = TID_GET(packet);
+ *hopCount = HOP_GET(packet);
+ *offset = CONFIG_OFFSET_GET(packet);
+ *data = DOUBLE_WORD_MSB_GET(packet, 0) | DOUBLE_WORD_LSB_GET(packet, 0);
+}
+
+static void sendMaintenanceWriteResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ /* REMARK: What should we do if there are no buffers available to send the packet... */
+ ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = (uint32_t)0x0018ul << 16;
+ content |= (uint32_t) destid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 0ul, content);
+
+ /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
+ content = (uint32_t) srcid << 16;
+ content |= (uint32_t)0x38ul << 8;
+ content |= (uint32_t) tid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 1ul, content);
+
+ /* hopcount(7:0)|reserved(23:0) */
+ content = hopCount << 24;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 2ul, content);
+
+ /* crc(15:0)|pad(15:0) */
+ content = (uint32_t)crc << 16;
+ QueueSetContent(stack->txQueue, 3ul, content);
+
+ /* Set the size of the packet and place it in the queue. */
+ QueueSetSize(stack->txQueue, 4ul);
+ stack->txQueue = QueueEnqueue(stack->txQueue);
+}
+
+static void receiveMaintenanceWriteResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount)
+{
+ uint32_t *packet;
+
+
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ packet = QueueGetFrontBuffer(stack->rxQueue);
+
+ *destid = DESTID_GET(packet);
+ *srcid = SRCID_GET(packet);
+ *tid = TID_GET(packet);
+ *hopCount = HOP_GET(packet);
+}
+
+/* REMARK: Use a packet pointer instead of using the QueueSetContent... */
+static void sendNwrite( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer,
+ const uint8_t ack)
+{
+ uint32_t content;
+ uint32_t size;
+ uint16_t wrsize = wrsizeGet(address, bufferSize);
+
+
+ ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
+ ASSERT((wrsize != 0xffff), "Write access unsupported by protocol.");
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = ((uint32_t)0x0015ul) << 16;
+ content |= (uint32_t)destid;
+ QueueSetContent(stack->txQueue, 0ul, content);
+
+ /* sourceId(15:0)|transaction(3:0)|wrsize(3:0)|srcTID(7:0) */
+ content = ((uint32_t) srcid) << 16;
+ if(ack == 0u)
+ {
+ /* Send NWRITE. */
+ content |= (uint32_t) TRANSACTION_WRITE_NWRITE << 12;
+ }
+ else
+ {
+ /* Send NWRITE_R. */
+ content |= (uint32_t) TRANSACTION_WRITE_NWRITER << 12;
+ }
+ content |= (uint32_t) (wrsize & 0x0f00);
+ content |= (uint32_t) tid;
+ QueueSetContent(stack->txQueue, 1ul, content);
+
+ /* address(28:0)|wdptr|xamsbs(1:0) */
+ /* wrsize also contains wdptr in the lower nibble. */
+ /* REMARK: Note that xamsbs cannot be used if the address is a word. If the 2 msb bits in the
+ 34-bit address should be used, another mechanism to set it should be used. */
+ content = (address & 0xfffffff8ul);
+ content |= ((uint32_t) (wrsize & 0x000f)) << 2;
+ QueueSetContent(stack->txQueue, 2ul, content);
+
+ /* Place data buffer into the payload of the packet. */
+ size = setPacketPayload(QueueGetBackBuffer(stack->txQueue), 12, address & 0x7, bufferSize, buffer);
+
+ /* Set the size of the packet and place it in the queue. */
+ QueueSetSize(stack->txQueue, size+1);
+ stack->txQueue = QueueEnqueue(stack->txQueue);
+}
+
+static uint16_t receiveNwrite( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint32_t *address, const uint16_t dataLength, uint8_t *data )
+{
+ uint32_t *packet;
+ uint8_t offset;
+ uint16_t size;
+ uint8_t wrsize;
+ uint8_t wdptr;
+
+
+ ASSERT((data != NULL), "Buffer is not allocated.");
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ packet = QueueGetFrontBuffer(stack->rxQueue);
+
+ wrsize = WRSIZE_GET(packet);
+ wdptr = WDPTR_GET(packet);
+ wrsizeToOffset(wrsize, wdptr, &offset, &size);
+
+ *destid = DESTID_GET(packet);
+ *srcid = SRCID_GET(packet);
+ *tid = TID_GET(packet);
+ *address = ADDRESS_GET(packet) | offset;
+
+ if(size > 16)
+ {
+ /* Remove header and crc from the size count. */
+ size = ((QueueGetFrontSize(stack->rxQueue)-4) * 4);
+ }
+
+ /* Check if there is enough room in the receiving buffer. */
+ if(size <= dataLength)
+ {
+ return getPacketPayload(packet, 12, offset, size, data);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static void sendNread( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint32_t address, const uint16_t dataLength)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+ uint16_t rdsize = rdsizeGet(address, dataLength);
+
+
+ ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
+ ASSERT((rdsize != 0xffff), "Read access unsupported by protocol.");
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = ((uint32_t) 0x0012ul) << 16;
+ content |= (uint32_t) destid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 0ul, content);
+
+ /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
+ content = ((uint32_t) srcid) << 16;
+ content |= ((uint32_t) TRANSACTION_REQUEST_NREAD) << 12;
+ content |= (uint32_t) (rdsize & 0x0f00);
+ content |= (uint32_t) tid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 1ul, content);
+
+ /* address(28:0)|wdptr|xamsbs(1:0) */
+ /* rdsize also contains wdptr in the lower nibble. */
+ /* REMARK: Note that xamsbs cannot be used if the address is a word. If the 2 msb bits in the
+ 34-bit address should be used, another mechanism to set it should be used. */
+ content = address & 0xfffffff8ul;
+ content |= ((uint32_t) (rdsize & 0x000f)) << 2;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 2ul, content);
+
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ QueueSetContent(stack->txQueue, 3ul, content);
+
+ /* Set the size of the packet and place it in the queue. */
+ QueueSetSize(stack->txQueue, 4ul);
+ stack->txQueue = QueueEnqueue(stack->txQueue);
+}
+
+static void receiveNread( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint32_t *address, uint16_t *dataLength)
+{
+ uint32_t *packet;
+ uint8_t offset;
+ uint16_t size;
+ uint8_t rdsize;
+ uint8_t wdptr;
+
+
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ packet = QueueGetFrontBuffer(stack->rxQueue);
+
+ rdsize = WRSIZE_GET(packet);
+ wdptr = WDPTR_GET(packet);
+ rdsizeToOffset(rdsize, wdptr, &offset, &size);
+
+ *destid = DESTID_GET(packet);
+ *srcid = SRCID_GET(packet);
+ *tid = TID_GET(packet);
+ *address = ADDRESS_GET(packet) | offset;
+ *dataLength = size;
+}
+
+static void sendResponseDonePayload( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer)
+{
+ uint32_t content;
+ uint32_t size;
+
+
+ ASSERT((buffer != NULL), "Buffer is not allocated.");
+ ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x001dul << 16;
+ content |= (uint32_t) destid;
+ QueueSetContent(stack->txQueue, 0ul, content);
+
+ /* sourceId(15:0)|transaction(3:0)|status(3:0)|targetTID(7:0) */
+ content = ((uint32_t) srcid) << 16;
+ content |= ((uint32_t) TRANSACTION_RESPONSE_WITH_PAYLOAD) << 12;
+ content |= (uint32_t) tid;
+ QueueSetContent(stack->txQueue, 1ul, content);
+
+ /* Place data buffer into the payload of the packet. */
+ size = setPacketPayload(QueueGetBackBuffer(stack->txQueue), 8, address & 0x7, bufferSize, buffer);
+
+ /* Set the size of the packet and place it in the queue. */
+ QueueSetSize(stack->txQueue, size+1);
+ stack->txQueue = QueueEnqueue(stack->txQueue);
+}
+
+
+static uint16_t receiveResponseDonePayload( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ const uint32_t address, const uint16_t dataLength, uint8_t *data )
+{
+ uint32_t *packet;
+
+
+ ASSERT((data != NULL), "Buffer is not allocated.");
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ packet = QueueGetFrontBuffer(stack->rxQueue);
+
+ *destid = DESTID_GET(packet);
+ *srcid = SRCID_GET(packet);
+ *tid = TID_GET(packet);
+
+ return getPacketPayload(packet, 8, address & 0x7, dataLength, data);
+}
+
+
+static void sendResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t status)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = (uint32_t)0x001dul << 16;
+ content |= destid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 0ul, content);
+
+ /* sourceId(15:0)|transaction(3:0)|status(3:0)|targetTID(7:0) */
+ content = (uint32_t)srcid << 16;
+ content |= ((uint32_t)status & (uint32_t)0x0ful) << 8;
+ content |= tid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 1ul, content);
+
+ /* crc(15:0)|pad(15:0) */
+ content = (uint32_t)crc << 16;
+ QueueSetContent(stack->txQueue, 2ul, content);
+
+ /* Set the size of the packet and place it in the queue. */
+ QueueSetSize(stack->txQueue, 3ul);
+ stack->txQueue = QueueEnqueue(stack->txQueue);
+}
+
+
+static void receiveResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid)
+{
+ uint32_t *packet;
+
+
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ packet = QueueGetFrontBuffer(stack->rxQueue);
+
+ *destid = DESTID_GET(packet);
+ *srcid = SRCID_GET(packet);
+ *tid = TID_GET(packet);
+}
+
+
+static void sendDoorbell( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint16_t info )
+{
+ uint32_t content;
+ uint16_t crc;
+
+
+ ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x001aul << 16;
+ content |= (uint32_t) destid;
+ crc = Crc32(content, 0xffffu);
+ QueueSetContent(stack->txQueue, 0ul, content);
+
+ /* sourceId(15:0)|rsrv(7:0)|srcTID(7:0) */
+ content = ((uint32_t) srcid) << 16;
+ content |= (uint32_t) tid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 1ul, content);
+
+ /* infoMSB(7:0)|infoLSB(7:0)|crc(15:0) */
+ content = ((uint32_t) info) << 16;
+ crc = Crc16(info, crc);
+ content |= crc;
+ QueueSetContent(stack->txQueue, 2ul, content);
+
+ /* Set the size of the packet and place it in the queue. */
+ QueueSetSize(stack->txQueue, 3ul);
+ stack->txQueue = QueueEnqueue(stack->txQueue);
+}
+
+
+static void receiveDoorbell( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint16_t *info)
+{
+ uint32_t *packet;
+
+
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ packet = QueueGetFrontBuffer(stack->rxQueue);
+
+ *destid = DESTID_GET(packet);
+ *srcid = SRCID_GET(packet);
+ *tid = TID_GET(packet);
+ *info = INFO_GET(packet);
+}
+
+
+static void sendMessage( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
+ const uint16_t bufferSize, const uint8_t* bufferData)
+{
+ uint32_t content;
+ uint32_t size;
+
+
+ ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
+ ASSERT((bufferSize <= 256), "Packet sizes larger than 256 are currently unsupported.");
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = ((uint32_t) 0x001bul) << 16;
+ content |= (uint32_t) destid;
+ QueueSetContent(stack->txQueue, 0ul, content);
+
+ /* sourceId(15:0)|msglen(3:0)|ssize(3:0)|letter(1:0|mbox(1:0)|xmbox(3:0) */
+ content = ((uint32_t) srcid) << 16;
+ if(bufferSize <= 8u)
+ {
+ content |= ((uint32_t) 0x09ul) << 8;
+ }
+ else if(bufferSize <= 16u)
+ {
+ content |= ((uint32_t) 0x0aul) << 8;
+ }
+ else if(bufferSize <= 32u)
+ {
+ content |= ((uint32_t) 0x0bul) << 8;
+ }
+ else if(bufferSize <= 64u)
+ {
+ content |= ((uint32_t) 0x0cul) << 8;
+ }
+ else if(bufferSize <= 128u)
+ {
+ content |= ((uint32_t) 0x0dul) << 8;
+ }
+ else
+ {
+ content |= ((uint32_t) 0x0eul) << 8;
+ }
+ content |= ((uint32_t)mailbox & (uint32_t)0xfu) << 4;
+ content |= ((uint32_t)mailbox) >> 4;
+ QueueSetContent(stack->txQueue, 1ul, content);
+
+ /* Place data buffer into the payload of the packet. */
+ size = setPacketPayload(QueueGetBackBuffer(stack->txQueue), 8, 0, bufferSize, bufferData);
+
+ /* Set the size of the packet and place it in the queue. */
+ QueueSetSize(stack->txQueue, size+1);
+ stack->txQueue = QueueEnqueue(stack->txQueue);
+}
+
+static uint16_t receiveMessage( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox,
+ const uint16_t dataLength, uint8_t *data )
+{
+ uint32_t *packet;
+ uint32_t size;
+
+
+ ASSERT((data != NULL), "Buffer is not allocated.");
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ /* Get a pointer to the packet. */
+ packet = QueueGetFrontBuffer(stack->rxQueue);
+
+ /* The higher mailbox numbers are used with messages that cannot be multi-packets. */
+ *destid = DESTID_GET(packet);
+ *srcid = SRCID_GET(packet);
+ *mailbox = XMBOX_GET(packet);
+ *mailbox <<= 2;
+ *mailbox |= LETTER_GET(packet);
+ *mailbox <<= 2;
+ *mailbox |= MBOX_GET(packet);
+
+ /* Calculate the number of bytes to transfer. */
+ /* Remove the header and crc from the size count. */
+ size = (QueueGetFrontSize(stack->rxQueue)-3) * 4;
+
+ /* Check if there is enough room in the receiving buffer. */
+ if(size <= dataLength)
+ {
+ return getPacketPayload(packet, 8, 0, size, data);
+ }
+ else
+ {
+ return 0;
+ }
+
+}
+
+static void sendMessageResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
+ const uint8_t status)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = (uint32_t)0x001dul << 16;
+ content |= destid;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 0ul, content);
+
+ /* sourceId(15:0)|transaction(3:0)|status(3:0)|letter(1:0|mbox(1:0)|msgseg(3:0) */
+ content = (uint32_t)srcid << 16;
+ content |= (uint32_t)0x1ul << 12;
+ content |= ((uint32_t)status & (uint32_t)0xful) << 8;
+ content |= ((uint32_t)mailbox & (uint32_t)0xful) << 4;
+ content |= ((uint32_t)mailbox) >> 4;
+ crc = Crc32(content, crc);
+ QueueSetContent(stack->txQueue, 1ul, content);
+
+ /* crc(15:0)|pad(15:0) */
+ content = (uint32_t)crc << 16;
+ QueueSetContent(stack->txQueue, 2ul, content);
+
+ /* Set the size of the packet and place it in the queue. */
+ QueueSetSize(stack->txQueue, 3ul);
+ stack->txQueue = QueueEnqueue(stack->txQueue);
+}
+
+static void receiveMessageResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox)
+{
+ uint32_t *packet;
+
+
+ ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
+
+ packet = QueueGetFrontBuffer(stack->rxQueue);
+
+ *destid = DESTID_GET(packet);
+ *srcid = SRCID_GET(packet);
+ *mailbox = XMBOX_GET(packet);
+ *mailbox <<= 2;
+ *mailbox |= LETTER_GET(packet);
+ *mailbox <<= 2;
+ *mailbox |= MBOX_GET(packet);
+}
+
+
+static uint16_t getPacketPayload(uint32_t *packet, const uint16_t payloadOffset, const uint16_t dataOffset,
+ const uint16_t dataSize, uint8_t *data)
+{
+ uint32_t content = 0;
+ uint16_t packetIndex;
+ uint16_t payloadIndex;
+ uint16_t dataIndex;
+
+
+ /* Move bytes from inbound packet queue into the user buffer. */
+ /* Long packets contain a CRC in byte 80-81, this is removed when the buffer
+ is copied. */
+ packetIndex = payloadOffset;
+ payloadIndex = 0;
+ dataIndex = 0;
+ while(dataIndex < dataSize)
+ {
+ /* Check if a new word should be read from the inbound queue. */
+ if((packetIndex & 0x3) == 0)
+ {
+ /* Get a new word. */
+ content = packet[packetIndex>>2];
+ }
+ else
+ {
+ /* Update the current word. Remove the MSB, it has already be moved
+ to the user buffer. */
+ content <<= 8;
+ }
+
+ /* Check if the current byte is CRC. */
+ if((packetIndex != 80) && (packetIndex != 81) && (payloadIndex >= dataOffset))
+ {
+ /* Not CRC. */
+ /* Move the byte to the user buffer. */
+ data[dataIndex++] = (content >> 24);
+ }
+
+ /* Increment to the next position in the packet. */
+ packetIndex++;
+ payloadIndex++;
+ }
+
+ return dataIndex;
+}
+
+
+static uint16_t setPacketPayload(uint32_t *packet, const uint16_t payloadOffset, const uint16_t dataOffset,
+ const uint16_t dataSize, const uint8_t *data)
+{
+ uint16_t crc = 0xffffu;
+ uint32_t content = 0;
+ uint16_t packetIndex;
+ uint16_t payloadIndex;
+ uint16_t dataIndex;
+
+
+ /***************************************************
+ * Calculate the CRC for the packet header.
+ ***************************************************/
+ for(packetIndex = 0; packetIndex < payloadOffset; packetIndex+=4)
+ {
+ crc = Crc32(packet[packetIndex>>2], crc);
+ }
+
+ /***************************************************
+ * Pad the data before the actual data is written.
+ ***************************************************/
+ payloadIndex = 0;
+ while(payloadIndex < dataOffset)
+ {
+ content <<= 8;
+
+ if((packetIndex & 0x3) == 3)
+ {
+ crc = Crc32(content, crc);
+ packet[packetIndex>>2] = content;
+ }
+
+ payloadIndex++;
+ packetIndex++;
+ }
+
+ /***************************************************
+ * Write content and any embedded CRC.
+ ***************************************************/
+ dataIndex = 0;
+ while(dataIndex < dataSize)
+ {
+ content <<= 8;
+
+ /* Check if CRC or content should be entered into the packet. */
+ if(packetIndex == 80)
+ {
+ /* CRC MSB. */
+ content |= crc >> 8;
+ }
+ else if(packetIndex == 81)
+ {
+ /* CRC LSB. */
+ content |= crc & 0xff;
+ }
+ else
+ {
+ /* Data content. */
+ content |= data[dataIndex++];
+ payloadIndex++;
+ }
+
+ if((packetIndex & 0x3) == 3)
+ {
+ crc = Crc32(content, crc);
+ packet[packetIndex>>2] = content;
+ }
+
+ packetIndex++;
+ }
+
+ /***************************************************
+ * Pad the data to an even double word.
+ ***************************************************/
+ while((payloadIndex & 0x7) != 0)
+ {
+ content <<= 8;
+
+ if((packetIndex & 0x3) == 3)
+ {
+ crc = Crc32(content, crc);
+ packet[packetIndex>>2] = content;
+ }
+
+ packetIndex++;
+ payloadIndex++;
+ }
+
+ /***************************************************
+ * Write the CRC into the packet.
+ ***************************************************/
+ if((packetIndex & 0x3) == 0)
+ {
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ }
+ else
+ {
+ /* double-wordN-LSB|crc(15:0) */
+ content &= 0x0000ffff;
+ crc = Crc16(content, crc);
+ content <<= 16;
+ content |= crc;
+ }
+ packet[packetIndex>>2] = content;
+
+ return (packetIndex>>2);
+}
+
+
+/* \note See the RapidIO standard part1 table 4-4 for details about
+ * {address, size}->{wdptr, wrsize} mapping.
+ */
+static uint16_t rdsizeGet(const uint32_t address, const uint16_t size)
+{
+ uint8_t wdptr;
+ uint8_t rdsize;
+
+
+ switch(size/8)
+ {
+ case 0:
+ /**************************************************************
+ * Sub double-word access.
+ **************************************************************/
+ /* REMARK: The same code as in wrsizeGet for sub
+ double-word... use it instead??? */
+ switch(size%8)
+ {
+ case 0:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 1:
+ /* Reading one byte. */
+ /* Any address is allowed. */
+ wdptr = (address >> 2) & 0x1;
+ rdsize = address & 0x3;
+ break;
+ case 2:
+ /* Reading two bytes. */
+ /* Address 0, 2, 4, 6 are valid. */
+ if((address & 0x1) == 0)
+ {
+ wdptr = (address >> 2) & 0x1;
+ rdsize = (address & 0x7) | 0x4;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 3:
+ /* Reading 3 bytes. */
+ /* Address 0 and 5 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 5))
+ {
+ wdptr = (address >> 2) & 0x1;
+ rdsize = 0x5ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 4:
+ /* Reading 4 bytes. */
+ /* Address 0 and 4 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 4))
+ {
+ wdptr = (address >> 2) & 0x1;
+ rdsize = 0x8ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 5:
+ /* Reading 5 bytes. */
+ /* Address 0 and 3 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 3))
+ {
+ wdptr = (address >> 1) & 0x1;
+ rdsize = 0x7ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 6:
+ /* Reading 6 bytes. */
+ /* Addresses 0 and 2 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 2))
+ {
+ wdptr = (address >> 1) & 0x1;
+ rdsize = 0x9ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ default:
+ /* Reading 7 bytes. */
+ /* Addresses 0 and 1 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 1))
+ {
+ wdptr = address & 0x1;
+ rdsize = 0xaul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ }
+ break;
+ case 1:
+ /* Reading 8 bytes. */
+ /* Only even double-word address are valid. */
+ if((address % 8) == 0)
+ {
+ wdptr = 0;
+ rdsize = 0xbul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 2:
+ /* Reading 16 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address % 8) == 0)
+ {
+ wdptr = 1;
+ rdsize = 0xbul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 3:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 4:
+ /* Reading 32 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 0;
+ rdsize = 0xcul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 5:
+ case 6:
+ case 7:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 8:
+ /* Reading 64 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 1;
+ rdsize = 0xcul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 9:
+ case 10:
+ case 11:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 12:
+ /* Reading 96 bytes. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 0;
+ rdsize = 0xdul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 13:
+ case 14:
+ case 15:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 16:
+ /* Reading 128 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 1;
+ rdsize = 0xdul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 17:
+ case 18:
+ case 19:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 20:
+ /* Reading 160 bytes. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 0;
+ rdsize = 0xeul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 21:
+ case 22:
+ case 23:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 24:
+ /* Reading 192 bytes. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 1;
+ rdsize = 0xeul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 25:
+ case 26:
+ case 27:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 28:
+ /* Reading 224 bytes. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 0;
+ rdsize = 0xful;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 29:
+ case 30:
+ case 31:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 32:
+ /* Reading 256 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 1;
+ rdsize = 0xful;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ default:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ }
+
+ return ((((uint16_t) rdsize) << 8) | ((uint16_t) wdptr));
+}
+
+
+void rdsizeToOffset(uint8_t rdsize, uint8_t wdptr, uint8_t *offset, uint16_t *size)
+{
+ switch(rdsize)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ *offset = wdptr << 2;
+ *offset |= rdsize;
+ *size = 1;
+ break;
+ case 4:
+ case 6:
+ *offset = wdptr << 2;
+ *offset |= rdsize & 0x02;
+ *size = 2;
+ break;
+ case 5:
+ *offset = wdptr * 5;
+ *size = 3;
+ break;
+ case 8:
+ *offset = wdptr * 4;
+ *size = 4;
+ break;
+ case 7:
+ *offset = wdptr * 3;
+ *size = 5;
+ break;
+ case 9:
+ *offset = wdptr * 2;
+ *size = 6;
+ break;
+ case 10:
+ *offset = wdptr * 1;
+ *size = 7;
+ break;
+ case 11:
+ *offset = 0;
+ *size = 8 + 8*wdptr;
+ break;
+ case 12:
+ *offset = 0;
+ *size = 32 + 32*wdptr;
+ break;
+ case 13:
+ *offset = 0;
+ *size = 96 + 32*wdptr;
+ break;
+ case 14:
+ *offset = 0;
+ *size = 160 + 32*wdptr;
+ break;
+ case 15:
+ *offset = 0;
+ *size = 224 + 32*wdptr;
+ break;
+ }
+}
+
+
+static uint16_t wrsizeGet(const uint32_t address, const uint16_t size)
+{
+ uint8_t wdptr;
+ uint8_t wrsize;
+
+
+ switch(size/8)
+ {
+ case 0:
+ /**************************************************************
+ * Sub double-word access.
+ **************************************************************/
+ switch(size%8)
+ {
+ case 0:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ break;
+ case 1:
+ /* Writing one byte. */
+ /* Any address is allowed. */
+ wdptr = (address >> 2) & 0x1;
+ wrsize = address & 0x3;
+ break;
+ case 2:
+ /* Writing two bytes. */
+ /* Address 0, 2, 4, 6 are valid. */
+ if((address & 0x1) == 0)
+ {
+ wdptr = (address >> 2) & 0x1;
+ wrsize = (address & 0x7) | 0x4;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 3:
+ /* Writing 3 bytes. */
+ /* Address 0 and 5 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 5))
+ {
+ wdptr = (address >> 2) & 0x1;
+ wrsize = 0x5ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 4:
+ /* Writing 4 bytes. */
+ /* Address 0 and 4 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 4))
+ {
+ wdptr = (address >> 2) & 0x1;
+ wrsize = 0x8ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 5:
+ /* Writing 5 bytes. */
+ /* Address 0 and 3 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 3))
+ {
+ wdptr = (address >> 1) & 0x1;
+ wrsize = 0x7ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 6:
+ /* Writing 6 bytes. */
+ /* Addresses 0 and 2 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 2))
+ {
+ wdptr = (address >> 1) & 0x1;
+ wrsize = 0x9ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ default:
+ /* Writing 7 bytes. */
+ /* Addresses 0 and 1 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 1))
+ {
+ wdptr = address & 0x1;
+ wrsize = 0xaul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ }
+ break;
+ case 1:
+ /* Writing 8 bytes. */
+ /* Only even double-word address are valid. */
+ if((address % 8) == 0)
+ {
+ wdptr = 0;
+ wrsize = 0xbul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 2:
+ /* Writing 16 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address % 8) == 0)
+ {
+ wdptr = 1;
+ wrsize = 0xbul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 3:
+ case 4:
+ /* Writing 32 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 0;
+ wrsize = 0xcul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ /* Writing 64 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 1;
+ wrsize = 0xcul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ /* Writing 128 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 1;
+ wrsize = 0xdul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ case 22:
+ case 23:
+ case 24:
+ case 25:
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ case 30:
+ case 31:
+ case 32:
+ /* Writing 256 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 1;
+ wrsize = 0xful;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ default:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ break;
+ }
+
+ return ((((uint16_t) wrsize) << 8) | ((uint16_t) wdptr));
+}
+
+
+void wrsizeToOffset(uint8_t wrsize, uint8_t wdptr, uint8_t *offset, uint16_t *size)
+{
+ switch(wrsize)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ *offset = wdptr << 2;
+ *offset |= wrsize;
+ *size = 1;
+ break;
+ case 4:
+ case 6:
+ *offset = wdptr << 2;
+ *offset |= wrsize & 0x02;
+ *size = 2;
+ break;
+ case 5:
+ *offset = wdptr * 5;
+ *size = 3;
+ break;
+ case 8:
+ *offset = wdptr * 4;
+ *size = 4;
+ break;
+ case 7:
+ *offset = wdptr * 3;
+ *size = 5;
+ break;
+ case 9:
+ *offset = wdptr * 2;
+ *size = 6;
+ break;
+ case 10:
+ *offset = wdptr * 1;
+ *size = 7;
+ break;
+ case 11:
+ *offset = 0;
+ *size = 8 + 8*wdptr;
+ break;
+ case 12:
+ *offset = 0;
+ *size = 32 + 32*wdptr;
+ break;
+ case 13:
+ *offset = 0;
+ *size = 128*wdptr;
+ break;
+ case 14:
+ *offset = 0;
+ *size = 0;
+ break;
+ case 15:
+ *offset = 0;
+ *size = 256*wdptr;
+ break;
+ }
+}
+
+
+static RioSymbol CreateControlSymbol( const uint8_t stype0,
+ const uint8_t parameter0, const uint8_t parameter1,
+ const uint8_t stype1, const uint8_t cmd)
+{
+ RioSymbol s;
+
+ s.type = RIO_SYMBOL_TYPE_CONTROL;
+
+ s.data = ((uint32_t)stype0 & (uint32_t)0x07ul) << 21;
+ s.data |= ((uint32_t)parameter0 & (uint32_t)0x1ful) << 16;
+ s.data |= ((uint32_t)parameter1 & (uint32_t)0x1ful) << 11;
+ s.data |= ((uint32_t)stype1 & (uint32_t)0x07ul) << 8;
+ s.data |= ((uint32_t)cmd & (uint32_t)0x7ul) << 5;
+ s.data |= Crc5(s.data, 0x1fu);
+
+ return s;
+}
+
+
+static uint8_t Crc5( const uint32_t data, const uint8_t crc)
+{
+ static const uint8_t crcTable[] = {
+ 0x00u, 0x15u, 0x1fu, 0x0au, 0x0bu, 0x1eu, 0x14u, 0x01u,
+ 0x16u, 0x03u, 0x09u, 0x1cu, 0x1du, 0x08u, 0x02u, 0x17u,
+ 0x19u, 0x0cu, 0x06u, 0x13u, 0x12u, 0x07u, 0x0du, 0x18u,
+ 0x0fu, 0x1au, 0x10u, 0x05u, 0x04u, 0x11u, 0x1bu, 0x0eu
+ };
+
+ uint8_t result;
+ uint8_t index;
+
+ result = crc;
+ index = (uint8_t)((data >> 19) & (uint32_t)0x1ful) ^ result;
+ result = crcTable[index];
+ index = (uint8_t)((data >> 14) & (uint32_t)0x1ful) ^ result;
+ result = crcTable[index];
+ index = (uint8_t)((data >> 9) & (uint32_t)0x1ful) ^ result;
+ result = crcTable[index];
+ index = (uint8_t)((data >> 4) & (uint32_t)0x1eul) ^ result;
+ result = crcTable[index];
+
+ return result;
+}
+
+
+static uint16_t Crc16( const uint16_t data, const uint16_t crc)
+{
+ static const uint16_t crcTable[] = {
+ 0x0000u, 0x1021u, 0x2042u, 0x3063u, 0x4084u, 0x50a5u, 0x60c6u, 0x70e7u,
+ 0x8108u, 0x9129u, 0xa14au, 0xb16bu, 0xc18cu, 0xd1adu, 0xe1ceu, 0xf1efu,
+ 0x1231u, 0x0210u, 0x3273u, 0x2252u, 0x52b5u, 0x4294u, 0x72f7u, 0x62d6u,
+ 0x9339u, 0x8318u, 0xb37bu, 0xa35au, 0xd3bdu, 0xc39cu, 0xf3ffu, 0xe3deu,
+ 0x2462u, 0x3443u, 0x0420u, 0x1401u, 0x64e6u, 0x74c7u, 0x44a4u, 0x5485u,
+ 0xa56au, 0xb54bu, 0x8528u, 0x9509u, 0xe5eeu, 0xf5cfu, 0xc5acu, 0xd58du,
+ 0x3653u, 0x2672u, 0x1611u, 0x0630u, 0x76d7u, 0x66f6u, 0x5695u, 0x46b4u,
+ 0xb75bu, 0xa77au, 0x9719u, 0x8738u, 0xf7dfu, 0xe7feu, 0xd79du, 0xc7bcu,
+ 0x48c4u, 0x58e5u, 0x6886u, 0x78a7u, 0x0840u, 0x1861u, 0x2802u, 0x3823u,
+ 0xc9ccu, 0xd9edu, 0xe98eu, 0xf9afu, 0x8948u, 0x9969u, 0xa90au, 0xb92bu,
+ 0x5af5u, 0x4ad4u, 0x7ab7u, 0x6a96u, 0x1a71u, 0x0a50u, 0x3a33u, 0x2a12u,
+ 0xdbfdu, 0xcbdcu, 0xfbbfu, 0xeb9eu, 0x9b79u, 0x8b58u, 0xbb3bu, 0xab1au,
+ 0x6ca6u, 0x7c87u, 0x4ce4u, 0x5cc5u, 0x2c22u, 0x3c03u, 0x0c60u, 0x1c41u,
+ 0xedaeu, 0xfd8fu, 0xcdecu, 0xddcdu, 0xad2au, 0xbd0bu, 0x8d68u, 0x9d49u,
+ 0x7e97u, 0x6eb6u, 0x5ed5u, 0x4ef4u, 0x3e13u, 0x2e32u, 0x1e51u, 0x0e70u,
+ 0xff9fu, 0xefbeu, 0xdfddu, 0xcffcu, 0xbf1bu, 0xaf3au, 0x9f59u, 0x8f78u,
+ 0x9188u, 0x81a9u, 0xb1cau, 0xa1ebu, 0xd10cu, 0xc12du, 0xf14eu, 0xe16fu,
+ 0x1080u, 0x00a1u, 0x30c2u, 0x20e3u, 0x5004u, 0x4025u, 0x7046u, 0x6067u,
+ 0x83b9u, 0x9398u, 0xa3fbu, 0xb3dau, 0xc33du, 0xd31cu, 0xe37fu, 0xf35eu,
+ 0x02b1u, 0x1290u, 0x22f3u, 0x32d2u, 0x4235u, 0x5214u, 0x6277u, 0x7256u,
+ 0xb5eau, 0xa5cbu, 0x95a8u, 0x8589u, 0xf56eu, 0xe54fu, 0xd52cu, 0xc50du,
+ 0x34e2u, 0x24c3u, 0x14a0u, 0x0481u, 0x7466u, 0x6447u, 0x5424u, 0x4405u,
+ 0xa7dbu, 0xb7fau, 0x8799u, 0x97b8u, 0xe75fu, 0xf77eu, 0xc71du, 0xd73cu,
+ 0x26d3u, 0x36f2u, 0x0691u, 0x16b0u, 0x6657u, 0x7676u, 0x4615u, 0x5634u,
+ 0xd94cu, 0xc96du, 0xf90eu, 0xe92fu, 0x99c8u, 0x89e9u, 0xb98au, 0xa9abu,
+ 0x5844u, 0x4865u, 0x7806u, 0x6827u, 0x18c0u, 0x08e1u, 0x3882u, 0x28a3u,
+ 0xcb7du, 0xdb5cu, 0xeb3fu, 0xfb1eu, 0x8bf9u, 0x9bd8u, 0xabbbu, 0xbb9au,
+ 0x4a75u, 0x5a54u, 0x6a37u, 0x7a16u, 0x0af1u, 0x1ad0u, 0x2ab3u, 0x3a92u,
+ 0xfd2eu, 0xed0fu, 0xdd6cu, 0xcd4du, 0xbdaau, 0xad8bu, 0x9de8u, 0x8dc9u,
+ 0x7c26u, 0x6c07u, 0x5c64u, 0x4c45u, 0x3ca2u, 0x2c83u, 0x1ce0u, 0x0cc1u,
+ 0xef1fu, 0xff3eu, 0xcf5du, 0xdf7cu, 0xaf9bu, 0xbfbau, 0x8fd9u, 0x9ff8u,
+ 0x6e17u, 0x7e36u, 0x4e55u, 0x5e74u, 0x2e93u, 0x3eb2u, 0x0ed1u, 0x1ef0u
+ };
+
+ uint16_t result;
+ uint8_t index;
+
+ result = crc;
+ index = (uint8_t) ((data >> 8) ^ (result >> 8));
+ result = (uint16_t) (crcTable[index] ^ (uint16_t)(result << 8));
+ index = (uint8_t) ((data) ^ (result >> 8));
+ result = (uint16_t) (crcTable[index] ^ (uint16_t)(result << 8));
+
+ return result;
+}
+
+
+static uint16_t Crc32( const uint32_t data, uint16_t crc)
+{
+ crc = Crc16((uint16_t) (data >> 16), crc);
+ crc = Crc16((uint16_t) (data), crc);
+ return crc;
+}
+
+
+
+
+
+static Queue_t QueueCreate( const uint8_t size, uint32_t *buffer)
+{
+ Queue_t q;
+
+ q.size = size;
+ q.available = size;
+ q.windowSize = 0u;
+ q.windowIndex = 0u;
+ q.frontIndex = 0u;
+ q.backIndex = 0u;
+ q.buffer_p = buffer;
+
+ return q;
+}
+
+
+static uint8_t QueueAvailable( const Queue_t q)
+{
+ return q.available;
+}
+
+
+static bool_t QueueEmpty( const Queue_t q)
+{
+ return (bool_t) (q.available == q.size);
+}
+
+
+static uint8_t QueueLength( const Queue_t q)
+{
+ return q.size - q.available;
+}
+
+
+static Queue_t QueueEnqueue( Queue_t q)
+{
+ q.backIndex++;
+ if(q.backIndex == q.size)
+ {
+ q.backIndex = 0;
+ }
+ q.available--;
+ return q;
+}
+
+
+static Queue_t QueueDequeue( Queue_t q)
+{
+ q.frontIndex++;
+ if(q.frontIndex == q.size)
+ {
+ q.frontIndex = 0;
+ }
+ q.available++;
+ if(q.windowSize == 0)
+ {
+ q.windowIndex = q.frontIndex;
+ }
+ else
+ {
+ q.windowSize--;
+ }
+ return q;
+}
+
+
+static bool_t QueueWindowEmpty( const Queue_t q)
+{
+ return (bool_t) ((q.available + q.windowSize) == q.size);
+}
+
+
+static Queue_t QueueWindowReset(Queue_t q)
+{
+ q.windowIndex = q.frontIndex;
+ q.windowSize = 0;
+ return q;
+}
+
+
+static Queue_t QueueWindowNext(Queue_t q)
+{
+ q.windowIndex++;
+ if(q.windowIndex == q.size)
+ {
+ q.windowIndex = 0;
+ }
+ q.windowSize++;
+ return q;
+}
+
+
+static void QueueSetSize( Queue_t q, const uint32_t size)
+{
+ (q.buffer_p+(RIO_BUFFER_SIZE*q.backIndex))[0] = size;
+}
+
+
+static void QueueSetContent( Queue_t q, const uint32_t index, const uint32_t content)
+{
+ (q.buffer_p+(RIO_BUFFER_SIZE*q.backIndex))[index+1ul] = content;
+}
+
+
+static uint32_t QueueGetFrontSize( Queue_t q)
+{
+ return (q.buffer_p+(RIO_BUFFER_SIZE*q.windowIndex))[0];
+}
+
+
+static uint32_t QueueGetFrontContent( const Queue_t q, const uint32_t index)
+{
+ return (q.buffer_p+(RIO_BUFFER_SIZE*q.windowIndex))[index+1ul];
+}
+
+
+static uint32_t *QueueGetFrontBuffer( const Queue_t q )
+{
+ return &((q.buffer_p+(RIO_BUFFER_SIZE*q.windowIndex))[1]);
+}
+
+
+static uint32_t QueueGetBackSize( const Queue_t q)
+{
+ return (q.buffer_p+(RIO_BUFFER_SIZE*q.backIndex))[0];
+}
+
+
+static uint32_t *QueueGetBackBuffer( const Queue_t q )
+{
+ return &((q.buffer_p+(RIO_BUFFER_SIZE*q.backIndex))[1]);
+}
+
+
+#ifdef MODULE_TEST
+#include
+#define PrintS(s) \
+ { \
+ FILE *fd; \
+ fd=fopen("testspec.txt", "a"); \
+ fputs(s "\n", fd); \
+ fclose(fd); \
+ }
+
+#define TESTSTART(s) printf(s)
+#define TESTEND printf(" passed.\n");
+
+#define TESTCOND(got) \
+ if (!(got)) \
+ { \
+ printf("ERROR at line %u:%s=%u (0x%08x)\n", \
+ __LINE__, #got, (got), (got)); \
+ exit(1); \
+ }
+
+#define TESTEXPR(got, expected) \
+ if ((got)!=(expected)) \
+ { \
+ printf("ERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n", \
+ __LINE__, #got, (got), (got), (expected), (expected)); \
+ exit(1); \
+ }
+
+#define TESTSYMBOL(got, expected) testSymbol(__LINE__, #got, (got), (expected))
+
+void testSymbol(uint32_t line, char *expression, RioSymbol got, RioSymbol expected)
+{
+ if ((got).type==(expected).type)
+ {
+ switch ((got).type)
+ {
+ case RIO_SYMBOL_TYPE_ERROR:
+ case RIO_SYMBOL_TYPE_IDLE:
+ break;
+ case RIO_SYMBOL_TYPE_CONTROL:
+ if((got).data != (expected).data)
+ {
+ if(STYPE0_GET((got).data) != STYPE0_GET((expected).data))
+ {
+ printf("ERROR at line %u:STYPE0=0x%02x expected=0x%02x\n",
+ line, STYPE0_GET((got).data), STYPE0_GET((expected).data));
+ }
+ if(PARAMETER0_GET((got).data) != PARAMETER0_GET((expected).data))
+ {
+ printf("ERROR at line %u:PARAMETER0=0x%02x expected=0x%02x\n",
+ line, PARAMETER0_GET((got).data), PARAMETER0_GET((expected).data));
+ }
+ if(PARAMETER1_GET((got).data) != PARAMETER1_GET((expected).data))
+ {
+ printf("ERROR at line %u:PARAMETER1=0x%02x expected=0x%02x\n",
+ line, PARAMETER1_GET((got).data), PARAMETER1_GET((expected).data));
+ }
+ if(STYPE1_GET((got).data) != STYPE1_GET((expected).data))
+ {
+ printf("ERROR at line %u:STYPE1=0x%02x expected=0x%02x\n",
+ line, STYPE1_GET((got).data), STYPE1_GET((expected).data));
+ }
+ if(CMD_GET((got).data) != CMD_GET((expected).data))
+ {
+ printf("ERROR at line %u:CMD=0x%02x expected=0x%02x\n",
+ line, CMD_GET((got).data), CMD_GET((expected).data));
+ }
+ if(CRC5_GET((got).data) != CRC5_GET((expected).data))
+ {
+ printf("ERROR at line %u:CRC5=0x%02x expected=0x%02x\n",
+ line, CRC5_GET((got).data), CRC5_GET((expected).data));
+ }
+ exit(1);
+ }
+ break;
+ case RIO_SYMBOL_TYPE_DATA:
+ if((got).data != (expected).data)
+ {
+ printf("ERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n",
+ line, expression, (got).data, (got).data, (expected).data, (expected).data);
+ exit(1);
+ }
+ break;
+ }
+ }
+ else
+ {
+ printf("ERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n",
+ line, expression, (got).type, (got).type, (expected).type, (expected).type);
+ exit(1);
+ }
+}
+
+
+
+uint32_t testConfigWriteData;
+
+uint8_t createDoorbell(uint32_t *doorbell, uint8_t ackId, uint16_t destid, uint16_t srcId, uint8_t tid, uint16_t info)
+{
+ uint16_t crc;
+ uint32_t content;
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x001aul << 16;
+ content |= (uint32_t) destid;
+ crc = Crc32(content, 0xffffu);
+ doorbell[0] = (((uint32_t) ackId) << 27) | content;
+
+ /* sourceId(15:0)|rsrv(7:0)|srcTID(7:0) */
+ content = ((uint32_t) srcId) << 16;
+ content |= (uint32_t) tid;
+ crc = Crc32(content, crc);
+ doorbell[1] = content;
+
+ /* infoMSB(7:0)|infoLSB(7:0)|crc(15:0) */
+ content = ((uint32_t) info) << 16;
+ crc = Crc16(info, crc);
+ content |= ((uint32_t) crc);
+ doorbell[2] = content;
+
+ return 3;
+
+}
+
+uint32_t testConfigRead(RioStack_t *stack, uint32_t offset)
+{
+ switch(offset)
+ {
+ case 0:
+ return 0x80000006;
+ case 4:
+ return 0x00a100a2;
+ case 8:
+ return testConfigWriteData;
+ default:
+ return 0x00000000;
+ }
+}
+
+void testConfigWrite(RioStack_t *stack, uint32_t offset, uint32_t data)
+{
+ switch(offset)
+ {
+ case 8:
+ testConfigWriteData = data;
+ break;
+ default:
+ /* Dont do anything. */
+ break;
+ }
+}
+
+/*******************************************************************************
+ * Module test for this file.
+ *******************************************************************************/
+int32_t main(void)
+{
+ RioStack_t stack;
+ RioStackObserver_t observer;
+ uint32_t rxPacketBuffer[RIO_BUFFER_SIZE*8], txPacketBuffer[RIO_BUFFER_SIZE*8];
+ RioSymbol s, c, d;
+ int i, j, k;
+ uint16_t length;
+ uint16_t srcid;
+ uint8_t tid;
+ uint8_t hop;
+ uint8_t mailbox;
+ uint16_t info;
+ uint32_t address;
+ uint32_t data;
+ uint8_t payload8[256];
+ uint8_t payload8Expected[256];
+ uint32_t packet[69];
+ uint32_t packetLength;
+
+
+ /*************************************************************************
+ * Test prelude.
+ * Setup the RIO stack for operation.
+ *************************************************************************/
+
+ /* Setup callback handlers for config-space accesses in the implementation-
+ defined address range. */
+ observer.configRead = testConfigRead;
+ observer.configWrite = testConfigWrite;
+
+ /* Open the stack and set the port status to initialized. */
+ RIO_open(&stack, &observer, NULL,
+ RIO_BUFFER_SIZE*8, &rxPacketBuffer[0],
+ RIO_BUFFER_SIZE*8, &txPacketBuffer[0],
+ 0xb03b, 0x0000, 0x00000000, 0x0000, 0x0000, 0x0000, 0xffff);
+
+ /* Set the port timeout. */
+ RIO_portSetTimeout(&stack, 1);
+
+ /* Set the current port time. */
+ RIO_portSetTime(&stack, 0);
+
+ /* Set master enable. */
+ RIO_writeConfig(&stack,
+ PORT_GENERAL_CONTROL_CSR(EXTENDED_FEATURES_OFFSET), 0x40000000);
+
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riostack");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riostack-TC1");
+ PrintS("Description: Test link initialization and normal packet exchange.");
+ PrintS("Requirement: XXXXX");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send packets when port is uninitialized.");
+ PrintS("Result: All packets should be ignored during initialization.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC1-Step1");
+ /******************************************************************************/
+
+ /* Place a packet in the outbound queue to check that it is received once
+ the transmitter is placed in the correct state. */
+ RIO_sendDoorbell(&stack, 1, 0, 0xdeaf);
+
+ /* Check that only idle symbols are transmitted when the port has not been
+ initialied even if statuses are received. */
+ for(i = 0; i < 1024; i++)
+ {
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0));
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /*****************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Set port initialized and get symbols from the stack.");
+ PrintS("Result: Status-control-symbols should be generated each 256 symbol.");
+ PrintS("----------------------------------------------------------------------");
+ /*****************************************************************************/
+ TESTSTART("TG_riostack-TC1-Step2");
+ /*****************************************************************************/
+
+ /* Set the port status to intialized. */
+ RIO_portSetStatus(&stack, 1);
+
+ /* Set port time. */
+ RIO_portSetTime(&stack, 1);
+
+ /* Check that status-control-symbols are transmitted once every 256 symbol. */
+ for(j = 0; j < 15; j++)
+ {
+ for(i = 0; i < 255; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
+ }
+ s = RIO_portGetSymbol(&stack);
+ c = CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_NOP, 0);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Add a status-control-symbol to the receiver.");
+ PrintS("Result: Status-control-symbols should be generated each 15 symbol.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC1-Step3");
+ /*****************************************************************************/
+
+ /* Insert a status-control-symbol in the receive. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0));
+
+ /* Check that status-control-symbols are transmitted once every 16 symbol. */
+ for(i = 0; i < 15; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
+ }
+ s = RIO_portGetSymbol(&stack);
+ c = CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_NOP, 0);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 4:");
+ PrintS("Action: Add a packet to the receiver.");
+ PrintS("Result: Packet should be ignored until the link is initialized.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC1-Step4");
+ /*****************************************************************************/
+
+ /* Send a packet. Note that the start and end of the packet contains a status. */
+ packetLength = createDoorbell(packet, 0, 0, 0, 0, 0);
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_START_OF_PACKET, 0));
+ for(i = 0; i < packetLength; i++)
+ {
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ RIO_portAddSymbol(&stack, d);
+ }
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_END_OF_PACKET, 0));
+
+ /* Check that packet was not received. */
+ TESTEXPR(RIO_eventPoll(&stack), RIO_EVENT_NONE);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 5:");
+ PrintS("Action: Add four more status-control-symbols followed by one with error in ");
+ PrintS(" CRC5. Then send a packet.");
+ PrintS("Result: The receiver should remain in port initialized and packet should ");
+ PrintS(" still be ignored.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC1-Step5");
+ /*****************************************************************************/
+
+ /* Send 4 more status-control-symbols followed by one erronous. */
+ for(i = 0; i < 4; i++)
+ {
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0));
+ }
+ c = CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0);
+ c.data ^= 1;
+ RIO_portAddSymbol(&stack, c);
+
+ /* Send a packet. Note that the start and end of the packet contains status. */
+ packetLength = createDoorbell(packet, 0, 0, 0, 0, 0);
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_START_OF_PACKET, 0));
+ for(i = 0; i < packetLength; i++)
+ {
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ RIO_portAddSymbol(&stack, d);
+ }
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_END_OF_PACKET, 0));
+
+ /* Check that the packet was ignored. */
+ TESTEXPR(RIO_eventPoll(&stack), RIO_EVENT_NONE);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 6:");
+ PrintS("Action: Add six more status-control-symbols. Then send a packet.");
+ PrintS("Result: The receiver should enter link initialized and the packet should ");
+ PrintS(" be received.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC1-Step6");
+ /*****************************************************************************/
+
+ /* Send 6 more status-control-symbols. */
+ for(i = 0; i < 6; i++)
+ {
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0));
+ }
+
+ /* Send a packet and check that it is accepted. */
+ /* The ackId on receiver in testobject is updated when this has been transmitted. */
+ packetLength = createDoorbell(packet, 0, 0, 0, 0, 0);
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_START_OF_PACKET, 0));
+ for(i = 0; i < packetLength; i++)
+ {
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ RIO_portAddSymbol(&stack, d);
+ }
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_END_OF_PACKET, 0));
+
+ /* Check that the packet is received. */
+ TESTEXPR(RIO_eventPoll(&stack), RIO_EVENT_DOORBELL);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 7:");
+ PrintS("Action: Get symbols from transmitter.");
+ PrintS("Result: Status-control-symbols should still be generated each 15 symbol ");
+ PrintS("until a total of 15 status-control-symbols has been transmitted. Once these ");
+ PrintS("has been transmitted, the transmitter will be link initialized.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC1-Step7");
+ /*****************************************************************************/
+
+ /* Note that the available buffers in the receiver should have decremented once
+ since the previously received packet has not been read from the application
+ side of the stack yet. */
+ for(j = 0; j < 14; j++)
+ {
+ for(i = 0; i < 15; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
+ }
+ s = RIO_portGetSymbol(&stack);
+ c = CreateControlSymbol(STYPE0_STATUS, 1, 7, STYPE1_NOP, 0);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 8:");
+ PrintS("Action: Get the first symbol from the transmitter once the link-intialized ");
+ PrintS(" state has been entered.");
+ PrintS("Result: A packet-accepted-symbol should be received for the newly received ");
+ PrintS(" packet.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC1-Step8");
+ /*****************************************************************************/
+
+ c = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 0, 7, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 9:");
+ PrintS("Action: Get the next symbols from the transmitter.");
+ PrintS("Result: The packet placed in the outbound queue at startup should be ");
+ PrintS(" received. Dont acknowledge the packet yet.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC1-Step9");
+ /*****************************************************************************/
+
+ /* Create a packet. */
+ packetLength = createDoorbell(packet, 0, 1, 0xffff, 0, 0xdeaf);
+
+ /* Receive the start of the frame. */
+ c = CreateControlSymbol(STYPE0_STATUS, 1, 7, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Receive the data of the frame. */
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+
+ /* Receive the end of the frame. */
+ c = CreateControlSymbol(STYPE0_STATUS, 1, 7, STYPE1_END_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTSYMBOL(s, c);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 10:");
+ PrintS("Action: Remove the packet from the inbound queue. Dont acknowledge the");
+ PrintS(" transmitted packet yet.");
+ PrintS("Result: Check that status-control-symbols are sent each 256 symbol and that ");
+ PrintS(" the buffer count is updated when the inbound packet has been read.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC1-Step10");
+ /*****************************************************************************/
+
+ /* Simulate the application reading the received packet to free one reception
+ buffer. */
+ RIO_packetRemove(&stack);
+
+ /* Check that the status-control-symbols are generated each 256 symbol. */
+ for(i = 0; i < 255; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
+ }
+
+ /* Check that the buffer status has been updated. */
+ s = RIO_portGetSymbol(&stack);
+ c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_NOP, 0);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 11:");
+ PrintS("Action: Send a packet when an acknowledge has not been received.");
+ PrintS("Result: Only idle and status control symbols should be transmitted until ");
+ PrintS(" the packet-accepted symbol has been received.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC1-Step11");
+ /*****************************************************************************/
+
+ /* Place a packet in the outbound queue. */
+ RIO_sendDoorbell(&stack, 2, 1, 0xc0de);
+
+ packetLength = createDoorbell(packet, 1, 2, 0xffff, 1, 0xc0de);
+
+ /* Receive the start of the frame. */
+ c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Receive the data of the frame. */
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+
+ /* Receive the end of the frame. */
+ c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_END_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTSYMBOL(s, c);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 12:");
+ PrintS("Action: Send a packet-accepted symbol.");
+ PrintS("Result: Check that the new packet is transmitted.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC1-Step12");
+ /*****************************************************************************/
+
+ /* Send acknowledge for the first frame. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 0, 1, STYPE1_NOP, 0));
+
+ /* Check that status-control-symbols are transmitted once every 256 symbol with
+ updated ackId. */
+ for(i = 0; i < 255; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
+ }
+ s = RIO_portGetSymbol(&stack);
+ c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_NOP, 0);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 13:");
+ PrintS("Action: Send a packet-accepted symbol.");
+ PrintS("Result: Check that only idle and status-control-symbols are transmitted ");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC1-Step13");
+ /*****************************************************************************/
+
+ /* Acknowledge the second frame. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 1, 1, STYPE1_NOP, 0));
+
+ /* Check that status-control-symbols are transmitted once every 256 symbol with
+ updated ackId. */
+ for(i = 0; i < 255; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
+ }
+ s = RIO_portGetSymbol(&stack);
+ c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_NOP, 0);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riostack-TC2");
+ PrintS("Description: Test flow control.");
+ PrintS("Requirement: XXXXX");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send packets to receiver but don't acknowledge them.");
+ PrintS("Result: The reception queue of the stack is full.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC2-Step1");
+ /******************************************************************************/
+
+ /* Fill input queue in receiver. */
+ for(j = 0; j < 8; j++)
+ {
+ packetLength = createDoorbell(packet, 1+j, 0, 0, 1+j, 0);
+
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0));
+ for(i = 0; i < packetLength; i++)
+ {
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ RIO_portAddSymbol(&stack, d);
+ }
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0));
+
+ c = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 1+j, 7-j, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Send a packet when the inbound queue of the stack is full.");
+ PrintS("Result: The stack sends a packet-retry symbol. The receiver will end up in ");
+ PrintS("input-retry-stopped state.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC2-Step2");
+ /******************************************************************************/
+
+ /* Send another packet. */
+ packetLength = createDoorbell(packet, 9, 0, 0, 9, 0);
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0));
+ for(i = 0; i < packetLength; i++)
+ {
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ RIO_portAddSymbol(&stack, d);
+ }
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0));
+
+ /* Receive indication from stack that the packet must be retried. */
+ c = CreateControlSymbol(STYPE0_PACKET_RETRY, 9, 0, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Send a packet when the receiver is in input-retry-stopped.");
+ PrintS("Result: The receiver should ignore the new packet.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC2-Step3");
+ /******************************************************************************/
+
+ /* Resend the packet. */
+ packetLength = createDoorbell(packet, 9, 0, 0, 9, 0);
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0));
+ for(i = 0; i < packetLength; i++)
+ {
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ RIO_portAddSymbol(&stack, d);
+ }
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0));
+ s = RIO_portGetSymbol(&stack);
+
+ /* Check that nothing is transmitted. */
+ TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
+
+ /* REMARK: Send other symbols here to check that they are handled as expected... */
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 4:");
+ PrintS("Action: Send restart-from-retry and resend the previous packet.");
+ PrintS("Result: The receiver should leave the input-retry-stopped state and receive ");
+ PrintS(" the new frame.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC2-Step4");
+ /******************************************************************************/
+
+ /* Send restart-from-retry. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_RESTART_FROM_RETRY, 0));
+
+ /* Check that the transaction id is correct and remove a packet from the inbound
+ queue. One entry in the inbound queue will be empty. */
+ RIO_receiveDoorbell(&stack, &srcid, &tid, &info);
+ TESTEXPR(tid, 1);
+ RIO_packetRemove(&stack);
+
+ /* Check that the buffer status has changed to show that a buffer is available. */
+ s = RIO_portGetSymbol(&stack);
+ while(s.type == RIO_SYMBOL_TYPE_IDLE)
+ {
+ s = RIO_portGetSymbol(&stack);
+ }
+ c = CreateControlSymbol(STYPE0_STATUS, 9, 1, STYPE1_NOP, 0);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Resend the packet and check that it is received. */
+ packetLength = createDoorbell(packet, 9, 0, 0, 9, 0);
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0));
+ for(i = 0; i < packetLength; i++)
+ {
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ RIO_portAddSymbol(&stack, d);
+ }
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0));
+ c = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 9, 0, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 5:");
+ PrintS("Action: Place receiver in input-retry-stopped state.");
+ PrintS("Result: Check that packets may be transmitted normally.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC2-Step5");
+ /******************************************************************************/
+
+ /* Send another packet and check that the receiver indicates that it should be retried. */
+ packetLength = createDoorbell(packet, 10, 0, 0, 10, 0);
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0));
+ for(i = 0; i < packetLength; i++)
+ {
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ RIO_portAddSymbol(&stack, d);
+ }
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0));
+ c = CreateControlSymbol(STYPE0_PACKET_RETRY, 10, 0, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send two packets to see that the first acknowledge has been processed. */
+ RIO_sendDoorbell(&stack, 0, 2, 0xfeed);
+ RIO_sendDoorbell(&stack, 0, 3, 0xdeed);
+
+ /* Get the first packet. */
+ packetLength = createDoorbell(packet, 2, 0, 0xffff, 2, 0xfeed);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+
+ /* Get the second packet. */
+ packetLength = createDoorbell(packet, 3, 0, 0xffff, 3, 0xdeed);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTSYMBOL(s, c);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Indicate the packets must be retransmitted. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 2, 1, STYPE1_NOP, 0));
+
+ /* Receive confirmation that the packet will be retransmitted. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_RESTART_FROM_RETRY, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTSYMBOL(s, c);
+
+ /* Get the retransmission of the first packet. */
+ packetLength = createDoorbell(packet, 2, 0, 0xffff, 2, 0xfeed);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+
+ /* Get the retransmission of the second packet. */
+ packetLength = createDoorbell(packet, 3, 0, 0xffff, 3, 0xdeed);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTSYMBOL(s, c);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Confirm the reception of the packets. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 2, 1, STYPE1_NOP, 0));
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 3, 1, STYPE1_NOP, 0));
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 6:");
+ PrintS("Action: Send status-control-symbol to show that no packets can be ");
+ PrintS(" transmitted.");
+ PrintS("Result: No packets should be transmitted.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC2-Step6");
+ /******************************************************************************/
+
+ /* Send status with bufferStatus set to zero. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 4, 0, STYPE1_NOP, 0));
+
+ /* Send a packet. */
+ RIO_sendDoorbell(&stack, 0, 4, 0xf00d);
+
+ /* Check that nothing is transmitted but status-control-symbols. */
+ for(i = 0; i < 255; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
+ }
+ s = RIO_portGetSymbol(&stack);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_NOP, 0);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 7:");
+ PrintS("Action: Indicate free buffers and receive a frame, then request it to be ");
+ PrintS("retried.");
+ PrintS("Result: The packet should be retransmitted.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC2-Step7");
+ /******************************************************************************/
+
+ /* Send status with bufferStatus set to available. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 4, 1, STYPE1_NOP, 0));
+
+ /* Get the packet but request it to be retried. */
+ packetLength = createDoorbell(packet, 4, 0, 0xffff, 4, 0xf00d);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 4, 1, STYPE1_NOP, 0));
+
+ /* Check the acknowledge of the retransmission. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_RESTART_FROM_RETRY, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Get the packet and acknowledge it. */
+ packetLength = createDoorbell(packet, 4, 0, 0xffff, 4, 0xf00d);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 4, 1, STYPE1_NOP, 0));
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 8:");
+ PrintS("Action: Read all inbound packets from the reception queue.");
+ PrintS("Result: The buffer status should be updated.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC2-Step8");
+ /******************************************************************************/
+
+ for(j = 0; j < 8; j++)
+ {
+ RIO_receiveDoorbell(&stack, &srcid, &tid, &info);
+ TESTEXPR(tid, j+2);
+ RIO_packetRemove(&stack);
+
+ for(i = 0; i < 255; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
+ }
+ s = RIO_portGetSymbol(&stack);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, j+1, STYPE1_NOP, 0);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 9:");
+ PrintS("Action: Send a restart-from-retry to make the receiver leave the ");
+ PrintS(" input-retry-stopped state.");
+ PrintS("Result: New packets should be received again.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC2-Step9");
+ /******************************************************************************/
+
+ /* Send restart-from-retry. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_RESTART_FROM_RETRY, 0));
+
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riostack-TC3");
+ PrintS("Description: Test receiver error handling.");
+ PrintS("Requirement: XXXXX");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send invalid ack id in packet.");
+ PrintS("Result: Input-error-stopped state should be entered and link-response ");
+ PrintS(" should indicate an ackId error.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC3-Step1");
+ /******************************************************************************/
+
+ /* Send packet with invalid ackId, same as sent previously. */
+ packetLength = createDoorbell(packet, 9, 0, 0, 10, 0);
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0));
+ for(i = 0; i < packetLength; i++)
+ {
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ RIO_portAddSymbol(&stack, d);
+ }
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0));
+
+ /* Check that the packet is not accepted with cause error in ackId. */
+ c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 1, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send a link-request. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
+ STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
+
+ /* Check that a link-response is returned. */
+ /* Note that the status of the input-port will be reported as ok since a
+ link-request has been received. */
+ c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Check that a status is transmitted directly after the link-response. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Send packet with invalid CRC.");
+ PrintS("Result: Input-error-stopped state should be entered and link-response ");
+ PrintS(" should indicate a CRC error.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC3-Step2");
+ /******************************************************************************/
+
+ /* Send packet with invalid crc. */
+ packetLength = createDoorbell(packet, 10, 0, 0, 10, 0);
+ packet[0] ^= 0x00000001;
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0));
+ for(i = 0; i < packetLength; i++)
+ {
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ RIO_portAddSymbol(&stack, d);
+ }
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0));
+
+ /* Check that the packet is not accepted with cause error in ackId. */
+ c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 4, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send a link-request. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
+ STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
+
+ /* Check that a link-response is returned. */
+ /* Note that the status of the input-port will be reported as ok since a
+ link-request has been received. */
+ c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Check that a status is transmitted directly after the link-response. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Send a packet that is too short.");
+ PrintS("Result: Input-error-stopped state should be entered and link-response ");
+ PrintS(" should indicate a packet error.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC3-Step3");
+ /******************************************************************************/
+
+ /* Send packet with valid ackid and crc but too short. */
+ packetLength = createDoorbell(packet, 10, 0, 0, 10, 0);
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0));
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[0];
+ RIO_portAddSymbol(&stack, d);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = ((uint32_t) Crc32(packet[0] & 0x07ffffff, 0xffff)) << 16;
+ RIO_portAddSymbol(&stack, d);
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0));
+
+ /* Check that the packet is not accepted with cause error in ackId. */
+ c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 31, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send a link-request. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
+ STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
+
+ /* Check that a link-response is returned. */
+ /* Note that the status of the input-port will be reported as ok since a
+ link-request has been received. */
+ c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Check that a status is transmitted directly after the link-response. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 4:");
+ PrintS("Action: Send a packet that is too long.");
+ PrintS("Result: Input-error-stopped state should be entered and link-response ");
+ PrintS(" should indicate a packet error.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC3-Step4");
+ /******************************************************************************/
+
+ /* Send packet with too many data symbols and without a end-of-packet. */
+ packetLength = createDoorbell(packet, 10, 0, 0, 10, 0);
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0));
+ for(i = 0; i < 70; i++)
+ {
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ RIO_portAddSymbol(&stack, d);
+ }
+
+ /* Check that the packet is not accepted with cause error in ackId. */
+ c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 31, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send a link-request. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
+ STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
+
+ /* Check that a link-response is returned. */
+ /* Note that the status of the input-port will be reported as ok since a
+ link-request has been received. */
+ c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Check that a status is transmitted directly after the link-response. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 5:");
+ PrintS("Action: Send a data symbol without starting a packet.");
+ PrintS("Result: Input-error-stopped state should be entered and link-response ");
+ PrintS(" should indicate a packet error.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC3-Step5");
+ /******************************************************************************/
+
+ /* Send a data symbol. */
+ packetLength = createDoorbell(packet, 10, 0, 0, 10, 0);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[0];
+ RIO_portAddSymbol(&stack, d);
+
+ /* Check that the packet is not accepted with cause error in ackId. */
+ c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 31, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send a link-request. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
+ STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
+
+ /* Check that a link-response is returned. */
+ /* Note that the status of the input-port will be reported as ok since a
+ link-request has been received. */
+ c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Check that a status is transmitted directly after the link-response. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 6:");
+ PrintS("Action: Send end-of-packet without matching start.");
+ PrintS("Result: Input-error-stopped state should be entered and link-response ");
+ PrintS(" should indicate a packet error.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC3-Step6");
+ /******************************************************************************/
+
+ /* Send end-of-packet. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0));
+
+ /* Check that the packet is not accepted with cause error in ackId. */
+ c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 31, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send a link-request. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
+ STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
+
+ /* Check that a link-response is returned. */
+ /* Note that the status of the input-port will be reported as ok since a
+ link-request has been received. */
+ c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Check that a status is transmitted directly after the link-response. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 7:");
+ PrintS("Action: Send a symbol indicating a codec error.");
+ PrintS("Result: Input-error-stopped state should be entered and link-response ");
+ PrintS(" should indicate a symbol error.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC3-Step7");
+ /******************************************************************************/
+
+ /* Send error-symbol. */
+ s.type = RIO_SYMBOL_TYPE_ERROR;
+ RIO_portAddSymbol(&stack, s);
+
+ /* Check that the packet is not accepted with cause error in ackId. */
+ c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 5, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send a link-request. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
+ STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
+
+ /* Check that a link-response is returned. */
+ /* Note that the status of the input-port will be reported as ok since a
+ link-request has been received. */
+ c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Check that a status is transmitted directly after the link-response. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riostack-TC4");
+ PrintS("Description: Test transmitter error handling.");
+ PrintS("Requirement: XXXXX");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send acknowledge for a frame that has not been transmitted and ");
+ PrintS(" without any frame being expected.");
+ PrintS("Result: The transmitter should enter output-error-stopped and send ");
+ PrintS(" link-request.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC4-Step1");
+ /******************************************************************************/
+
+ /* Packet acknowledge for unsent frame. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 5, 1, STYPE1_NOP, 0));
+
+ /* Check that a link-request is received as the transmitter enters
+ output-error-stopped state. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8,
+ STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send link-response with expected ackId. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 5, 16, STYPE1_NOP, 0));
+
+ /* Send a status directly afterwards. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_NOP, 0));
+
+ /* Check that packets are relayed after this. */
+ RIO_sendDoorbell(&stack, 0, 5, 2);
+ packetLength = createDoorbell(packet, 5, 0, 0xffff, 5, 2);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 5, 1, STYPE1_NOP, 0));
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Send a packet and send acknowledge for a previous frame. Then send ");
+ PrintS(" a link-response indicating that the packet was received (accepted ");
+ PrintS(" but reply corrupted).");
+ PrintS("Result: The transmitter should enter output-error-stopped state and send ");
+ PrintS(" link-request and proceed with the next packet.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC4-Step2");
+ /******************************************************************************/
+
+ /* Send a packet. */
+ RIO_sendDoorbell(&stack, 0, 6, 2);
+ packetLength = createDoorbell(packet, 6, 0, 0xffff, 6, 2);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send acknowledge for another packet. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 5, 1, STYPE1_NOP, 0));
+
+ /* Check that a link-request is received as the transmitter enters
+ output-error-stopped state. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8,
+ STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send link-response with expected ackId. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 7, 16, STYPE1_NOP, 0));
+
+ /* Send a status directly afterwards. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 7, 1, STYPE1_NOP, 0));
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Send a packet and let the packet-accepted time out. Then send a ");
+ PrintS(" link-response indicating that the packet was not received.");
+ PrintS("Result: The transmitter should enter output-error-stopped state, send a");
+ PrintS(" link-request and then resend the packet.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC4-Step3");
+ /******************************************************************************/
+
+ /* Set the time at frame transmission. */
+ RIO_portSetTime(&stack, 2);
+
+ /* Send an output packet. */
+ RIO_sendDoorbell(&stack, 0, 7, 2);
+
+ /* Receive the transmitted packet. */
+ packetLength = createDoorbell(packet, 7, 0, 0xffff, 7, 2);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Indicate that time has passed to trigger a timeout. */
+ RIO_portSetTime(&stack, 3);
+
+ /* Check that a link-request is received as the transmitter enters
+ output-error-stopped state. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8,
+ STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send link-response with expected ackId. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 7, 16, STYPE1_NOP, 0));
+
+ /* Send a status directly afterwards. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 7, 1, STYPE1_NOP, 0));
+
+ /* Receive retransmitted packet. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send acknowledge for the retransmitted packet. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 7, 1, STYPE1_NOP, 0));
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 4:");
+ PrintS("Action: Send a packet and then indicate that the packet was not accepted. ");
+ PrintS(" Then send a link-response indicating that the packet was not received.");
+ PrintS("Result: The transmitter should enter output-error-stopped state, send a");
+ PrintS(" link-request and then resend the packet.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC4-Step4");
+ /******************************************************************************/
+
+ /* Send an output packet. */
+ RIO_sendDoorbell(&stack, 0, 8, 3);
+
+ /* Receive the transmitted packet. */
+ packetLength = createDoorbell(packet, 8, 0, 0xffff, 8, 3);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send packet-not-accepted indicating CRC error. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 4, STYPE1_NOP, 0));
+
+ /* Check that a link-request is received as the transmitter enters
+ output-error-stopped state. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8,
+ STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send link-response with expected ackId. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 8, 16, STYPE1_NOP, 0));
+
+ /* Send a status directly afterwards. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 8, 1, STYPE1_NOP, 0));
+
+ /* Receive retransmitted packet. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send acknowledge for the retransmitted packet. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 8, 1, STYPE1_NOP, 0));
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 5:");
+ PrintS("Action: Send a packet-retry for an unexpected packet. Then send a");
+ PrintS(" link-response indicating the expected ackId and a normal packet.");
+ PrintS("Result: The transmitter should enter output-error-stopped state, send a");
+ PrintS(" link-request and then the normal packet.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC4-Step5");
+ /******************************************************************************/
+
+ /* Send packet-retry indicating that a packet should be retransmitted. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 8, 1, STYPE1_NOP, 0));
+
+ /* Check that a link-request is received as the transmitter enters
+ output-error-stopped state. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8,
+ STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send link-response with expected ackId. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 9, 16, STYPE1_NOP, 0));
+
+ /* Send a status directly afterwards. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 9, 1, STYPE1_NOP, 0));
+
+ /* Send an output packet. */
+ RIO_sendDoorbell(&stack, 0, 9, 4);
+
+ /* Receive retransmitted packet. */
+ packetLength = createDoorbell(packet, 9, 0, 0xffff, 9, 4);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Send acknowledge for the retransmitted packet. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 9, 1, STYPE1_NOP, 0));
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 6:");
+ PrintS("Action: Fill outbound queue with packets, then check retransmission when ");
+ PrintS(" packet-retry is encountered. ");
+ PrintS("Result: Packets should be retried until packet-accepted is received.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC4-Step6");
+ /******************************************************************************/
+
+ TESTCOND(RIO_sendAvailable(&stack, 0));
+ RIO_sendDoorbell(&stack, 0, 20, 0xbabe);
+
+ TESTCOND(RIO_sendAvailable(&stack, 0));
+ RIO_sendDoorbell(&stack, 0, 21, 0xbabe);
+
+ TESTCOND(RIO_sendAvailable(&stack, 0));
+ RIO_sendDoorbell(&stack, 0, 22, 0xbabe);
+
+ TESTCOND(RIO_sendAvailable(&stack, 0));
+ RIO_sendDoorbell(&stack, 0, 23, 0xbabe);
+
+ TESTCOND(RIO_sendAvailable(&stack, 0));
+ RIO_sendDoorbell(&stack, 0, 24, 0xbabe);
+
+ TESTCOND(RIO_sendAvailable(&stack, 0));
+ RIO_sendDoorbell(&stack, 0, 25, 0xbabe);
+
+ TESTCOND(RIO_sendAvailable(&stack, 0));
+ RIO_sendDoorbell(&stack, 0, 26, 0xbabe);
+
+ TESTCOND(RIO_sendAvailable(&stack, 0));
+ RIO_sendDoorbell(&stack, 0, 27, 0xbabe);
+
+ TESTCOND(!RIO_sendAvailable(&stack, 0));
+
+ /* Receive transmitted packet. */
+ packetLength = createDoorbell(packet, 10, 0, 0xffff, 20, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ packetLength = createDoorbell(packet, 11, 0, 0xffff, 21, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ packetLength = createDoorbell(packet, 12, 0, 0xffff, 22, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ packetLength = createDoorbell(packet, 13, 0, 0xffff, 23, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ packetLength = createDoorbell(packet, 14, 0, 0xffff, 24, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ packetLength = createDoorbell(packet, 15, 0, 0xffff, 25, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ packetLength = createDoorbell(packet, 16, 0, 0xffff, 26, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ packetLength = createDoorbell(packet, 17, 0, 0xffff, 27, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ for(i = 0; i < 10; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
+ }
+
+ /* Request retransmission. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 10, 1, STYPE1_NOP, 0));
+
+ /* Acknowledge retransmission. */
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_RESTART_FROM_RETRY, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ /* Check retransmitted packets. */
+ packetLength = createDoorbell(packet, 10, 0, 0xffff, 20, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ packetLength = createDoorbell(packet, 11, 0, 0xffff, 21, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ packetLength = createDoorbell(packet, 12, 0, 0xffff, 22, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+
+ /* Acknowledge. */
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 10, 1, STYPE1_NOP, 0));
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 11, 1, STYPE1_NOP, 0));
+
+ packetLength = createDoorbell(packet, 13, 0, 0xffff, 23, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ packetLength = createDoorbell(packet, 14, 0, 0xffff, 24, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 12, 1, STYPE1_NOP, 0));
+
+ packetLength = createDoorbell(packet, 15, 0, 0xffff, 25, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 13, 1, STYPE1_NOP, 0));
+
+ packetLength = createDoorbell(packet, 16, 0, 0xffff, 26, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 14, 1, STYPE1_NOP, 0));
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ packetLength = createDoorbell(packet, 17, 0, 0xffff, 27, 0xbabe);
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+ for(i = 0; i < packetLength; i++)
+ {
+ s = RIO_portGetSymbol(&stack);
+ d.type = RIO_SYMBOL_TYPE_DATA;
+ d.data = packet[i];
+ TESTEXPR(s.type, d.type);
+ TESTEXPR(s.data, d.data);
+ }
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 15, 1, STYPE1_NOP, 0));
+ c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
+ s = RIO_portGetSymbol(&stack);
+ TESTEXPR(s.type, c.type);
+ TESTEXPR(s.data, c.data);
+
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 16, 1, STYPE1_NOP, 0));
+ RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 17, 1, STYPE1_NOP, 0));
+
+
+ /*************************************************************************
+ * Reset ackIds to be able to use the stack in loopback for the testcases
+ * below.
+ *************************************************************************/
+
+ stack.rxAckId = 0;
+ stack.rxAckIdAcked = 0;
+ stack.txAckId = 0;
+ stack.txAckIdWindow = 0;
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riostack-TC5");
+ PrintS("Description: Test MAINTENANCE-READ-REQUEST, MAINTENANCE-READ-RESPONSE,");
+ PrintS(" MAINTENANCE-WRITE-REQUEST and MAINTENANCE-WRITE-RESPONSE packets.");
+ PrintS("Requirement: XXXXX");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send two read requests to read identity and address of stack.");
+ PrintS("Result: The identity and address defined at RIO_open should be returned.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC5-Step1");
+ /******************************************************************************/
+
+ /* Send two read requests. */
+ RIO_sendMaintenanceReadRequest(&stack, 0xffff, 10, 0, 0x00000000);
+ RIO_sendMaintenanceReadRequest(&stack, 0xffff, 11, 0, 0x00000060);
+
+ TESTEXPR(RIO_outboundQueueLength(&stack), 2);
+
+ while(RIO_inboundQueueLength(&stack) != 2)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
+ TESTEXPR(srcid, 0xffff);
+ TESTEXPR(tid, 10);
+ TESTEXPR(hop, 0xff);
+ TESTEXPR(data, 0x0000b03b);
+ RIO_packetRemove(&stack);
+
+ RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
+ TESTEXPR(srcid, 0xffff);
+ TESTEXPR(tid, 11);
+ TESTEXPR(hop, 0xff);
+ TESTEXPR(data, 0x0000ffff);
+ RIO_packetRemove(&stack);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Send a write requests to write base device id of the stack.");
+ PrintS("Result: The identity and address defined at RIO_open should be returned.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC5-Step2");
+ /******************************************************************************/
+
+ /* Write base device id. */
+ RIO_sendMaintenanceWriteRequest(&stack, 0xffff, 12, 0, 0x00000060, 0xdead);
+ while(RIO_eventPoll(&stack) != RIO_EVENT_MAINT_WRITE_RESPONSE)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveMaintenanceWriteResponse(&stack, &srcid, &tid, &hop);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(tid, 12);
+ TESTEXPR(hop, 0xff);
+ RIO_packetRemove(&stack);
+
+ /* Read back the written base device id. */
+ RIO_sendMaintenanceReadRequest(&stack, 0xffff, 14, 0, 0x00000060);
+ while(RIO_eventPoll(&stack) != RIO_EVENT_MAINT_READ_RESPONSE)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(tid, 14);
+ TESTEXPR(hop, 0xff);
+ TESTEXPR(data, 0x0000dead);
+ RIO_packetRemove(&stack);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Send a write requests to write to the implementation defined ");
+ PrintS(" configuration space of the stack.");
+ PrintS("Result: The same data should be returned.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC5-Step3");
+ /******************************************************************************/
+
+ /* Write to implementation defined space. */
+ RIO_sendMaintenanceWriteRequest(&stack, 0xffff, 14, 0, 0x00010004, 0x01020304);
+ RIO_sendMaintenanceWriteRequest(&stack, 0xffff, 15, 0, 0x00010008, 0xc0debabe);
+ RIO_sendMaintenanceWriteRequest(&stack, 0xffff, 16, 0, 0x0001000c, 0x05060708);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_MAINT_WRITE_RESPONSE)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveMaintenanceWriteResponse(&stack, &srcid, &tid, &hop);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(tid, 14);
+ TESTEXPR(hop, 0xff);
+ RIO_packetRemove(&stack);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_MAINT_WRITE_RESPONSE)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveMaintenanceWriteResponse(&stack, &srcid, &tid, &hop);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(tid, 15);
+ TESTEXPR(hop, 0xff);
+ RIO_packetRemove(&stack);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_MAINT_WRITE_RESPONSE)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveMaintenanceWriteResponse(&stack, &srcid, &tid, &hop);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(tid, 16);
+ TESTEXPR(hop, 0xff);
+ RIO_packetRemove(&stack);
+
+ /* Read from implementation defined space. */
+ RIO_sendMaintenanceReadRequest(&stack, 0xffff, 14, 0, 0x00010000);
+ RIO_sendMaintenanceReadRequest(&stack, 0xffff, 15, 0, 0x00010004);
+ RIO_sendMaintenanceReadRequest(&stack, 0xffff, 16, 0, 0x00010008);
+ RIO_sendMaintenanceReadRequest(&stack, 0xffff, 17, 0, 0x0001000c);
+
+ while(RIO_inboundQueueLength(&stack) != 4)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(tid, 14);
+ TESTEXPR(hop, 0xff);
+ TESTEXPR(data, 0x80000006);
+ RIO_packetRemove(&stack);
+
+ RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(tid, 15);
+ TESTEXPR(hop, 0xff);
+ TESTEXPR(data, 0x00a100a2);
+ RIO_packetRemove(&stack);
+
+ RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(tid, 16);
+ TESTEXPR(hop, 0xff);
+ TESTEXPR(data, 0xc0debabe);
+ RIO_packetRemove(&stack);
+
+ RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(tid, 17);
+ TESTEXPR(hop, 0xff);
+ TESTEXPR(data, 0x00000000);
+ RIO_packetRemove(&stack);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riostack-TC6");
+ PrintS("Description: Test NREAD packets.");
+ PrintS("Requirement: XXXXX");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send one byte using NREAD and receive it at the other side.");
+ PrintS("Result: The same NREAD should be received as has been sent.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC6-Step1");
+ /******************************************************************************/
+
+ for(j = 0; j < 8; j++)
+ {
+ RIO_sendNread(&stack, 0x0060, j, 0xaaaaaaaa+j, 1);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_NREAD)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveNread(&stack, &srcid, &tid, &address, &length);
+
+ TESTEXPR(tid, j);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(address, 0xaaaaaaaa+j);
+ TESTEXPR(length, 1);
+
+ RIO_packetRemove(&stack);
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Send two bytes using NREAD and receive it at the other side.");
+ PrintS("Result: The same NREAD should be received as has been sent.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC6-Step2");
+ /******************************************************************************/
+
+ for(j = 0; j < 4; j++)
+ {
+ RIO_sendNread(&stack, 0x0060, j, 0x00000008+2*j, 2);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_NREAD)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveNread(&stack, &srcid, &tid, &address, &length);
+
+ TESTEXPR(tid, j);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(address, 0x00000008+2*j);
+ TESTEXPR(length, 2);
+
+ RIO_packetRemove(&stack);
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Send three to seven bytes using NREAD and receive it at the other ");
+ PrintS(" side.");
+ PrintS("Result: The same NREAD should be received as has been sent.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC6-Step3");
+ /******************************************************************************/
+
+ for(k = 3; k < 8; k++)
+ {
+ for(j = 0; j < 2; j++)
+ {
+ RIO_sendNread(&stack, 0x0060, j, 0x00000008+(8-k)*j, k);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_NREAD)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveNread(&stack, &srcid, &tid, &address, &length);
+
+ TESTEXPR(tid, j);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(address, 0x00000008+(8-k)*j);
+ TESTEXPR(length, k);
+
+ RIO_packetRemove(&stack);
+ }
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 4:");
+ PrintS("Action: Send one and two double words using NREAD and receive it at the ");
+ PrintS(" other side.");
+ PrintS("Result: The same NREAD should be received as has been sent.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC6-Step4");
+ /******************************************************************************/
+
+ for(j = 0; j < 2; j++)
+ {
+ RIO_sendNread(&stack, 0x0060, j, 0x00000008+8*j, 8*j+8);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_NREAD)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveNread(&stack, &srcid, &tid, &address, &length);
+
+ TESTEXPR(tid, j);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(address, 0x00000008+8*j);
+ TESTEXPR(length, 8*j+8);
+
+ RIO_packetRemove(&stack);
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 5:");
+ PrintS("Action: Send multiple of four full double words using NREAD and receive it");
+ PrintS("at the other side.");
+ PrintS("Result: The same NREAD should be received as has been sent.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC6-Step5");
+ /******************************************************************************/
+
+ for(j = 0; j < 8; j++)
+ {
+ RIO_sendNread(&stack, 0x0060, j, 0x00000008+8*j, 32*j+32);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_NREAD)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveNread(&stack, &srcid, &tid, &address, &length);
+
+ TESTEXPR(tid, j);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(address, 0x00000008+8*j);
+ TESTEXPR(length, 32*j+32);
+
+ RIO_packetRemove(&stack);
+ }
+
+ /* REMARK: Add negative testcase where all unallowed address, size combinations
+ are sent...*/
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riostack-TC7");
+ PrintS("Description: Test NWRITER packets.");
+ PrintS("Requirement: XXXXX");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send one byte using NWRITER and receive it at the other side.");
+ PrintS("Result: The same NWRITER should be received as has been sent.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC7-Step1");
+ /******************************************************************************/
+
+ for(j = 0; j < 8; j++)
+ {
+ for(i = 0; i < 1; i++)
+ {
+ payload8[i] = i+j+1;
+ payload8Expected[i] = 0;
+ }
+
+ RIO_sendNwrite(&stack, 0x0060, 0xaaaaaaaa+j, 1, payload8);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_NWRITE)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ length = RIO_receiveNwrite(&stack, &srcid, &tid, &address, sizeof(payload8Expected), payload8Expected);
+
+ TESTEXPR(length, 1);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(address, 0xaaaaaaaa+j);
+
+ for(i = 0; i < 1; i++)
+ {
+ TESTEXPR(payload8Expected[i], i+j+1);
+ }
+
+ RIO_packetRemove(&stack);
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Send two bytes using NWRITE and receive it at the other side.");
+ PrintS("Result: The same NWRITE should be received as has been sent.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC7-Step2");
+ /******************************************************************************/
+
+ for(j = 0; j < 4; j++)
+ {
+ for(i = 0; i < 2; i++)
+ {
+ payload8[i] = i+j;
+ payload8Expected[i] = 0;
+ }
+
+ RIO_sendNwriteR(&stack, 0x0060, j, 0x00000008+2*j, 2, payload8);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_NWRITE_R)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ length = RIO_receiveNwrite(&stack, &srcid, &tid, &address, sizeof(payload8Expected), payload8Expected);
+
+ TESTEXPR(tid, j);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(address, 0x00000008+2*j);
+ TESTEXPR(length, 2);
+
+ for(i = 0; i < 2; i++)
+ {
+ TESTEXPR(payload8Expected[i], i+j);
+ }
+
+ RIO_packetRemove(&stack);
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Send three to seven bytes using NWRITE and receive it at the other ");
+ PrintS(" side.");
+ PrintS("Result: The same NWRITE should be received as has been sent.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC7-Step3");
+ /******************************************************************************/
+
+ for(k = 3; k < 8; k++)
+ {
+ for(j = 0; j < 2; j++)
+ {
+ for(i = 0; i < k; i++)
+ {
+ payload8[i] = i+j+1;
+ payload8Expected[i] = 0;
+ }
+
+ RIO_sendNwriteR(&stack, 0x0060, j, 0x00000008+(8-k)*j, k, payload8);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_NWRITE_R)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ length = RIO_receiveNwrite(&stack, &srcid, &tid, &address, sizeof(payload8Expected), payload8Expected);
+
+ TESTEXPR(tid, j);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(address, 0x00000008+(8-k)*j);
+ TESTEXPR(length, k);
+
+ for(i = 0; i < k; i++)
+ {
+ TESTEXPR(payload8Expected[i], i+j+1);
+ }
+
+ RIO_packetRemove(&stack);
+ }
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 4:");
+ PrintS("Action: Send full double words using NWRITE and receive it at the other side.");
+ PrintS("Result: The same NWRITE should be received as has been sent.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC7-Step4");
+ /******************************************************************************/
+
+ for(j = 1; j < 32; j++)
+ {
+ for(i = 0; i < 8*j; i++)
+ {
+ payload8[i] = i+j+1;
+ payload8Expected[i] = 0;
+ }
+
+ RIO_sendNwriteR(&stack, 0x0060, j, 0x00000008+8*j, 8*j, payload8);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_NWRITE_R)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ length = RIO_receiveNwrite(&stack, &srcid, &tid, &address, sizeof(payload8Expected), payload8Expected);
+
+ TESTEXPR(tid, j);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(address, 0x00000008+8*j);
+ TESTEXPR(length, 8*j);
+
+ for(i = 0; i < 8*j; i++)
+ {
+ TESTEXPR(payload8Expected[i], (uint8_t) (i+j+1));
+ }
+
+ RIO_packetRemove(&stack);
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riostack-TC8");
+ PrintS("Description: Test RESPONSE packets.");
+ PrintS("Requirement: XXXXX");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send one byte using RESPONSE_WITH_PAYLOAD and receive it at the ");
+ PrintS(" other side.");
+ PrintS("Result: The same RESPONSE_WITH_PAYLOAD should be received as has been sent.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC8-Step1");
+ /******************************************************************************/
+
+ for(j = 0; j < 8; j++)
+ {
+ for(i = 0; i < 1; i++)
+ {
+ payload8[i] = i+j+1;
+ payload8Expected[i] = 0;
+ }
+
+ RIO_sendResponseDonePayload(&stack, 0x0060, j, 0x00000008+j, 1, payload8);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_RESPONSE_DONE_PAYLOAD)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ length = RIO_receiveResponseDonePayload(&stack, &srcid, &tid, 0x00000008+j, 1, payload8Expected);
+
+ TESTEXPR(tid, j);
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(length, 1);
+
+ for(i = 0; i < 1; i++)
+ {
+ TESTEXPR(payload8Expected[i], i+j+1);
+ }
+
+ RIO_packetRemove(&stack);
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riostack-TC9");
+ PrintS("Description: Test DOORBELL packet and its response.");
+ PrintS("Requirement: XXXXX");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send a doorbell.");
+ PrintS("Result: The received doorbell should have the same properties as the sent.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC9-Step1");
+ /******************************************************************************/
+
+ RIO_sendDoorbell(&stack, 0x0060, 16, 0xbabe);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_DOORBELL)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveDoorbell(&stack, &srcid, &tid, &info);
+
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(tid, 16);
+ TESTEXPR(info, 0xbabe);
+ RIO_packetRemove(&stack);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Send a response that is used for doorbells.");
+ PrintS("Result: The same data should be returned.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC9-Step2");
+ /******************************************************************************/
+
+ RIO_sendResponseDone(&stack, 0x0060, 16);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_RESPONSE_DONE)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveResponseDone(&stack, &srcid, &tid);
+
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(tid, 16);
+ RIO_packetRemove(&stack);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riostack-TC10");
+ PrintS("Description: Test MESSAGE packets.");
+ PrintS("Requirement: XXXXX");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send increasing number of byte using MESSAGE on all mailboxes");
+ PrintS(" and receive it at the other side.");
+ PrintS("Result: The same MESSAGE on the correct mailbox should be received as has");
+ PrintS(" been sent.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC10-Step1");
+ /******************************************************************************/
+
+ for(k = 0; k < 256; k++)
+ {
+ for(j = 1; j < 256; j++)
+ {
+ for(i = 0; i < j; i++)
+ {
+ payload8[i] = i+j+1;
+ payload8Expected[i] = 0;
+ }
+
+ RIO_sendMessage(&stack, 0x0060, k, j, payload8);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_MESSAGE)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ length = RIO_receiveMessage(&stack, &srcid, &mailbox, sizeof(payload8Expected), payload8Expected);
+
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(mailbox, k);
+ TESTEXPR(length, (((j-1)/8)+1)*8);
+
+ for(i = 0; i < j; i++)
+ {
+ TESTEXPR(payload8Expected[i], (uint8_t) (i+j+1));
+ }
+
+ RIO_packetRemove(&stack);
+ }
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Send a MESSAGE-RESPONSE from all mailboxes.");
+ PrintS("Result: The same MESSAGE-RESPONSE should be received as has been sent.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC10-Step2");
+ /******************************************************************************/
+
+ for(i = 0; i < 256; i++)
+ {
+ RIO_sendMessageResponseDone(&stack, 0x0060, i);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_MESSAGE_RESPONSE_DONE)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveMessageResponseDone(&stack, &srcid, &mailbox);
+
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(mailbox, i);
+ RIO_packetRemove(&stack);
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riostack-TC11");
+ PrintS("Description: Test reading and writing raw packets.");
+ PrintS("Requirement: XXXXX");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send a packet using normal functions then copy it using the ");
+ PrintS(" packetGet() and packetSet() functions. ");
+ PrintS("Result: The same packet should be received when copied.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC11-Step1");
+ /******************************************************************************/
+
+ RIO_sendDoorbell(&stack, 0x0060, 1, 0xca1e);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_DOORBELL)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ RIO_receiveDoorbell(&stack, &srcid, &tid, &info);
+
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(tid, 1);
+ TESTEXPR(info, 0xca1e);
+
+ packetLength = RIO_packetGet(&stack, sizeof(packet)/4, packet);
+ RIO_packetSet(&stack, packetLength, packet);
+
+ while(RIO_eventPoll(&stack) != RIO_EVENT_DOORBELL)
+ {
+ s = RIO_portGetSymbol(&stack);
+ RIO_portAddSymbol(&stack, s);
+ }
+
+ TESTEXPR(srcid, 0xdead);
+ TESTEXPR(tid, 1);
+ TESTEXPR(info, 0xca1e);
+ RIO_packetRemove(&stack);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+
+ return 0;
+}
+#endif
+
+/*************************** end of file **************************************/
1.0.1/sw/stack/riostack.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/sw/stack/rioconfig.h
===================================================================
--- 1.0.1/sw/stack/rioconfig.h (nonexistent)
+++ 1.0.1/sw/stack/rioconfig.h (revision 29)
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ *
+ * RapidIO IP Library Core
+ *
+ * This file is part of the RapidIO IP library project
+ * http://www.opencores.org/cores/rio/
+ *
+ * Description:
+ * This file contains the implementation dependent information needed to build
+ * the riostack. Replace declarations and definitions in this file to customize
+ * for your own compiler environment.
+ *
+ * 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
+ *
+ *******************************************************************************/
+
+#ifndef __RIO_CONFIG
+#define __RIO_CONFIG
+
+/*******************************************************************************
+* Includes
+*******************************************************************************/
+
+#include
+#include
+
+/*******************************************************************************
+* Global typedefs
+*******************************************************************************/
+
+#ifndef ASSERT
+#ifdef MODULE_TEST
+#include
+#define ASSERT(c, s) (c)?:fprintf(stderr, s)
+#endif
+#endif
+
+#ifndef ASSERT0
+#ifdef MODULE_TEST
+#include
+#define ASSERT0(s) fprintf(stderr, s)
+#endif
+#endif
+
+#ifndef DEBUG_OUT
+#define DEBUG_OUT(...)
+#endif
+
+#define DEBUG_STATE(...) /*DEBUG_OUT(__VA_ARGS__)*/
+#define DEBUG_FRAMING_RX(...) /*DEBUG_OUT(__VA_ARGS__)*/
+#define DEBUG_FRAMING_TX(...) /*DEBUG_OUT(__VA_ARGS__)*/
+
+typedef uint8_t bool_t;
+
+
+/*******************************************************************************
+* Global declarations
+*******************************************************************************/
+
+/*******************************************************************************
+* Global function prototypes
+*******************************************************************************/
+
+#endif // __RIO_CONFIG
+
+/*************************** end of file **************************************/
1.0.1/sw/stack/rioconfig.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/sw/stack/riostack.h
===================================================================
--- 1.0.1/sw/stack/riostack.h (nonexistent)
+++ 1.0.1/sw/stack/riostack.h (revision 29)
@@ -0,0 +1,1736 @@
+/*******************************************************************************
+ *
+ * RapidIO IP Library Core
+ *
+ * This file is part of the RapidIO IP library project
+ * http://www.opencores.org/cores/rio/
+ *
+ * Description:
+ * This file contains the function prototypes and types that are needed to be
+ * able to use the riostack.c module.
+ *
+ * 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
+ *
+ *******************************************************************************/
+
+/**
+ * \file riostack.h
+ */
+
+#ifndef _RIOSTACK_H
+#define _RIOSTACK_H
+
+/*******************************************************************************
+ * Includes
+ *******************************************************************************/
+
+#include "rioconfig.h"
+
+
+/*******************************************************************************
+ * Global typedefs
+ *******************************************************************************/
+
+/* The maximum size of a RapidIO packet. */
+#define RIO_PACKET_SIZE ((uint8_t)69u)
+
+/* The size of a maximum sized RapidIO packet when stored in memory. */
+/* One entry contains a header with the used buffer size. */
+#define RIO_BUFFER_SIZE (RIO_PACKET_SIZE+1u)
+
+/* Configuration space offsets. */
+#define DEVICE_IDENTITY_CAR ((uint32_t)0x00000000ul)
+#define DEVICE_INFORMATION_CAR ((uint32_t)0x00000004ul)
+#define ASSEMBLY_IDENTITY_CAR ((uint32_t)0x00000008ul)
+#define ASSEMBLY_INFORMATION_CAR ((uint32_t)0x0000000cul)
+#define PROCESSING_ELEMENT_FEATURES_CAR ((uint32_t)0x00000010ul)
+#define SWITCH_PORT_INFORMATION_CAR ((uint32_t)0x00000014ul)
+#define SOURCE_OPERATIONS_CAR ((uint32_t)0x00000018ul)
+#define DESTINATION_OPERATIONS_CAR ((uint32_t)0x0000001cul)
+#define SWITCH_ROUTE_TABLE_DESTINATION_ID_LIMIT_CAR ((uint32_t)0x00000034ul)
+#define PROCESSING_ELEMENT_LOGICAL_LAYER_CONTROL_CSR ((uint32_t)0x0000004cul)
+#define BASE_DEVICE_ID_CSR ((uint32_t)0x00000060ul)
+#define HOST_BASE_DEVICE_ID_LOCK_CSR ((uint32_t)0x00000068ul)
+#define COMPONENT_TAG_CSR ((uint32_t)0x0000006cul)
+#define STANDARD_ROUTE_CONFIGURATION_DESTINATION_ID_SELECT_CSR ((uint32_t)0x00000070ul)
+#define STANDARD_ROUTE_CONFIGURATION_PORT_SELECT_CSR ((uint32_t)0x00000074ul)
+#define STANDARD_ROUTE_DEFAULT_PORT_CSR ((uint32_t)0x00000078ul)
+#define EXTENDED_FEATURES_OFFSET ((uint32_t)0x00000100ul)
+#define IMPLEMENTATION_DEFINED_OFFSET ((uint32_t)0x00010000ul)
+#define LP_SERIAL_REGISTER_BLOCK_HEADER(offset) (offset)
+#define PORT_LINK_TIMEOUT_CONTROL_CSR(offset) ((offset) + 0x00000020ul)
+#define PORT_RESPONSE_TIMEOUT_CONTROL_CSR(offset) ((offset) + 0x00000024ul)
+#define PORT_GENERAL_CONTROL_CSR(offset) ((offset) + 0x0000003cul)
+#define PORT_N_LOCAL_ACKID_CSR(offset, n) ((offset) + (0x00000048ul+((n)*0x00000020ul)))
+#define PORT_N_ERROR_AND_STATUS_CSR(offset, n) ((offset) + (0x00000058ul+((n)*0x00000020ul)))
+#define PORT_N_CONTROL_CSR(offset, n) ((offset) + (0x0000005cul+((n)*0x00000020ul)))
+
+
+/* Define the different types of RioSymbols. */
+typedef enum
+{
+ RIO_SYMBOL_TYPE_IDLE, RIO_SYMBOL_TYPE_CONTROL,
+ RIO_SYMBOL_TYPE_DATA, RIO_SYMBOL_TYPE_ERROR
+} RioSymbolType;
+
+
+/*
+ * RapidIO symbol definition.
+ * Idle symbol: Sent when nothing else to send. Does not use the data field.
+ * Control symbol: Sent when starting, ending and acknowleding a packet. Data
+ * is right aligned, (Unused, C0, C1, C2) where C0 is transmitted/received first.
+ * Data symbol: Sent to transfer packets. Uses the full data field, (D0, D1,
+ * D2, D3) where D0 is transmitted/received first.
+ * Error symbols are created when a symbols could not be created and the stack
+ * should know about it.
+ */
+typedef struct
+{
+ RioSymbolType type;
+ uint32_t data;
+} RioSymbol;
+
+
+/* Define different events that may happen in the stack. */
+typedef enum
+{
+ RIO_EVENT_NONE,
+ RIO_EVENT_NREAD, RIO_EVENT_NWRITE, RIO_EVENT_NWRITE_R,
+ RIO_EVENT_DOORBELL, RIO_EVENT_MESSAGE,
+ RIO_EVENT_MAINT_READ_REQUEST, RIO_EVENT_MAINT_WRITE_REQUEST,
+ RIO_EVENT_MAINT_READ_RESPONSE, RIO_EVENT_MAINT_WRITE_RESPONSE,
+ RIO_EVENT_RESPONSE_DONE, RIO_EVENT_RESPONSE_DONE_PAYLOAD,
+ RIO_EVENT_RESPONSE_RETRY, RIO_EVENT_RESPONSE_ERROR,
+ RIO_EVENT_MESSAGE_RESPONSE_DONE, RIO_EVENT_MESSAGE_RESPONSE_RETRY,
+ RIO_EVENT_MESSAGE_RESPONSE_ERROR
+} RioEventType;
+
+
+/* Define different states the link may be in. */
+typedef enum
+{
+ RIO_STATUS_UNINITIALIZED,
+ RIO_STATUS_ENUMERATION,
+ RIO_STATUS_OPERATIONAL
+} RioStatusType;
+
+
+/* Receiver states. */
+typedef enum
+{
+ RX_STATE_UNINITIALIZED, RX_STATE_PORT_INITIALIZED, RX_STATE_LINK_INITIALIZED,
+ RX_STATE_INPUT_RETRY_STOPPED, RX_STATE_INPUT_ERROR_STOPPED
+} RioReceiverState;
+
+
+/* Transmitter states. */
+typedef enum
+{
+ TX_STATE_UNINITIALIZED, TX_STATE_PORT_INITIALIZED, TX_STATE_LINK_INITIALIZED,
+ TX_STATE_SEND_PACKET_RETRY, TX_STATE_SEND_PACKET_NOT_ACCEPTED, TX_STATE_SEND_LINK_RESPONSE,
+ TX_STATE_OUTPUT_RETRY_STOPPED, TX_STATE_OUTPUT_ERROR_STOPPED
+} RioTransmitterState;
+
+
+/* Queue definition. */
+typedef struct
+{
+ uint8_t size;
+ uint8_t available;
+ uint8_t windowSize;
+ uint8_t windowIndex;
+ uint8_t frontIndex;
+ uint8_t backIndex;
+ uint32_t *buffer_p;
+} Queue_t;
+
+/* Forward declaration for the RioStack-structure. */
+struct RioStack_t;
+
+/* Structure to enter callback function pointers in. */
+typedef struct
+{
+ uint32_t (*configRead)(struct RioStack_t *stack, uint32_t offset);
+ void (*configWrite)(struct RioStack_t *stack, uint32_t offset, uint32_t data);
+} RioStackObserver_t;
+
+
+/* Define the structure to keep all the RapidIO stack variables. */
+typedef struct RioStack_t
+{
+ /* Receiver variables. */
+ RioReceiverState rxState;
+ uint8_t rxCounter;
+ uint16_t rxCrc;
+ uint8_t rxStatusReceived;
+ uint8_t rxAckId;
+ uint8_t rxAckIdAcked;
+ uint8_t rxErrorCause;
+ Queue_t rxQueue;
+
+ /* Transmitter variables. */
+ RioTransmitterState txState;
+ uint8_t txCounter;
+ uint16_t txStatusCounter;
+ uint8_t txFrameState;
+ uint32_t txFrameTimeout[32];
+ uint8_t txAckId;
+ uint8_t txAckIdWindow;
+ uint8_t txBufferStatus;
+ Queue_t txQueue;
+
+ /* Common protocol stack variables. */
+ uint32_t portTime;
+ uint32_t portTimeout;
+
+ /* Common protocol stack variables updated visible via the configuration space. */
+ uint16_t deviceIdentity;
+ uint16_t deviceVendorIdentity;
+ uint32_t deviceRev;
+ uint16_t assyIdentity;
+ uint16_t assyVendorIdentity;
+ uint16_t assyRev;
+ uint16_t baseDeviceId;
+ uint32_t hostBaseDeviceIdLock;
+ uint32_t componentTag;
+ uint8_t host;
+ uint8_t masterEnable;
+ uint8_t discovered;
+
+ /** The number of successfully received packets. */
+ uint32_t statusInboundPacketComplete;
+
+ /** The number of retried received packets.
+ This will happen if the receiver does not have resources available when an inbound packet is received. */
+ uint32_t statusInboundPacketRetry;
+
+ /** The number of received erronous control symbols.
+ This may happen if the inbound link has a high bit-error-rate. */
+ uint32_t statusInboundErrorControlCrc;
+
+ /** The number of received packets with an unexpected ackId.
+ This may happen if the inbound link has a high bit-error-rate. */
+ uint32_t statusInboundErrorPacketAckId;
+
+ /** The number of received packets with a checksum error.
+ This may happen if the inbound link has a high bit-error-rate. */
+ uint32_t statusInboundErrorPacketCrc;
+
+ /** The number of received symbols that contains an illegals character.
+ This may happen if the inbound link has a high bit-error-rate or if characters are missing in the
+ inbound character stream. */
+ uint32_t statusInboundErrorIllegalCharacter;
+
+ /** The number of general errors encountered at the receiver that does not fit into the other categories.
+ This happens if too short or too long packets are received. */
+ uint32_t statusInboundErrorGeneral;
+
+ /** The number of received packets that were discarded since they were unsupported by the stack.
+ This will happen if an inbound packet contains information that cannot be accessed using the function API
+ of the stack. */
+ uint32_t statusInboundErrorPacketUnsupported;
+
+ /** The number of successfully transmitted packets. */
+ uint32_t statusOutboundPacketComplete;
+
+ /** The number of retried transmitted packets.
+ This will happen if the receiver at the link-partner does not have resources available when an outbound
+ packet is received. */
+ uint32_t statusOutboundPacketRetry;
+
+ /** The number of outbound packets that has had its retransmission timer expired.
+ This happens if the latency of the system is too high or if a packet is corrupted due to a high
+ bit-error-rate on the outbound link. */
+ uint32_t statusOutboundErrorTimeout;
+
+ /** The number of packet-accepted that was received that contained an unexpected ackId.
+ This happens if the transmitter and the link-partner is out of synchronization, probably due
+ to a software error. */
+ uint32_t statusOutboundErrorPacketAccepted;
+
+ /** The number of packet-retry that was received that contained an unexpected ackId.
+ This happens if the transmitter and the link-partner is out of synchronization, probably due to
+ a software error. */
+ uint32_t statusOutboundErrorPacketRetry;
+
+ /** The number of received link-requests.
+ This happens if the link-partner transmitter has found an error and need to resynchronize itself
+ to the receiver. */
+ uint32_t statusPartnerLinkRequest;
+
+ /** The number of received erronous control symbols at the link-partner receiver.
+ This may happen if the outbound link has a high bit-error-rate. */
+ uint32_t statusPartnerErrorControlCrc;
+
+ /** The number of received packets with an unexpected ackId at the link-partner receiver.
+ This may happen if the outbound link has a high bit-error-rate. */
+ uint32_t statusPartnerErrorPacketAckId;
+
+ /** The number of received packets with a checksum error at the link-partner receiver.
+ This may happen if the outbound link has a high bit-error-rate. */
+ uint32_t statusPartnerErrorPacketCrc;
+
+ /** The number of received symbols that contains an illegals character at the link-parter receiver.
+ This may happen if the outbound link has a high bit-error-rate or if characters are missing in the
+ outbound character stream. */
+ uint32_t statusPartnerErrorIllegalCharacter;
+
+ /** The number of general errors encountered at the receiver that does not fit into the other categories.
+ This happens depending on the link-partner implementation. */
+ uint32_t statusPartnerErrorGeneral;
+
+ /* Callback structure. */
+ const RioStackObserver_t *observer;
+
+ /* Private user data. */
+ const void *private;
+} RioStack_t;
+
+
+/*******************************************************************************
+ * Global function prototypes
+ *******************************************************************************/
+
+/**
+ * \brief Open the RapidIO stack for operation.
+ *
+ * \param[in] stack Stack instance to operate on.
+ * \param[in] observer Callback structure to use when events happen.
+ * \param[in] private Pointer to an opaque data area containing private user data.
+ * \param[in] rxPacketBufferSize Number of words to use as reception buffer. This
+ * argument specifies the size of rxPacketBuffer.
+ * \param[in] rxPacketBuffer Pointer to buffer to store inbound packets in.
+ * \param[in] txPacketBufferSize Number of words to use as transmission buffer. This
+ * argument specifies the size of txPacketBuffer.
+ * \param[in] txPacketBuffer Pointer to buffer to store outbound packets in.
+ * \param[in] configDeviceVendorId Constant to use as deviceVendorIdentity when
+ * accessed in configuration space. (See Part 1, chapter 5.4.1)
+ * \param[in] configDeviceId Constant to use as deviceIdentity when accessed in
+ * configuration space. (See Part 1, chapter 5.4.1)
+ * \param[in] configDeviceRevisionId Constant to use as deviceRev when accessed in
+ * configuration space. (See Part 1, chapter 5.4.2)
+ * \param[in] configAssyVendorId Constant to use as assyVendorIdentity when accessed in
+ * configuration space. (See Part 1, chapter 5.4.3)
+ * \param[in] configAssyId Constant to use as assyIdentity when accessed in
+ * configuration space. (See Part 1, chapter 5.4.3)
+ * \param[in] configAssyRevisionId Constant to use as assyRev when accessed in
+ * configuration space. (See Part 1, chapter 5.4.4)
+ * \param[in] configBaseDeviceId The deviceId (source address) to use at startup when
+ * sending packets.
+ *
+ * This function initializes all internally used variables in the stack. The stack will
+ * however not be operational until the transcoder has signalled that it is ready for
+ * other symbols than idle. This is done using the function RIO_setPortStatus(). Once
+ * this function has been called it is possible to get and set symbols and to issue
+ * requests. The requests will be transmitted once the link initialization has
+ * been completed.
+ *
+ * The rxPacket/txPacket arguments are word buffers that are used internally to store the
+ * inbound and outbound packet queues.
+ *
+ * The config argument constants are used as identification when maintenance packets
+ * are received and replied to. They should be set to make the device where the stack
+ * is used easily identifiable on the net.
+ *
+ * \note The reception buffers can only support maximum 31 buffers.
+ */
+void RIO_open( RioStack_t *stack, const RioStackObserver_t *observer, const void *private,
+ const uint32_t rxPacketBufferSize, uint32_t *rxPacketBuffer,
+ const uint32_t txPacketBufferSize, uint32_t *txPacketBuffer,
+ const uint16_t configDeviceVendorId, const uint16_t configDeviceId,
+ const uint32_t configDeviceRevisionId, const uint16_t configAssyVendorId,
+ const uint16_t configAssyId, const uint16_t configAssyRevisionId,
+ const uint16_t configBaseDeviceId );
+
+/*******************************************************************************************
+ * Stack status functions.
+ * Note that status counters are access directly in the stack-structure.
+ *******************************************************************************************/
+
+/**
+ * \brief Get the status of the link.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return Returns the status of the link.
+ *
+ * This function indicates if the link is up and ready to relay packets.
+ */
+RioStatusType RIO_getStatus( RioStack_t *stack );
+
+/**
+ * \brief Get the number of pending outbound packets.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return Returns the number of pending outbound packets.
+ *
+ * This function checks the outbound queue and returns the number of packets
+ * that are pending to be transmitted onto the link.
+ */
+uint8_t RIO_outboundQueueLength( RioStack_t *stack );
+
+/**
+ * \brief Get the number of pending inbound packets.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return Returns the number of pending inbound packets.
+ *
+ * This function checks the inbound queue and returns the number of packets
+ * that has been received but not read by the user yet.
+ */
+uint8_t RIO_inboundQueueLength( RioStack_t *stack );
+
+/*******************************************************************************************
+ * Packet reception functions.
+ *******************************************************************************************/
+
+/**
+ * \brief Check for new events.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return Returns the value RIO_EVENT_NONE if no event is pending and
+ * something else if there are pending events.
+ *
+ * This function polls the incoming queue of packets and returns the
+ * type of packet present there. The return value from this function
+ * indicates which access functions that should be used to read the
+ * received packet.
+ *
+ * \note When a packet has been processed, RIO_packetRemove() must be called to free the
+ * used resources in the inbound queue.
+ */
+RioEventType RIO_eventPoll( RioStack_t *stack );
+
+/**
+ * \brief Remove a packet from the stack.
+ * \param[in] stack The stack to operate on.
+ *
+ * Remove a pending packet from the stack. The incoming packet queue is updated
+ * to remove the received packet.
+ */
+void RIO_packetRemove( RioStack_t *stack );
+
+/**
+ * \brief Check transmission buffers.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] size The size of the buffer that is about to be sent.
+ * \return Returns non-zero if a buffer with the specified size fits into the
+ * internal transmission buffers.
+ *
+ * Return if there are buffers available to send a packet of a specified size.
+ *
+ * \note If the response is negative, it might be positive later if outbound
+ * packets has been sent and new buffers becomes available.
+ *
+ * \note Set size to zero if there is no user definded payload.
+ */
+bool_t RIO_sendAvailable( RioStack_t *stack, const uint16_t size );
+
+/**
+ * \brief Get a raw packet from inbound queue.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] length The size of the buffer to write the packet to.
+ * \param[in] dest Pointer to where to copy the raw packet.
+ * \return The number of words copied.
+ *
+ * This function copies a raw packet in the inbound queue into a word buffer. An assert
+ * will occur if the packet does not fit into the provided buffer.
+ *
+ * \note The packet is automatically removed from the inbound queue. Do not use
+ * RIO_packetRemove() to remove it.
+ */
+uint32_t RIO_packetGet( RioStack_t *stack, uint32_t length, uint32_t *dest);
+
+/**
+ * \brief Set a raw packet in outbound queue.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] length The size of the packet to write.
+ * \param[in] src Pointer to where to copy the raw packet from.
+ *
+ * This function copies a raw packet from a source buffer into the outbound queue.
+ * An assert will occur if the packet does not fit into the internal buffer.
+ *
+ * \note Calling this function resembles a send-function, the packet will be placed in the
+ * outbound queue for transmission.
+ *
+ * \note If the copied packet does not have a correct CRC it might lock the stack since
+ * retransmissions will be done until forever.
+ */
+void RIO_packetSet( RioStack_t *stack, uint32_t length, uint32_t *src);
+
+/*******************************************************************************************
+ * Configuration-space access methods.
+ *******************************************************************************************/
+
+/**
+ * \brief Read configuration space.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] offset The configuration space address to read.
+ * \return The data read on the configuration space address specified.
+ *
+ * This function reads a configuration space offset and returns the content of
+ * the entry.
+ */
+uint32_t RIO_readConfig( RioStack_t *stack, const uint32_t offset );
+
+/**
+ * \brief Write configuration space.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] offset The configuration space address to write to.
+ * \param[in] data The data to write to the configuration space.
+ *
+ * This function writes to a configuration space offset and sets the
+ * content to the specified data.
+ */
+void RIO_writeConfig( RioStack_t *stack, const uint32_t offset, const uint32_t data);
+
+/*******************************************************************************************
+ * Logical I/O MAINTENANCE-READ functions.
+ *******************************************************************************************/
+
+/**
+ * \brief Send a maintenance read request.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device id of the destination end point.
+ * \param[in] tid The transaction id to be returned in the response.
+ * \param[in] hopCount The hop_count to set in the read request.
+ * \param[in] offset The byte address in the configuration space to read.
+ *
+ * This function creates and sends a maintenance read request packet.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendMaintenanceReadRequest(RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t offset );
+#else
+void RIO_sendMaintenanceReadRequest(RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t offset );
+#endif
+
+/**
+ * \brief Read a received maintenance read request.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] srcid The device id of the destination end point.
+ * \param[out] tid The transaction id to be returned in the response.
+ * \param[out] hopCount The hop_count to set in the read request.
+ * \param[out] offset The byte address in the configuration space to read.
+ *
+ * This function reads a received maintenance read request packet.
+ *
+ * \note In normal operational mode, the stack answers maintenance requests
+ * automatically without user intervention. This function should only be
+ * called if the stack is compiled in transparent mode.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_receiveMaintenanceReadRequest(RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *offset);
+#else
+void RIO_receiveMaintenanceReadRequest(RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *offset);
+#endif
+
+/**
+ * \brief Send a maintenance read response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device id of the destination end point.
+ * \param[in] tid The transaction id to be returned in the response.
+ * \param[in] hopCount The hop_count to set in the read request.
+ * \param[in] data The data to send in the response.
+ *
+ * This function creates a maintanance read response packet that should be
+ * sent when a request is received.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ *
+ * \note In normal operational mode, the stack answers maintenance requests
+ * automatically without user intervention. This function should only be
+ * called if the stack is compiled in transparent mode.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendMaintenanceReadResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t data);
+#else
+void RIO_sendMaintenanceReadResponse( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t data);
+#endif
+
+/**
+ * \brief Read a received maintenance read response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] srcid The device id of the source end point.
+ * \param[out] tid The transaction id in the response.
+ * \param[out] hopCount The hop_count set in the read response.
+ * \param[out] data The data in the response.
+ *
+ * This function reads a received maintanance read response packet.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_receiveMaintenanceReadResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *data);
+#else
+void RIO_receiveMaintenanceReadResponse( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *data);
+#endif
+
+/*******************************************************************************************
+ * Logical I/O MAINTENANCE-WRITE functions.
+ *******************************************************************************************/
+
+/**
+ * \brief Send a maintenance write request.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device id of the destination end point.
+ * \param[in] tid The transaction id to be returned in the response.
+ * \param[in] hopCount The hop_count to set in the write request.
+ * \param[in] offset The byte address in the configuration space to write to.
+ * \param[in] data The data to write in configuration space.
+ *
+ * This function creates and sends a maintenance write request packet.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendMaintenanceWriteRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t offset, const uint32_t data );
+#else
+void RIO_sendMaintenanceWriteRequest( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint8_t hopCount, const uint32_t offset, const uint32_t data );
+#endif
+
+/**
+ * \brief Read a received maintenance write request.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] destid The device id of the destination end point.
+ * \param[out] tid The transaction id to be returned in the response.
+ * \param[out] hopCount The hop_count to set in the write request.
+ * \param[out] offset The byte address in the configuration space to write to.
+ * \param[out] data The data to write in configuration space.
+ *
+ * This function creates and sends a maintenance write request packet. The reply
+ * is received using RIO_eventPoll-function and RIO_packetTid together with the return
+ * value from this function.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ *
+ * \note In normal operational mode, the stack answers maintenance requests
+ * automatically without user intervention. This function should only be
+ * called if the stack is compiled in transparent mode.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_receiveMaintenanceWriteRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *offset, uint32_t *data );
+#else
+void RIO_receiveMaintenanceWriteRequest( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount, uint32_t *offset, uint32_t *data );
+#endif
+
+/**
+ * \brief Send a maintenance write response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device id of the destination end point.
+ * \param[in] tid The transaction id to be returned.
+ * \param[in] hopCount The hop_count to set in the write response.
+ *
+ * This function creates a maintanance write response packet from a pending
+ * maintenance read request. The generated packet are placed in the outbound
+ * packet queue.
+ *
+ * \note In normal operational mode, the stack answers maintenance requests
+ * automatically without user intervention. This function should only be
+ * called if the stack is compiled in transparent mode.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendMaintenanceWriteResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint8_t hopCount);
+#else
+void RIO_sendMaintenanceWriteResponse( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint8_t hopCount);
+#endif
+
+/**
+ * \brief Read a received maintenance write response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] srcid The device id of the source end point.
+ * \param[out] tid The transaction id read in the response.
+ * \param[out] hopCount The hop_count read in the write response.
+ *
+ * This function creates a maintanance write response packet from a pending
+ * maintenance read request. The generated packet are placed in the outbound
+ * packet queue.
+ *
+ * \note In normal operational mode, the stack answers maintenance requests
+ * automatically without user intervention. This function should only be
+ * called if the stack is compiled in transparent mode.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_receiveMaintenanceWriteResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount);
+#else
+void RIO_receiveMaintenanceWriteResponse( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ uint8_t *hopCount);
+#endif
+
+/*******************************************************************************************
+ * Logical I/O NWRITE/NWRITER functions.
+ *******************************************************************************************/
+
+/**
+ * \brief Send an NWRITE request to write a byte array.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device id of the destination end point.
+ * \param[in] address The byte address to write to.
+ * \param[in] dataLength The number of bytes to write. The largest allowed size is 256 bytes.
+ * \param[in] data A pointer to the array of bytes to write.
+ *
+ * This function creates and sends an NWRITE request packet to write a number
+ * of bytes to a specified address. No reply will be received.
+ *
+ * \note The address is a byte address, not a word address.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ *
+ * \note Not all combinations of addresses and sizes are allowed. See table below:
+ * -------------------------------------------------------------------------------------
+ * size | valid byte in double-word
+ * -------------------------------------------------------------------------------------
+ * 1 | 10000000, 01000000, 00100000, 00010000, 00001000, 00000100, 00000010, 00000001
+ * 2 | 11000000, 00110000, 00001100, 00000011
+ * 3 | 11100000, 00000111
+ * 4 | 11110000, 00001111
+ * 5 | 11111000, 00011111
+ * 6 | 11111100, 00111111
+ * 7 | 11111110, 01111111
+ * 8*N | 11111111 (N={1...32})
+ * --------------------------------------------------------------------------------------
+ * See RapidIO 2.2 part1 table 4-4 for more details. Asserts will occurr if an invalid
+ * combination is detected.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendNwrite( RioStack_t *stack, const uint16_t destid, const uint16_t srcid,
+ const uint32_t address, const uint16_t dataLength, const uint8_t *data );
+#else
+void RIO_sendNwrite( RioStack_t *stack, const uint16_t destid,
+ const uint32_t address, const uint16_t dataLength, const uint8_t *data );
+#endif
+
+/**
+ * \brief Send an NWRITER request to write a byte array.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device id of the destination end point.
+ * \param[in] tid The transaction id to set in the response.
+ * \param[in] address The byte address to write to.
+ * \param[in] dataLength The number of bytes to write. The largest allowed size is 256 bytes.
+ * \param[in] data A pointer to the array of bytes to write.
+ *
+ * This function creates and sends an NWRITE request packet to write a number
+ * of bytes to a specified address. A reply will be received when the write has been completed.
+ *
+ * \note The address is a byte address, not a word address.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ *
+ * \note Not all combinations of addresses and sizes are allowed. See table below:
+ * -------------------------------------------------------------------------------------
+ * size | valid byte in double-word
+ * -------------------------------------------------------------------------------------
+ * 1 | 10000000, 01000000, 00100000, 00010000, 00001000, 00000100, 00000010, 00000001
+ * 2 | 11000000, 00110000, 00001100, 00000011
+ * 3 | 11100000, 00000111
+ * 4 | 11110000, 00001111
+ * 5 | 11111000, 00011111
+ * 6 | 11111100, 00111111
+ * 7 | 11111110, 01111111
+ * 8*N | 11111111 (N={1...32})
+ * --------------------------------------------------------------------------------------
+ * See RapidIO 2.2 part1 table 4-4 for more details. Asserts will occurr if an invalid
+ * combination is detected.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendNwriteR( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint32_t address, const uint16_t dataLength, const uint8_t *data );
+#else
+void RIO_sendNwriteR( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint32_t address, const uint16_t dataLength, const uint8_t *data );
+#endif
+
+/**
+ * \brief Read a received NWRITE/NWRITER request.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] srcid The device id of the destination end point.
+ * \param[out] tid The transaction id in the response. Undefined value when NWRITE is read.
+ * \param[out] address The byte address to write to.
+ * \param[in] dataLength The number of bytes allocated in data.
+ * \param[in] data A pointer to the array of bytes to copy to.
+ * \return The number of bytes copied into data.
+ *
+ * This function reads a received NWRITE/NWRITER request packet to write a number
+ * of bytes to a specified address. Used to receive both NWRITE and NWRITER. The payload
+ * of the packet is copied into the provided buffer pointed to by data.
+ *
+ * \note The address is a byte address, not a word address.
+ */
+#ifdef RIO_TRANSPARENT
+uint16_t RIO_receiveNwrite( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint32_t *address, const uint16_t dataLength, uint8_t *data );
+#else
+uint16_t RIO_receiveNwrite( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ uint32_t *address, const uint16_t dataLength, uint8_t *data );
+#endif
+
+/*******************************************************************************************
+ * Logical I/O NREAD functions.
+ *******************************************************************************************/
+
+/**
+ * \brief Send an NREAD request to read a byte array.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device id of the destination end point.
+ * \param[in] tid The transaction id to set in the response.
+ * \param[in] address The byte address to write to.
+ * \param[in] dataLength The number of bytes to write. The largest allowed size is 256 bytes.
+ *
+ * This function creates and sends an NWRITE request packet to write a number
+ * of bytes to a specified address. A reply will be received when the write has been completed.
+ *
+ * \note The address is a byte address, not a word address.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ *
+ * \note Not all combinations of address and length are allowed. See table below:
+ * -------------------------------------------------------------------------------------
+ * size | valid byte in double-word
+ * -------------------------------------------------------------------------------------
+ * 1 | 10000000, 01000000, 00100000, 00010000, 00001000, 00000100, 00000010, 00000001
+ * 2 | 11000000, 00110000, 00001100, 00000011
+ * 3 | 11100000, 00000111
+ * 4 | 11110000, 00001111
+ * 5 | 11111000, 00011111
+ * 6 | 11111100, 00111111
+ * 7 | 11111110, 01111111
+ * -------------------------------------------------------------------------------------
+ * For full double-words the following byte sizes are allowed:
+ * 8, 16, 32, 64, 96, 128, 160, 192, 224, 256
+ * --------------------------------------------------------------------------------------
+ * See RapidIO 2.2 part1 table 4-4 for more details. Asserts will occurr if an invalid
+ * combination is detected.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendNread( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint32_t address, const uint16_t dataLength);
+#else
+void RIO_sendNread( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint32_t address, const uint16_t dataLength);
+#endif
+
+/**
+ * \brief Read a received NREAD request.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] srcid The device id of the destination end point.
+ * \param[out] tid The transaction id in the response.
+ * \param[out] address The byte address to write to.
+ * \param[in] dataLength The number of bytes allocated in data.
+ *
+ * This function reads a received NREAD request packet to read a number
+ * of bytes at a specified address.
+ *
+ * \note The address is a byte address, not a word address.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_receiveNread( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint32_t *address, uint16_t *dataLength);
+#else
+void RIO_receiveNread( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ uint32_t *address, uint16_t *dataLength);
+#endif
+
+/*******************************************************************************************
+ * Logical I/O RESPONSE-DONE-PAYLOAD, RESPONSE-DONE, RESPONSE-RETRY and RESPONSE-ERROR
+ * functions.
+ *******************************************************************************************/
+
+/**
+ * \brief Send a response with data payload.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The destination identifier of the response.
+ * \param[in] tid The transaction identifier for the reply. It should correspond to
+ * the tid in the received packet for which this response is sent.
+ * \param[in] address The byte address that was read. It should correspond to
+ * the address in the received packet for which this response is sent.
+ * \param[in] dataLength The size of the data buffer to return in the reply. It
+ * should correspond to the dataLength in the received packet for which this response
+ * is sent.
+ * \param[in] data The data buffer to return in the reply.
+ *
+ * This function creates a response packet with the specified destination
+ * identifier, transaction id and data payload. The generated packet are placed
+ * in the outbound packet queue.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendResponseDonePayload( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint32_t address, const uint16_t dataLength, const uint8_t *data);
+#else
+void RIO_sendResponseDonePayload( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint32_t address, const uint16_t dataLength, const uint8_t *data);
+#endif
+
+/**
+ * \brief Read payload from a response with payload.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] srcid The device id of the destination end point.
+ * \param[out] tid The transaction id in the response.
+ * \param[in] address The byte address that was read. It should correspond to
+ * the address in the received packet for which this response is sent.
+ * \param[in] dataLength The size of the data buffer to return in the reply. It
+ * should correspond to the dataLength in the received packet for which this response
+ * is sent.
+ * \param[in] data Pointer to a buffer to where the data in the response will be copied.
+ * \return The number of bytes copied from the data payload contained in the response.
+ *
+ * This function reads a response packet and returns a the byte payload contained within.
+ */
+#ifdef RIO_TRANSPARENT
+uint16_t RIO_receiveResponseDonePayload( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ const uint32_t address, const uint16_t dataLength, uint8_t *data );
+#else
+uint16_t RIO_receiveResponseDonePayload( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ const uint32_t address, const uint16_t dataLength, uint8_t *data );
+#endif
+
+/**
+ * \brief Send a response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device identifier of the target to send the response to.
+ * \param[in] tid The transaction id to send the response for. This should be the
+ * same value as the packet that this response was received with.
+ *
+ * This function is used to send a response indicating a successfull
+ * completion in reply to a previously received packet.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendResponseDone( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid );
+
+#else
+void RIO_sendResponseDone( RioStack_t *stack, const uint16_t destid, const uint8_t tid );
+
+#endif
+/**
+ * \brief Read a received response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] srcid The device identifier of the source of the response.
+ * \param[out] tid The transaction id in the response.
+ *
+ * This function is used to read a received response indicating a successfull
+ * completion in reply to a previously sent packet.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_receiveResponseDone( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid );
+
+#else
+void RIO_receiveResponseDone( RioStack_t *stack, uint16_t *srcid, uint8_t *tid );
+
+#endif
+/**
+ * \brief Send a retry response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device identifier of the target to send the response to.
+ * \param[in] tid The transaction id to send the response for. This should be the
+ * same value as the packet that this response was received with.
+ *
+ * This function is used to send a response indicating a busy resource
+ * in reply to a previously received packet.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendResponseRetry( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid );
+
+#else
+void RIO_sendResponseRetry( RioStack_t *stack, const uint16_t destid, const uint8_t tid );
+
+#endif
+/**
+ * \brief Read a received retry response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] srcid The device identifier of the source of the response.
+ * \param[out] tid The transaction id in the response.
+ *
+ * This function is used to read a received response indicating a retry condition
+ * in reply to a previously sent packet.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_receiveResponseRetry( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid );
+
+#else
+void RIO_receiveResponseRetry( RioStack_t *stack, uint16_t *srcid, uint8_t *tid );
+
+#endif
+/**
+ * \brief Send a error response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device identifier of the target to send the response to.
+ * \param[in] tid The transaction id to send the response for. This should be the
+ * same value as the packet that this response was received with.
+ *
+ * This function is used to send a response indicating a busy resource
+ * in reply to a previously received packet.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendResponseError( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid );
+#else
+void RIO_sendResponseError( RioStack_t *stack, const uint16_t destid, const uint8_t tid );
+#endif
+
+/**
+ * \brief Read a received error response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] srcid The device identifier of the source of the response.
+ * \param[out] tid The transaction id in the response.
+ *
+ * This function is used to read a received response indicating an error condition
+ * in reply to a previously sent packet.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_receiveResponseError( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid );
+#else
+void RIO_receiveResponseError( RioStack_t *stack, uint16_t *srcid, uint8_t *tid );
+#endif
+
+/*******************************************************************************************
+ * Logical message passing DOORBELL and MESSAGE functions.
+ *******************************************************************************************/
+
+/**
+ * \brief Send a doorbell.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device id of the destination end point.
+ * \param[in] tid The transaction id to be returned in the response.
+ * \param[in] info The information to send with the doorbell.
+ * \return An identifier that maps to the doorbell response that are received using
+ * RIO_packetTid.
+ *
+ * This function is used to send a doorbell to a remote endpoint. A response
+ * should be sent when the doorbell has been processed using the RIO_sendResponseDone(),
+ * RIO_sendResponseRetry() or RIO_sendResponseError() functions.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendDoorbell( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
+ const uint16_t info);
+#else
+void RIO_sendDoorbell( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
+ const uint16_t info);
+#endif
+
+/**
+ * \brief Read a received a doorbell.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] srcid The device id of the source end point.
+ * \param[out] tid The transaction id to be returned in the response.
+ * \param[out] info The information to send with the doorbell.
+ *
+ * This function is used to read a received doorbell from a remote endpoint.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_receiveDoorbell( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
+ uint16_t *info);
+#else
+void RIO_receiveDoorbell( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
+ uint16_t *info);
+#endif
+
+/**
+ * \brief Send a message.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device id of the destination endpoint.
+ * \param[in] mailbox The mailbox to send the message to.
+ * \param[in] dataLength The size of the buffer to copy to.
+ * \param[in] buffer A byte pointer to the message payload to send.
+ *
+ * This function sends a single packet message to a destination mailbox.
+ *
+ * \note Mailbox 0-15 can support multipacket (when support is enabled)
+ * messages and 16-255 can only handle singlepacket messages. Dont use mailbox
+ * 0-15 unless you know that there will be large packets transmitted on it.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendMessage( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
+ const uint16_t dataLength, const uint8_t *data );
+#else
+void RIO_sendMessage( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox,
+ const uint16_t dataLength, const uint8_t *data );
+#endif
+
+/**
+ * \brief Read a received message.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] srcid The device id of the source endpoint.
+ * \param[out] mailbox The mailbox the message is received on.
+ * \param[in] dataLength The size of the buffer to copy to.
+ * \param[in] data A byte pointer to the message payload to read.
+ * \return The number of bytes copied. A zero will be returned if unable to copy.
+ *
+ * This function reads a single packet message to a destination mailbox.
+ */
+#ifdef RIO_TRANSPARENT
+uint16_t RIO_receiveMessage( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox,
+ const uint16_t dataLength, uint8_t *data );
+#else
+uint16_t RIO_receiveMessage( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox,
+ const uint16_t dataLength, uint8_t *data );
+#endif
+
+/*******************************************************************************************
+ * Logical message passing MESSAGE-RESPONSE functions.
+ *******************************************************************************************/
+
+/**
+ * \brief Send a message response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device identifier of the target to send the response to.
+ * \param[in] mailbox The mailbox to send the response to.
+ *
+ * This function is used to send a message response indicating a successfull
+ * completion in reply to a previously received message.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendMessageResponseDone( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox );
+#else
+void RIO_sendMessageResponseDone( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox );
+#endif
+
+/**
+ * \brief Read a received message response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] srcid The device identifier of the source endpoint.
+ * \param[out] mailbox The mailbox the response is for.
+ *
+ * This function is used to read a received message response indicating a successfull
+ * completion in reply to a previously sent message.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_receiveMessageResponseDone( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox );
+#else
+void RIO_receiveMessageResponseDone( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox );
+#endif
+
+/**
+ * \brief Send a message retry response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device identifier of the target to send the response to.
+ * \param[in] mailbox The mailbox to send the response to.
+ *
+ * This function is used to send a message response indicating a busy resource
+ * in reply to a previously received message.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendMessageResponseRetry( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox );
+#else
+void RIO_sendMessageResponseRetry( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox );
+#endif
+
+/**
+ * \brief Read a received message retry response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] srcid The device identifier of the source endpoint.
+ * \param[out] mailbox The mailbox the response is for.
+ *
+ * This function is used to read a received message retry response indicating a retry
+ * condition in reply to a previously sent message.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_receiveMessageResponseRetry( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox );
+#else
+void RIO_receiveMessageResponseRetry( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox );
+#endif
+
+/**
+ * \brief Send a message error response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device identifier of the target to send the response to.
+ * \param[in] mailbox The mailbox to send the response to.
+ *
+ * This function is used to send a message response indicating a busy resource
+ * in reply to a previously received message.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_sendMessageResponseError( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox );
+#else
+void RIO_sendMessageResponseError( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox );
+#endif
+
+/**
+ * \brief Read a received message error response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] srcid The device identifier of the source endpoint.
+ * \param[out] mailbox The mailbox the response is for.
+ *
+ * This function is used to read a received message error response indicating an error
+ * condition in reply to a previously sent message.
+ */
+#ifdef RIO_TRANSPARENT
+void RIO_receiveMessageResponseError( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox );
+#else
+void RIO_receiveMessageResponseError( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox );
+#endif
+
+/*******************************************************************************************
+ * Port functions (backend API towards physical device)
+ *******************************************************************************************/
+
+/**
+ * \brief Set a port current time.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] time The current time without unit.
+ *
+ * This function indicates to the stack the current time and this is used internally
+ * to calculate when a packet timeout should be triggered. Use this together with RIO_setPortTimeout()
+ * to allow for the stack to handle timeouts.
+ */
+void RIO_portSetTime( RioStack_t *stack, const uint32_t time);
+
+/**
+ * \brief Set a port timeout limit.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] time The time out threshold.
+ *
+ * The time to wait for a response from the link partner. The unit of the
+ * timeout value should be the same as the time used in RIO_setPortTime().
+ *
+ * This function is used to set a timeout threshold value and is used to know when
+ * an acknowledge should have been received from a link partner.
+ */
+void RIO_portSetTimeout( RioStack_t *stack, const uint32_t time);
+
+/**
+ * \brief Set a ports status.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] initialized The state of the port.
+ *
+ * If set to non-zero, the symbol encoder/decoder indicates to the stack that
+ * it is successfully encoding/decoding symbol, i.e. synchronized to the link.
+ *
+ * This function indicates to the stack if the port that are encoding/decoding
+ * symbols are ready to accept other symbols than idle-symbols. If the
+ * encoding/decoding loses synchronization then this function should be called
+ * with an argument equal to zero to force the stack to resynchronize the link.
+ */
+void RIO_portSetStatus( RioStack_t *stack, const uint8_t initialized );
+
+/**
+ * \brief Add a new symbol to the RapidIO stack.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] s A symbol received from a port.
+ *
+ * This function is used to insert new data, read from a port, into the stack. The
+ * symbols will be concatenated to form packets that can be accessed using other
+ * functions.
+ */
+void RIO_portAddSymbol( RioStack_t *stack, const RioSymbol s );
+
+/**
+ * \brief Get the next symbol to transmit on a port.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return A symbol that should be sent on a port.
+ *
+ * This function is used to fetch new symbols to transmit on a port. Packets that
+ * are inserted are split into symbols that are accessed with this function.
+ */
+RioSymbol RIO_portGetSymbol( RioStack_t *stack );
+
+
+/*******************************************************************************************
+ * DEPRECATED
+ * Will be removed.
+ *******************************************************************************************/
+
+/**
+ * \brief Read packet transaction identification.
+ * \param[in] stack The stack to operate on.
+ * \return The identification of the packet. This matches a transaction identifier
+ * that are set as argument when a send-function are called.
+ *
+ * This function is used to correlate a sent packet to a received response.
+ *
+ * \note This function cannot be used when receiving messages on mailboxes. Use
+ * RIO_readMessageMailbox() instead.
+ */
+uint8_t RIO_packetTid( RioStack_t *stack );
+
+/**
+ * \brief Read packet destination identification.
+ * \param[in] stack The stack to operate on.
+ * \return The destination device identifier of the packet.
+ *
+ * This function is used to get the destination device identifier of a received packet.
+ */
+uint16_t RIO_packetDestination( RioStack_t *stack );
+
+/**
+ * \brief Read packet source identification.
+ * \param[in] stack The stack to operate on.
+ * \return The source device identifier of the packet.
+ *
+ * This function is used to get the source device identifier of a received packet.
+ */
+uint16_t RIO_packetSource( RioStack_t *stack );
+
+/**
+ * \brief Read a maintenance read request hop count value.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The hopcount value of the packet.
+ *
+ * This function returns the hop count value of a received maintenance read
+ * request packet.
+ *
+ * \note In normal operational mode, the stack answers maintenance requests
+ * automatically without user intervention. This function should only be
+ * called if the stack is compiled in transparent mode.
+ */
+uint8_t RIO_readMaintenanceReadRequestHop( RioStack_t *stack );
+
+/**
+ * \brief Read a maintenance read request offset value.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The offset value of the packet.
+ *
+ * This function returns the offset value of a received maintenance read
+ * request packet.
+ *
+ * \note In normal operational mode, the stack answers maintenance requests
+ * automatically without user intervention. This function should only be
+ * called if the stack is compiled in transparent mode.
+ */
+uint32_t RIO_readMaintenanceReadRequestOffset( RioStack_t *stack );
+
+/**
+ * \brief Read a maintenance read response hop count value.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The hop count value of the packet.
+ *
+ * This function returns the hop count value of a received maintenance read
+ * response packet.
+ *
+ * \note In normal operational mode, the stack answers maintenance requests
+ * automatically without user intervention. This function should only be
+ * called if the stack is compiled in transparent mode.
+ */
+uint8_t RIO_readMaintenanceReadResponseHop( RioStack_t *stack );
+
+/**
+ * \brief Read a maintenance read response offset value.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The offset value of the packet.
+ *
+ * This function returns the offset value of a received maintenance read
+ * response packet.
+ *
+ * \note In normal operational mode, the stack answers maintenance requests
+ * automatically without user intervention. This function should only be
+ * called if the stack is compiled in transparent mode.
+ */
+uint32_t RIO_readMaintenanceReadResponse( RioStack_t *stack );
+
+/**
+ * \brief Read a maintenance write request hop count value.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The hopcount value of the packet.
+ *
+ * This function returns the hop count value of a received maintenance write
+ * request packet.
+ *
+ * \note In normal operational mode, the stack answers maintenance requests
+ * automatically without user intervention. This function should only be
+ * called if the stack is compiled in transparent mode.
+ */
+uint8_t RIO_readMaintenanceWriteRequestHop( RioStack_t *stack );
+
+/**
+ * \brief Read a maintenance write request offset value.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The offset value of the packet.
+ *
+ * This function returns the offset value of a received maintenance write
+ * request packet.
+ *
+ * \note In normal operational mode, the stack answers maintenance requests
+ * automatically without user intervention. This function should only be
+ * called if the stack is compiled in transparent mode.
+ */
+uint32_t RIO_readMaintenanceWriteRequestOffset( RioStack_t *stack );
+
+/**
+ * \brief Read a maintenance write request data value.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The data value of the packet.
+ *
+ * This function returns the data value of a received maintenance write
+ * request packet.
+ *
+ * \note In normal operational mode, the stack answers maintenance requests
+ * automatically without user intervention. This function should only be
+ * called if the stack is compiled in transparent mode.
+ */
+uint32_t RIO_readMaintenanceWriteRequestData( RioStack_t *stack );
+
+/**
+ * \brief Read a maintenance write response hop count value.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The hopcount value of the packet.
+ *
+ * This function returns the hop count value of a received maintenance write
+ * response packet.
+ *
+ * \note In normal operational mode, the stack answers maintenance requests
+ * automatically without user intervention. This function should only be
+ * called if the stack is compiled in transparent mode.
+ */
+uint8_t RIO_readMaintenanceWriteResponseHop( RioStack_t *stack );
+
+/**
+ * \brief Send an NWRITE request to write a byte.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device id of the destination end point.
+ * \param[in] address The byte address to write to.
+ * \param[in] data The byte data to write.
+ * This function creates and sends an NWRITE request packet. No reply will be received.
+ *
+ * \note The address is a byte address, not a word address.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+void RIO_sendNwrite8( RioStack_t *stack, const uint16_t destid, const uint32_t address, const uint8_t data );
+
+/**
+ * \brief Send an NWRITE_R request to write a byte.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device id of the destination end point.
+ * \param[in] tid The transaction id to be returned in the response.
+ * \param[in] address The byte address to write to.
+ * \param[in] data The byte data to write.
+ * \return An identifier that maps to the packet transaction identifier that are received using
+ * RIO_packetTid.
+ *
+ * This function creates and sends an NWRITE_R request packet. A reply should be received
+ * when the write has been completed.
+ *
+ * \note The address is a byte address, not a word address.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+void RIO_sendNwriteR8( RioStack_t *stack, const uint16_t destid, const uint8_t tid, const uint32_t address, const uint8_t data );
+
+/**
+ * \brief Get the byte address from an NWRITE or NWRITE_R packet.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The byte address contained in the NWRITE or NWRITE_R packet.
+ *
+ * This function reads a received an NWRITE or NWRITE_R request packet and fetches the address
+ * contained within.
+ *
+ * \note The address is a byte address, not a word address.
+ */
+uint32_t RIO_readNwriteAddress8( RioStack_t *stack );
+
+/**
+ * \brief Get the number of bytes to write from an NWRITE or NWRITE_R packet.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The number of bytes requested to be written in a NWRITE or NWRITE_R packet.
+ *
+ * This function reads a received an NWRITE or NWRITE_R request packet and fetches the
+ * number of bytes requested to be written.
+ *
+ * \note The returned size is the number of bytes.
+ */
+uint8_t RIO_readNwriteSize8( RioStack_t *stack );
+
+/**
+ * \brief Get the byte to write from a NWRITE or NWRITE_R packet.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The byte requested to be written in a NWRITE or NWRITE_R packet.
+ *
+ * This function reads a received an NWRITE or NWRITE_R request packet and fetches the
+ * byte to write.
+ */
+uint8_t RIO_readNwritePayload8( RioStack_t *stack );
+
+
+/**
+ * \brief Send a NREAD request to read a byte.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device id of the destination end point.
+ * \param[in] tid The transaction id to be returned in the response.
+ * \param[in] address The byte address to read.
+ * \return An identifier that maps to the packet identifier that are received using
+ * RIO_packetTid.
+ *
+ * This function creates and sends an NREAD request packet. The response packet will
+ * contain one byte of data. The reply is received using RIO_readResponseDone8().
+ *
+ * \note The address is a byte address, not a word address.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+void RIO_sendNread8( RioStack_t *stack, const uint16_t destid, const uint8_t tid, const uint32_t address );
+
+
+/**
+ * \brief Get the byte address from a NREAD packet.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The byte address contained in a NREAD packet.
+ *
+ * This function reads a received an NREAD request packet and fetches the address
+ * contained within.
+ *
+ * \note The address is a byte address, not a word address.
+ */
+uint32_t RIO_readNreadAddress8( RioStack_t *stack );
+
+/**
+ * \brief Get the number of bytes to read from a NREAD packet.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The number of bytes requested to read in a NREAD packet.
+ *
+ * This function reads a received an NREAD request packet and fetches the
+ * number of bytes to return in the reply.
+ *
+ * \note The returned size is the number of bytes.
+ */
+uint8_t RIO_readNreadSize8( RioStack_t *stack );
+
+/**
+ * \brief Get a doorbell info field.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The info field of a doorbell.
+ *
+ * This function is used to read and return the info field of a received doorbell.
+ */
+uint16_t RIO_readDoorbellInfo( RioStack_t *stack );
+
+/**
+ * \brief Send a byte message.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The device identifier of the target to send the message to.
+ * \param[in] mbox The mailbox to send the message to.
+ * \param[in] size The number of bytes to send.
+ * \param[in] data A pointer to an array of bytes to send. The parameter size indicates
+ * the number of bytes to send.
+ *
+ * This functions sends a message to a mailbox in an end-point target. A message response
+ * should be sent when the message has been processed using the RIO_sendMessageResponseDone(),
+ * RIO_sendMessageResponseRetry() or RIO_sendMessageResponseError() functions.
+ *
+ * \note All sizes that are transmitted are even double words. If 48-bits are
+ * sent then 64 bits will be received on the other side with the last bits
+ * padded to zero.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+void RIO_sendMessage8( RioStack_t *stack, const uint16_t destid, const uint8_t mbox, const uint16_t size, const uint8_t *data );
+
+/**
+ * \brief Read a received message mailbox.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The mailbox of a received message.
+ *
+ * This function returns the mailbox of an incoming message.
+ */
+uint8_t RIO_readMessageMbox( RioStack_t *stack );
+
+/**
+ * \brief Read a received message payload size in bytes.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The size in bytes of the received message payload.
+ *
+ * This function returns the number of bytes that was received in
+ * an incoming message.
+ *
+ * \note All sizes that are actually transmitted are even double words. If
+ * 48-bits are sent then 64 bits will be received on the other side with
+ * the last bits padded to zero.
+ */
+uint16_t RIO_readMessageSize8( RioStack_t *stack );
+
+/**
+ * \brief Get the payload of a received message.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[out] buffer A byte pointer to where to place the payload.
+ * \return None
+ * This function is used to copy the byte content of a received message.
+ */
+void RIO_readMessagePayload8( RioStack_t *stack, uint8_t *buffer );
+
+/**
+ * \brief Send a response with one byte data payload.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] destid The destination identifier of the response.
+ * \param[in] tid The transaction identifier for the reply. It should correspond to
+ * the tid in the received packet for which this response is sent.
+ * \param[in] address The byte address that was read.
+ * \param[in] data The data to return in the reply.
+ *
+ * This function creates a response packet with the specified destination
+ * identifier, transaction id and data payload. The generated packet are placed
+ * in the outbound packet queue.
+ *
+ * \note Call RIO_sendAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ */
+void RIO_sendResponseDone8( RioStack_t *stack, const uint16_t destid, const uint8_t tid, const uint32_t address, const uint8_t data );
+
+/**
+ * \brief Read a one byte payload from a response.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The byte data payload contained in the response.
+ *
+ * This function reads a response packet and returns a one byte payload
+ * contained within.
+ */
+uint8_t RIO_readResponseDone8( RioStack_t *stack );
+
+/**
+ * \brief Get the target mailbox.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return The target mailbox.
+ *
+ * This function is used to get the target mailbox of a message response.
+ */
+uint8_t RIO_readMessageResponseMbox( RioStack_t *stack );
+
+#endif /* _RIO_STACK_H */
+
+/*************************** end of file **************************************/
1.0.1/sw/stack/riostack.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/sw/codec/riocodecuart.c
===================================================================
--- 1.0.1/sw/codec/riocodecuart.c (nonexistent)
+++ 1.0.1/sw/codec/riocodecuart.c (revision 29)
@@ -0,0 +1,548 @@
+/*******************************************************************************
+ *
+ * RapidIO IP Library Core
+ *
+ * This file is part of the RapidIO IP library project
+ * http://www.opencores.org/cores/rio/
+ *
+ * Description:
+ * This file contains code that can serialize and deserialize rio symbols onto
+ * and from an 8-bit UART transmission channel.
+ *
+ * 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
+ *
+ *******************************************************************************/
+
+#include
+
+typedef enum
+{
+ RIO_SYMBOL_TYPE_IDLE, RIO_SYMBOL_TYPE_CONTROL,
+ RIO_SYMBOL_TYPE_DATA, RIO_SYMBOL_TYPE_ERROR
+} RioSymbolType;
+
+typedef struct
+{
+ RioSymbolType type;
+ uint32_t data;
+} RioSymbol;
+
+typedef struct
+{
+
+} RioStack_t;
+
+void RIO_portAddSymbol( RioStack_t *stack, const RioSymbol s );
+RioSymbol RIO_portGetSymbol( RioStack_t *stack );
+
+
+void receiveByte(RioStack_t *stack, uint8_t incoming)
+{
+ static RioSymbol rxSymbol;
+ static uint8_t flagFound = 0;
+ static uint8_t symbolCounter = 0;
+
+
+ if(incoming != 0x7e)
+ {
+ if(incoming != 0x7d)
+ {
+ if(flagFound)
+ {
+ incoming ^= 0x20;
+ }
+ else
+ {
+ /* Dont do anything. */
+ }
+
+ switch(symbolCounter)
+ {
+ case 0:
+ rxSymbol.type = RIO_SYMBOL_TYPE_ERROR;
+ rxSymbol.data = incoming;
+ symbolCounter++;
+ break;
+ case 1:
+ rxSymbol.type = RIO_SYMBOL_TYPE_ERROR;
+ rxSymbol.data <<= 8;
+ rxSymbol.data |= incoming;
+ symbolCounter++;
+ break;
+ case 2:
+ rxSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
+ rxSymbol.data <<= 8;
+ rxSymbol.data |= incoming;
+ symbolCounter++;
+ break;
+ case 3:
+ rxSymbol.type = RIO_SYMBOL_TYPE_DATA;
+ rxSymbol.data <<= 8;
+ rxSymbol.data |= incoming;
+
+ RIO_portAddSymbol(stack, rxSymbol);
+
+ rxSymbol.data = 0x00000000;
+ symbolCounter = 0;
+ break;
+ }
+
+ flagFound = 0;
+ }
+ else
+ {
+ flagFound = 1;
+ }
+ }
+ else
+ {
+ if(symbolCounter == 0)
+ {
+ rxSymbol.type = RIO_SYMBOL_TYPE_IDLE;
+ RIO_portAddSymbol(stack, rxSymbol);
+ }
+ else
+ {
+ RIO_portAddSymbol(stack, rxSymbol);
+ }
+
+ symbolCounter = 0;
+ }
+}
+
+uint8_t transmitByte(RioStack_t *stack)
+{
+ uint8_t returnValue;
+ static uint8_t symbolCounter = 3;
+ static uint8_t stuffing = 0;
+ static RioSymbol txSymbol;
+ uint8_t outbound;
+
+
+ /* Check if the previous symbol has been sent. */
+ if((symbolCounter == 3) && (stuffing == 0))
+ {
+ /* Symbol sent. */
+
+ /* Get a new symbol. */
+ txSymbol = RIO_portGetSymbol(stack);
+ if(txSymbol.type == RIO_SYMBOL_TYPE_CONTROL)
+ {
+ txSymbol.data <<= 8;
+ }
+ }
+ else
+ {
+ /* Symbol not sent. */
+ /* Continue to send the old symbol. */
+ }
+
+ /* Check if a flag should be sent. */
+ if ((txSymbol.type == RIO_SYMBOL_TYPE_IDLE) ||
+ ((stuffing == 0) && (symbolCounter == 0) && (txSymbol.type == RIO_SYMBOL_TYPE_CONTROL)))
+ {
+ /* A flag needs to be sent. */
+ /* An idle symbol should be sent as a flag and a control symbol should always be
+ terminated by a flag. */
+ returnValue = 0x7e;
+ symbolCounter = 3;
+ stuffing = 0;
+ }
+ else
+ {
+ /* A flag does not need to be sent. */
+
+ /* Get the current byte in the symbol. */
+ outbound = txSymbol.data >> (8*symbolCounter);
+
+ /* Check if stuffing is active. */
+ if(!stuffing)
+ {
+ /* No stuffing active. */
+
+ /* Check if the current byte needs to be stuffed. */
+ if((outbound != 0x7e) && (outbound != 0x7d))
+ {
+ /* The current byte does not need to be stuffed. */
+ returnValue = outbound;
+ symbolCounter = (symbolCounter - 1) & 0x3;
+ }
+ else
+ {
+ /* The current byte needs to be stuffed. */
+ returnValue = 0x7d;
+ stuffing = 1;
+ }
+ }
+ else
+ {
+ /* Stuffing is active. */
+ /* An escape sequence has been sent, transmit the original data but change it to not being a flag. */
+ returnValue = outbound ^ 0x20;
+ stuffing = 0;
+ symbolCounter = (symbolCounter - 1) & 0x3;
+ }
+ }
+
+ return returnValue;
+}
+
+
+
+/*******************************************************************************
+ * Module test code.
+ *******************************************************************************/
+
+#define TESTEXPR(got, expected) \
+ if ((got)!=(expected)) \
+ { \
+ printf("ERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n", \
+ __LINE__, #got, (got), (got), (expected), (expected)); \
+ exit(1); \
+ }
+static RioSymbol txSymbol;
+static uint8_t txNewSymbol;
+static RioSymbol rxSymbol;
+static uint8_t rxNewSymbol;
+void RIO_portAddSymbol( RioStack_t *stack, const RioSymbol s )
+{
+ rxNewSymbol = 1;
+ rxSymbol = s;
+}
+RioSymbol RIO_portGetSymbol( RioStack_t *stack )
+{
+ if(txNewSymbol)
+ {
+ txNewSymbol = 0;
+ return txSymbol;
+ }
+ else
+ {
+ RioSymbol s;
+ s.type = RIO_SYMBOL_TYPE_ERROR;
+ return s;
+ }
+}
+int main(int argc, char *argv[])
+{
+ RioStack_t *stack;
+
+ /***************************************************************
+ * Test receiver.
+ ***************************************************************/
+
+ /* Receive a flag. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_IDLE);
+
+ /* Receive not a flag followed by flag. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0xaa);
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_ERROR);
+
+ /* Receive not a flag twice followed by flag. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0xaa);
+ receiveByte(stack, 0x55);
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_ERROR);
+
+ /* Receive a control symbol followed by flag. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x11);
+ receiveByte(stack, 0x22);
+ receiveByte(stack, 0x33);
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_CONTROL);
+ TESTEXPR(rxSymbol.data, 0x00112233);
+
+ /* Receive a data symbol. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x44);
+ receiveByte(stack, 0x55);
+ receiveByte(stack, 0x66);
+ receiveByte(stack, 0x77);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
+ TESTEXPR(rxSymbol.data, 0x44556677);
+
+ /* Receive a back-to-back data symbol. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x88);
+ receiveByte(stack, 0x99);
+ receiveByte(stack, 0xaa);
+ receiveByte(stack, 0xbb);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
+ TESTEXPR(rxSymbol.data, 0x8899aabb);
+
+ /* Receive a back-to-back control symbol. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0xcc);
+ receiveByte(stack, 0xdd);
+ receiveByte(stack, 0xee);
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_CONTROL);
+ TESTEXPR(rxSymbol.data, 0x00ccddee);
+
+ /* Test control symbol with one stuffed byte. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0xff);
+ receiveByte(stack, 0x01);
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_CONTROL);
+ TESTEXPR(rxSymbol.data, 0x007eff01);
+
+ /* Test control symbol with two stuffed bytes. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0xff);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5d);
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_CONTROL);
+ TESTEXPR(rxSymbol.data, 0x007eff7d);
+
+ /* Test control symbol with three stuffed bytes. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5d);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5d);
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_CONTROL);
+ TESTEXPR(rxSymbol.data, 0x007d7e7d);
+
+ /* Test data symbol with one stuffed byte. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0x00);
+ receiveByte(stack, 0x01);
+ receiveByte(stack, 0x02);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
+ TESTEXPR(rxSymbol.data, 0x7e000102);
+
+ /* Test data symbol with two stuffed bytes. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5d);
+ receiveByte(stack, 0x03);
+ receiveByte(stack, 0x04);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
+ TESTEXPR(rxSymbol.data, 0x7e7d0304);
+
+ /* Test data symbol with three stuffed bytes. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5d);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0x05);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
+ TESTEXPR(rxSymbol.data, 0x7e7d7e05);
+
+ /* Test data symbol with four stuffed bytes. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5d);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5d);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
+ TESTEXPR(rxSymbol.data, 0x7e7d7e7d);
+
+ /***************************************************************
+ * Test transmitter.
+ ***************************************************************/
+
+ /* Test transmission of idle symbol. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_IDLE;
+ TESTEXPR(transmitByte(stack), 0x7e);
+
+ /* Test transmission of control symbol. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
+ txSymbol.data = 0x00112233;
+ TESTEXPR(transmitByte(stack), 0x11);
+ TESTEXPR(transmitByte(stack), 0x22);
+ TESTEXPR(transmitByte(stack), 0x33);
+ TESTEXPR(transmitByte(stack), 0x7e);
+
+ /* Test transmission of data symbol. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_DATA;
+ txSymbol.data = 0x44556677;
+ TESTEXPR(transmitByte(stack), 0x44);
+ TESTEXPR(transmitByte(stack), 0x55);
+ TESTEXPR(transmitByte(stack), 0x66);
+ TESTEXPR(transmitByte(stack), 0x77);
+
+ /* Test transmission of back-to-back data symbol. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_DATA;
+ txSymbol.data = 0x8899aabb;
+ TESTEXPR(transmitByte(stack), 0x88);
+ TESTEXPR(transmitByte(stack), 0x99);
+ TESTEXPR(transmitByte(stack), 0xaa);
+ TESTEXPR(transmitByte(stack), 0xbb);
+
+ /* Test transmission of back-to-back control symbol. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
+ txSymbol.data = 0xffccddee;
+ TESTEXPR(transmitByte(stack), 0xcc);
+ TESTEXPR(transmitByte(stack), 0xdd);
+ TESTEXPR(transmitByte(stack), 0xee);
+ TESTEXPR(transmitByte(stack), 0x7e);
+
+ /* Test transmission of back-to-back control symbol. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
+ txSymbol.data = 0xff010203;
+ TESTEXPR(transmitByte(stack), 0x01);
+ TESTEXPR(transmitByte(stack), 0x02);
+ TESTEXPR(transmitByte(stack), 0x03);
+ TESTEXPR(transmitByte(stack), 0x7e);
+
+ /* Test transmission of control symbol with one stuffed byte. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
+ txSymbol.data = 0xff7e0102;
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x01);
+ TESTEXPR(transmitByte(stack), 0x02);
+ TESTEXPR(transmitByte(stack), 0x7e);
+
+ /* Test transmission of stuffed control symbol with two stuffed bytes. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
+ txSymbol.data = 0xff7e7d01;
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5d);
+ TESTEXPR(transmitByte(stack), 0x01);
+ TESTEXPR(transmitByte(stack), 0x7e);
+
+ /* Test transmission of stuffed control symbol with three stuffed bytes. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
+ txSymbol.data = 0xff7e7d7e;
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5d);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x7e);
+
+ /* Test transmission of data symbol with one stuffed byte. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_DATA;
+ txSymbol.data = 0x7e010203;
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x01);
+ TESTEXPR(transmitByte(stack), 0x02);
+ TESTEXPR(transmitByte(stack), 0x03);
+
+ /* Test transmission of data symbol with two stuffed byte. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_DATA;
+ txSymbol.data = 0x7e7d0102;
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5d);
+ TESTEXPR(transmitByte(stack), 0x01);
+ TESTEXPR(transmitByte(stack), 0x02);
+
+ /* Test transmission of data symbol with three stuffed byte. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_DATA;
+ txSymbol.data = 0x7e7d7e01;
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5d);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x01);
+
+ /* Test transmission of data symbol with four stuffed byte. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_DATA;
+ txSymbol.data = 0x7e7d7e7d;
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5d);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5d);
+
+ /***************************************************************
+ * Test complete.
+ ***************************************************************/
+
+ printf("Test complete.\n");
+}
1.0.1/sw/codec/riocodecuart.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: 1.0.1/doc/rio.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: 1.0.1/doc/rio.pdf
===================================================================
--- 1.0.1/doc/rio.pdf (nonexistent)
+++ 1.0.1/doc/rio.pdf (revision 29)
1.0.1/doc/rio.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: 1.0.1/doc/rio.odt
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: 1.0.1/doc/rio.odt
===================================================================
--- 1.0.1/doc/rio.odt (nonexistent)
+++ 1.0.1/doc/rio.odt (revision 29)
1.0.1/doc/rio.odt
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property