URL
https://opencores.org/ocsvn/rio/rio/trunk
Subversion Repositories rio
Compare Revisions
- This comparison shows the changes necessary to convert path
/rio/trunk
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/bench/vhdl/TestRioSwitch.vhd
0,0 → 1,1265
------------------------------------------------------------------------------- |
-- |
-- RapidIO IP Library Core |
-- |
-- This file is part of the RapidIO IP library project |
-- http://www.opencores.org/cores/rio/ |
-- |
-- Description |
-- Contains automatic simulation test code to verify a RioSwitch implementation. |
-- |
-- To Do: |
-- - |
-- |
-- Author(s): |
-- - Magnus Rosenius, magro732@opencores.org |
-- |
------------------------------------------------------------------------------- |
-- |
-- Copyright (C) 2013 Authors and OPENCORES.ORG |
-- |
-- This source file may be used and distributed without |
-- restriction provided that this copyright statement is not |
-- removed from the file and that any derivative work contains |
-- the original copyright notice and the associated disclaimer. |
-- |
-- This source file is free software; you can redistribute it |
-- and/or modify it under the terms of the GNU Lesser General |
-- Public License as published by the Free Software Foundation; |
-- either version 2.1 of the License, or (at your option) any |
-- later version. |
-- |
-- This source is distributed in the hope that it will be |
-- useful, but WITHOUT ANY WARRANTY; without even the implied |
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
-- PURPOSE. See the GNU Lesser General Public License for more |
-- details. |
-- |
-- You should have received a copy of the GNU Lesser General |
-- Public License along with this source; if not, download it |
-- from http://www.opencores.org/lgpl.shtml |
-- |
------------------------------------------------------------------------------- |
|
|
------------------------------------------------------------------------------- |
-- TestRioSwitch. |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use ieee.math_real.all; |
library std; |
use std.textio.all; |
use work.rio_common.all; |
|
|
------------------------------------------------------------------------------- |
-- Entity for TestRioSwitch. |
------------------------------------------------------------------------------- |
entity TestRioSwitch is |
end entity; |
|
|
------------------------------------------------------------------------------- |
-- Architecture for TestRioSwitch. |
------------------------------------------------------------------------------- |
architecture TestRioSwitchImpl of TestRioSwitch is |
|
component RioSwitch is |
generic( |
SWITCH_PORTS : natural range 3 to 255 := 4; |
DEVICE_IDENTITY : std_logic_vector(15 downto 0); |
DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0); |
DEVICE_REV : std_logic_vector(31 downto 0); |
ASSY_IDENTITY : std_logic_vector(15 downto 0); |
ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0); |
ASSY_REV : std_logic_vector(15 downto 0)); |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
|
writeFrameFull_i : in Array1(SWITCH_PORTS-1 downto 0); |
writeFrame_o : out Array1(SWITCH_PORTS-1 downto 0); |
writeFrameAbort_o : out Array1(SWITCH_PORTS-1 downto 0); |
writeContent_o : out Array1(SWITCH_PORTS-1 downto 0); |
writeContentData_o : out Array32(SWITCH_PORTS-1 downto 0); |
|
readFrameEmpty_i : in Array1(SWITCH_PORTS-1 downto 0); |
readFrame_o : out Array1(SWITCH_PORTS-1 downto 0); |
readFrameRestart_o : out Array1(SWITCH_PORTS-1 downto 0); |
readFrameAborted_i : in Array1(SWITCH_PORTS-1 downto 0); |
readContentEmpty_i : in Array1(SWITCH_PORTS-1 downto 0); |
readContent_o : out Array1(SWITCH_PORTS-1 downto 0); |
readContentEnd_i : in Array1(SWITCH_PORTS-1 downto 0); |
readContentData_i : in Array32(SWITCH_PORTS-1 downto 0); |
|
portLinkTimeout_o : out std_logic_vector(23 downto 0); |
|
linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0); |
outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0); |
inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0); |
|
localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0); |
clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0); |
inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0); |
outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0); |
outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0); |
inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0); |
outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0); |
outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0); |
|
configStb_o : out std_logic; |
configWe_o : out std_logic; |
configAddr_o : out std_logic_vector(23 downto 0); |
configData_o : out std_logic_vector(31 downto 0); |
configData_i : in std_logic_vector(31 downto 0)); |
end component; |
|
component TestPort is |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
|
frameValid_i : in std_logic; |
frameWrite_i : in RioFrame; |
frameComplete_o : out std_logic; |
|
frameExpected_i : in std_logic; |
frameRead_i : in RioFrame; |
frameReceived_o : out std_logic; |
|
readFrameEmpty_o : out std_logic; |
readFrame_i : in std_logic; |
readFrameRestart_i : in std_logic; |
readFrameAborted_o : out std_logic; |
readContentEmpty_o : out std_logic; |
readContent_i : in std_logic; |
readContentEnd_o : out std_logic; |
readContentData_o : out std_logic_vector(31 downto 0); |
writeFrameFull_o : out std_logic; |
writeFrame_i : in std_logic; |
writeFrameAbort_i : in std_logic; |
writeContent_i : in std_logic; |
writeContentData_i : in std_logic_vector(31 downto 0)); |
end component; |
|
constant PORTS : natural := 7; |
constant SWITCH_IDENTITY : std_logic_vector(15 downto 0) := x"0123"; |
constant SWITCH_VENDOR_IDENTITY : std_logic_vector(15 downto 0) := x"4567"; |
constant SWITCH_REV : std_logic_vector(31 downto 0) := x"89abcdef"; |
constant SWITCH_ASSY_IDENTITY : std_logic_vector(15 downto 0) := x"0011"; |
constant SWITCH_ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0) := x"2233"; |
constant SWITCH_ASSY_REV : std_logic_vector(15 downto 0) := x"4455"; |
|
signal clk : std_logic; |
signal areset_n : std_logic; |
|
signal frameValid : Array1(PORTS-1 downto 0); |
signal frameWrite : RioFrameArray(PORTS-1 downto 0); |
signal frameComplete : Array1(PORTS-1 downto 0); |
|
signal frameExpected : Array1(PORTS-1 downto 0); |
signal frameRead : RioFrameArray(PORTS-1 downto 0); |
signal frameReceived : Array1(PORTS-1 downto 0); |
|
signal writeFrameFull : Array1(PORTS-1 downto 0); |
signal writeFrame : Array1(PORTS-1 downto 0); |
signal writeFrameAbort : Array1(PORTS-1 downto 0); |
signal writeContent : Array1(PORTS-1 downto 0); |
signal writeContentData : Array32(PORTS-1 downto 0); |
|
signal readFrameEmpty : Array1(PORTS-1 downto 0); |
signal readFrame : Array1(PORTS-1 downto 0); |
signal readFrameRestart : Array1(PORTS-1 downto 0); |
signal readFrameAborted : Array1(PORTS-1 downto 0); |
signal readContentEmpty : Array1(PORTS-1 downto 0); |
signal readContent : Array1(PORTS-1 downto 0); |
signal readContentEnd : Array1(PORTS-1 downto 0); |
signal readContentData : Array32(PORTS-1 downto 0); |
|
signal portLinkTimeout : std_logic_vector(23 downto 0); |
|
signal linkInitialized : Array1(PORTS-1 downto 0); |
signal outputPortEnable : Array1(PORTS-1 downto 0); |
signal inputPortEnable : Array1(PORTS-1 downto 0); |
|
signal localAckIdWrite : Array1(PORTS-1 downto 0); |
signal clrOutstandingAckId : Array1(PORTS-1 downto 0); |
signal inboundAckIdWrite : Array5(PORTS-1 downto 0); |
signal outstandingAckIdWrite : Array5(PORTS-1 downto 0); |
signal outboundAckIdWrite : Array5(PORTS-1 downto 0); |
signal inboundAckIdRead : Array5(PORTS-1 downto 0); |
signal outstandingAckIdRead : Array5(PORTS-1 downto 0); |
signal outboundAckIdRead : Array5(PORTS-1 downto 0); |
|
signal configStb, configStbExpected : std_logic; |
signal configWe, configWeExpected : std_logic; |
signal configAddr, configAddrExpected : std_logic_vector(23 downto 0); |
signal configDataWrite, configDataWriteExpected : std_logic_vector(31 downto 0); |
signal configDataRead, configDataReadExpected : std_logic_vector(31 downto 0); |
|
begin |
|
----------------------------------------------------------------------------- |
-- Clock generation. |
----------------------------------------------------------------------------- |
ClockGenerator: process |
begin |
clk <= '0'; |
wait for 20 ns; |
clk <= '1'; |
wait for 20 ns; |
end process; |
|
|
----------------------------------------------------------------------------- |
-- Serial port emulator. |
----------------------------------------------------------------------------- |
TestDriver: process |
|
--------------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------------- |
procedure SendFrame(constant portIndex : natural range 0 to 7; |
constant frame : RioFrame) is |
begin |
frameValid(portIndex) <= '1'; |
frameWrite(portIndex) <= frame; |
wait until frameComplete(portIndex) = '1'; |
frameValid(portIndex) <= '0'; |
end procedure; |
|
--------------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------------- |
procedure ReceiveFrame(constant portIndex : natural range 0 to 7; |
constant frame : RioFrame) is |
begin |
frameExpected(portIndex) <= '1'; |
frameRead(portIndex) <= frame; |
wait until frameReceived(portIndex) = '1'; |
frameExpected(portIndex) <= '0'; |
end procedure; |
|
--------------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------------- |
procedure ReadConfig32(constant portIndex : natural range 0 to 7; |
constant destinationId : std_logic_vector(15 downto 0); |
constant sourceId : std_logic_vector(15 downto 0); |
constant hop : std_logic_vector(7 downto 0); |
constant tid : std_logic_vector(7 downto 0); |
constant address : std_logic_vector(23 downto 0); |
constant data : std_logic_vector(31 downto 0)) is |
variable maintData : DoubleWordArray(0 to 7); |
begin |
SendFrame(portIndex, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
sourceId=>sourceId, destId=>destinationId, |
payload=>RioMaintenance(transaction=>"0000", |
size=>"1000", |
tid=>tid, |
hopCount=>hop, |
configOffset=>address(23 downto 3), |
wdptr=>address(2), |
dataLength=>0, |
data=>maintData))); |
if (address(2) = '0') then |
maintData(0) := data & x"00000000"; |
else |
maintData(0) := x"00000000" & data ; |
end if; |
|
ReceiveFrame(portIndex, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
sourceId=>destinationId, destId=>sourceId, |
payload=>RioMaintenance(transaction=>"0010", |
size=>"0000", |
tid=>tid, |
hopCount=>x"ff", |
configOffset=>"000000000000000000000", |
wdptr=>'0', |
dataLength=>1, |
data=>maintData))); |
end procedure; |
|
--------------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------------- |
procedure WriteConfig32(constant portIndex : natural range 0 to 7; |
constant destinationId : std_logic_vector(15 downto 0); |
constant sourceId : std_logic_vector(15 downto 0); |
constant hop : std_logic_vector(7 downto 0); |
constant tid : std_logic_vector(7 downto 0); |
constant address : std_logic_vector(23 downto 0); |
constant data : std_logic_vector(31 downto 0)) is |
variable maintData : DoubleWordArray(0 to 7); |
begin |
if (address(2) = '0') then |
maintData(0) := data & x"00000000"; |
else |
maintData(0) := x"00000000" & data ; |
end if; |
|
SendFrame(portIndex, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
sourceId=>sourceId, destId=>destinationId, |
payload=>RioMaintenance(transaction=>"0001", |
size=>"1000", |
tid=>tid, |
hopCount=>hop, |
configOffset=>address(23 downto 3), |
wdptr=>address(2), |
dataLength=>1, |
data=>maintData))); |
|
ReceiveFrame(portIndex, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
sourceId=>destinationId, destId=>sourceId, |
payload=>RioMaintenance(transaction=>"0011", |
size=>"0000", |
tid=>tid, |
hopCount=>x"ff", |
configOffset=>"000000000000000000000", |
wdptr=>'0', |
dataLength=>0, |
data=>maintData))); |
end procedure; |
|
--------------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------------- |
procedure RouteFrame(constant sourcePortIndex : natural range 0 to 7; |
constant destinationPortIndex : natural range 0 to 7; |
constant sourceId : std_logic_vector(15 downto 0); |
constant destinationId : std_logic_vector(15 downto 0); |
constant payload : RioPayload) is |
variable frame : RioFrame; |
begin |
frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>"0000", |
sourceId=>sourceId, destId=>destinationId, |
payload=>payload); |
|
frameExpected(destinationPortIndex) <= '1'; |
frameRead(destinationPortIndex) <= frame; |
|
frameValid(sourcePortIndex) <= '1'; |
frameWrite(sourcePortIndex) <= frame; |
wait until frameComplete(sourcePortIndex) = '1'; |
frameValid(sourcePortIndex) <= '0'; |
|
wait until frameReceived(destinationPortIndex) = '1'; |
frameExpected(destinationPortIndex) <= '0'; |
|
end procedure; |
|
--------------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------------- |
procedure SendFrame(constant portIndex : natural range 0 to 7; |
constant sourceId : std_logic_vector(15 downto 0); |
constant destinationId : std_logic_vector(15 downto 0); |
constant payload : RioPayload) is |
variable frame : RioFrame; |
begin |
frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>"0000", |
sourceId=>sourceId, destId=>destinationId, |
payload=>payload); |
|
frameValid(portIndex) <= '1'; |
frameWrite(portIndex) <= frame; |
end procedure; |
|
--------------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------------- |
procedure ReceiveFrame(constant portIndex : natural range 0 to 7; |
constant sourceId : std_logic_vector(15 downto 0); |
constant destinationId : std_logic_vector(15 downto 0); |
constant payload : RioPayload) is |
variable frame : RioFrame; |
begin |
frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>"0000", |
sourceId=>sourceId, destId=>destinationId, |
payload=>payload); |
|
frameExpected(portIndex) <= '1'; |
frameRead(portIndex) <= frame; |
end procedure; |
|
-- These variabels are needed for the random number generation. |
variable seed1 : positive := 1; |
variable seed2: positive := 1; |
|
variable data : DoubleWordArray(0 to 31); |
variable randomPayload : RioPayload; |
variable randomPayload1 : RioPayload; |
variable randomPayload2 : RioPayload; |
variable frame : RioFrameArray(0 to PORTS-1); |
|
begin |
areset_n <= '0'; |
|
linkInitialized <= (others=>'0'); |
|
for portIndex in 0 to PORTS-1 loop |
frameValid(portIndex) <= '0'; |
frameExpected(portIndex) <= '0'; |
localAckIdWrite(portIndex) <= '0'; |
clrOutstandingAckId(portIndex) <= '0'; |
inboundAckIdWrite(portIndex) <= (others=>'0'); |
outstandingAckIdWrite(portIndex) <= (others=>'0'); |
outboundAckIdWrite(portIndex) <= (others=>'0'); |
end loop; |
|
wait until clk'event and clk = '1'; |
wait until clk'event and clk = '1'; |
areset_n <= '1'; |
wait until clk'event and clk = '1'; |
wait until clk'event and clk = '1'; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("TG_RioSwitch"); |
PrintS("-----------------------------------------------------------------"); |
PrintS("TG_RioSwitch-TC1"); |
PrintS("Description: Test switch maintenance accesses on different ports."); |
PrintS("Requirement: XXXXX"); |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 1:"); |
PrintS("Action: Send maintenance read request packets to read switch identity."); |
PrintS("Result: The switch should answer with its configured identitiy."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC1-Step1"); |
--------------------------------------------------------------------------- |
|
ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"00", address=>x"000000", data=>(SWITCH_IDENTITY & SWITCH_VENDOR_IDENTITY)); |
ReadConfig32(portIndex=>1, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"01", address=>x"000004", data=>SWITCH_REV); |
ReadConfig32(portIndex=>2, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"02", address=>x"000008", data=>(SWITCH_ASSY_IDENTITY & SWITCH_ASSY_VENDOR_IDENTITY)); |
ReadConfig32(portIndex=>3, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"03", address=>x"00000c", data=>(SWITCH_ASSY_REV & x"0100")); |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 2:"); |
PrintS("Action: Check the switch Processing Element Features."); |
PrintS("Result: The expected switch features should be returned. "); |
PrintS(" Switch with extended features pointer valid. Common "); |
PrintS(" transport large system support and standard route table "); |
PrintS(" configuration support."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC1-Step2"); |
--------------------------------------------------------------------------- |
|
ReadConfig32(portIndex=>4, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"04", address=>x"000010", data=>x"10000118"); |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 3:"); |
PrintS("Action: Check the switch port information."); |
PrintS("Result: The expected port and number of ports should be returned."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC1-Step3"); |
--------------------------------------------------------------------------- |
|
ReadConfig32(portIndex=>5, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"05", address=>x"000014", data=>x"00000705"); |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 4:"); |
PrintS("Action: Check the switch number of supported routes."); |
PrintS("Result: The expected number of supported routes should be returned."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC1-Step4"); |
--------------------------------------------------------------------------- |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000034", data=>x"00000800"); |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 5:"); |
PrintS("Action: Test host base device id lock by reading it, then hold it "); |
PrintS(" and try to grab it from another address."); |
PrintS("Result: The value should follow the specification."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC1-Step5"); |
--------------------------------------------------------------------------- |
|
-- Check that the lock is released. |
ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"00", address=>x"000068", data=>x"0000ffff"); |
|
-- Try to accuire the lock. |
WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"00", address=>x"000068", data=>x"00000002"); |
|
-- Check that the lock has been accuired. |
ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"00", address=>x"000068", data=>x"00000002"); |
|
-- Try to accuire the lock from another source. |
WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"00", address=>x"000068", data=>x"00000003"); |
|
-- Check that the lock refuses the new access. |
ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"00", address=>x"000068", data=>x"00000002"); |
|
-- Release the lock. |
WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"00", address=>x"000068", data=>x"00000002"); |
|
-- Check that the lock is released. |
ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"00", address=>x"000068", data=>x"0000ffff"); |
|
-- Check that the lock can be accuired from another source once unlocked. |
WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"00", address=>x"000068", data=>x"00000003"); |
|
-- Check that the lock is released. |
ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"00", address=>x"000068", data=>x"00000003"); |
|
-- Release the lock again. |
WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"00", address=>x"000068", data=>x"00000003"); |
|
-- Check that the lock is released. |
ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"00", address=>x"000068", data=>x"0000ffff"); |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 6"); |
PrintS("Action: Check the component tag register."); |
PrintS("Result: The written value in the component tag should be saved."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC1-Step6"); |
--------------------------------------------------------------------------- |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00006c", data=>x"00000000"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00006c", data=>x"ffffffff"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00006c", data=>x"ffffffff"); |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 7"); |
PrintS("Action: Read and write to the port link timeout."); |
PrintS("Result: Check that the portLinkTimeout output from the switch changes."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC1-Step7"); |
--------------------------------------------------------------------------- |
|
assert portLinkTimeout = x"ffffff" report "Unexpected portLinkTimeout." severity error; |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000120", data=>x"ffffff00"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000120", data=>x"00000100"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000120", data=>x"00000100"); |
|
assert portLinkTimeout = x"000001" report "Unexpected portLinkTimeout." severity error; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 8"); |
PrintS("Action: Read from the port general control."); |
PrintS("Result: Check the discovered bit."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC1-Step8"); |
--------------------------------------------------------------------------- |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00013c", data=>x"00000000"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00013c", data=>x"20000000"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00013c", data=>x"20000000"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00013c", data=>x"00000000"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00013c", data=>x"00000000"); |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 9"); |
PrintS("Action: Read from the port N error and status."); |
PrintS("Result: Check the port ok and port uninitialized bits."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC1-Step9"); |
--------------------------------------------------------------------------- |
|
linkInitialized(0) <= '0'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000158", data=>x"00000001"); |
linkInitialized(0) <= '1'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000158", data=>x"00000002"); |
|
linkInitialized(1) <= '0'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000178", data=>x"00000001"); |
linkInitialized(1) <= '1'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000178", data=>x"00000002"); |
|
linkInitialized(2) <= '0'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000198", data=>x"00000001"); |
linkInitialized(2) <= '1'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000198", data=>x"00000002"); |
|
linkInitialized(3) <= '0'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001b8", data=>x"00000001"); |
linkInitialized(3) <= '1'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001b8", data=>x"00000002"); |
|
linkInitialized(4) <= '0'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001d8", data=>x"00000001"); |
linkInitialized(4) <= '1'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001d8", data=>x"00000002"); |
|
linkInitialized(5) <= '0'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001f8", data=>x"00000001"); |
linkInitialized(5) <= '1'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001f8", data=>x"00000002"); |
|
linkInitialized(6) <= '0'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000218", data=>x"00000001"); |
linkInitialized(6) <= '1'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000218", data=>x"00000002"); |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 10"); |
PrintS("Action: Read and write to/from the port N control."); |
PrintS("Result: Check the output/input port enable."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC1-Step10"); |
--------------------------------------------------------------------------- |
|
assert outputPortEnable(0) = '0' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(0) = '0' report "Unexpected inputPortEnable." severity error; |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00015c", data=>x"00000001"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00015c", data=>x"00600001"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00015c", data=>x"00600001"); |
|
assert outputPortEnable(0) = '1' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(0) = '1' report "Unexpected inputPortEnable." severity error; |
|
--------------------------------------------------------------------------- |
|
assert outputPortEnable(1) = '0' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(1) = '0' report "Unexpected inputPortEnable." severity error; |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00017c", data=>x"00000001"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00017c", data=>x"00600001"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00017c", data=>x"00600001"); |
|
assert outputPortEnable(1) = '1' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(1) = '1' report "Unexpected inputPortEnable." severity error; |
|
--------------------------------------------------------------------------- |
|
assert outputPortEnable(2) = '0' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(2) = '0' report "Unexpected inputPortEnable." severity error; |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00019c", data=>x"00000001"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00019c", data=>x"00600001"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00019c", data=>x"00600001"); |
|
assert outputPortEnable(2) = '1' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(2) = '1' report "Unexpected inputPortEnable." severity error; |
|
--------------------------------------------------------------------------- |
|
assert outputPortEnable(3) = '0' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(3) = '0' report "Unexpected inputPortEnable." severity error; |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001bc", data=>x"00000001"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001bc", data=>x"00600001"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001bc", data=>x"00600001"); |
|
assert outputPortEnable(3) = '1' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(3) = '1' report "Unexpected inputPortEnable." severity error; |
|
--------------------------------------------------------------------------- |
|
assert outputPortEnable(4) = '0' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(4) = '0' report "Unexpected inputPortEnable." severity error; |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001dc", data=>x"00000001"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001dc", data=>x"00600001"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001dc", data=>x"00600001"); |
|
assert outputPortEnable(4) = '1' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(4) = '1' report "Unexpected inputPortEnable." severity error; |
|
--------------------------------------------------------------------------- |
|
assert outputPortEnable(5) = '0' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(5) = '0' report "Unexpected inputPortEnable." severity error; |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001fc", data=>x"00000001"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001fc", data=>x"00600001"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001fc", data=>x"00600001"); |
|
assert outputPortEnable(5) = '1' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(5) = '1' report "Unexpected inputPortEnable." severity error; |
|
--------------------------------------------------------------------------- |
|
assert outputPortEnable(6) = '0' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(6) = '0' report "Unexpected inputPortEnable." severity error; |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00021c", data=>x"00000001"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00021c", data=>x"00600001"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00021c", data=>x"00600001"); |
|
assert outputPortEnable(6) = '1' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(6) = '1' report "Unexpected inputPortEnable." severity error; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 11"); |
PrintS("Action: Read and write to/from the implementation defined space."); |
PrintS("Result: Check the accesses on the external configuration port."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC1-Step11"); |
--------------------------------------------------------------------------- |
|
configStbExpected <= '1'; |
configWeExpected <= '0'; |
configAddrExpected <= x"010000"; |
configDataReadExpected <= x"deadbeef"; |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"010000", data=>x"deadbeef"); |
|
configStbExpected <= '1'; |
configWeExpected <= '1'; |
configAddrExpected <= x"010004"; |
configDataWriteExpected <= x"c0debabe"; |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"010004", data=>x"c0debabe"); |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("TG_RioSwitch-TC2"); |
PrintS("Description: Test the configuration of the routing table and the "); |
PrintS(" routing of packets."); |
PrintS("Requirement: XXXXX"); |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 1:"); |
PrintS("Action: Configure the routing table for address 0->port 1."); |
PrintS("Result: A packet to address 0 should be forwarded to port 1."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC2-Step1"); |
--------------------------------------------------------------------------- |
|
ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"07", address=>x"000070", data=>x"00000000"); |
WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"08", address=>x"000074", data=>x"00000001"); |
ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"09", address=>x"000074", data=>x"00000001"); |
|
-- Send a frame from a port and check if it is correctly routed. |
randomPayload.length := 3; |
CreateRandomPayload(randomPayload.data, seed1, seed2); |
RouteFrame(sourcePortIndex=>0, destinationPortIndex=>1, |
sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload); |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 2:"); |
PrintS("Action: Test the configuration of the default route->port 6."); |
PrintS("Result: An unknown address should be routed to port 6."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC2-Step2"); |
--------------------------------------------------------------------------- |
|
ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"0a", address=>x"000078", data=>x"00000000"); |
WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"0b", address=>x"000078", data=>x"00000006"); |
ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"0c", address=>x"000078", data=>x"00000006"); |
|
-- Send a frame from a port and check if it is correctly routed. |
randomPayload.length := 4; |
CreateRandomPayload(randomPayload.data, seed1, seed2); |
RouteFrame(sourcePortIndex=>1, destinationPortIndex=>6, |
sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload); |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("TG_RioSwitch-TC3"); |
PrintS("Description: Test the routing of normal packets."); |
PrintS("Requirement: XXXXX"); |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 1:"); |
PrintS("Action: Send two packets but not the same time."); |
PrintS("Result: Both packets should be received at the expected ports."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC3-Step1"); |
--------------------------------------------------------------------------- |
|
-- Frame on port 0 to port 1. |
randomPayload.length := 3; |
CreateRandomPayload(randomPayload.data, seed1, seed2); |
SendFrame(portIndex=>0, |
sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload); |
ReceiveFrame(portIndex=>1, |
sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload); |
|
-- Frame on port 1 to port 6. |
randomPayload.length := 4; |
CreateRandomPayload(randomPayload.data, seed1, seed2); |
SendFrame(portIndex=>1, |
sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload); |
ReceiveFrame(portIndex=>6, |
sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload); |
|
wait until frameComplete(1) = '1'; |
frameValid(1) <= '0'; |
wait until frameReceived(6) = '1'; |
frameExpected(6) <= '0'; |
|
wait until frameComplete(0) = '1'; |
frameValid(0) <= '0'; |
wait until frameReceived(1) = '1'; |
frameExpected(1) <= '0'; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 2:"); |
PrintS("Action: Send two packets to the same port with is full and one to"); |
PrintS(" another that is also full. Then receive the packets one at"); |
PrintS(" a time."); |
PrintS("Result: The packet to the port that is ready should go though."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC3-Step2"); |
--------------------------------------------------------------------------- |
|
-- Frame on port 0 to port 1. |
randomPayload.length := 5; |
CreateRandomPayload(randomPayload.data, seed1, seed2); |
SendFrame(portIndex=>0, |
sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload); |
|
-- Frame on port 1 to port 6. |
randomPayload1.length := 6; |
CreateRandomPayload(randomPayload1.data, seed1, seed2); |
SendFrame(portIndex=>1, |
sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload1); |
|
-- Frame on port 2 to port 6. |
randomPayload2.length := 7; |
CreateRandomPayload(randomPayload2.data, seed1, seed2); |
SendFrame(portIndex=>2, |
sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload2); |
|
wait for 10 us; |
|
ReceiveFrame(portIndex=>1, |
sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload); |
wait until frameComplete(0) = '1'; |
frameValid(0) <= '0'; |
wait until frameReceived(1) = '1'; |
frameExpected(1) <= '0'; |
|
wait for 10 us; |
|
ReceiveFrame(portIndex=>6, |
sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload1); |
wait until frameComplete(1) = '1'; |
frameValid(1) <= '0'; |
wait until frameReceived(6) = '1'; |
frameExpected(6) <= '0'; |
|
wait for 10 us; |
|
ReceiveFrame(portIndex=>6, |
sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload2); |
wait until frameComplete(2) = '1'; |
frameValid(2) <= '0'; |
wait until frameReceived(6) = '1'; |
frameExpected(6) <= '0'; |
|
--------------------------------------------------------------------------- |
-- Test completed. |
--------------------------------------------------------------------------- |
|
wait for 10 us; |
|
assert readContentEmpty = "1111111" |
report "Pending frames exist." severity error; |
|
TestEnd; |
end process; |
|
----------------------------------------------------------------------------- |
-- Instantiate a process receiving the configuration accesses to the |
-- implementation defined space. |
----------------------------------------------------------------------------- |
process |
begin |
loop |
wait until configStb = '1' and clk'event and clk = '1'; |
assert configStb = configStbExpected report "Unexpected configStb." severity error; |
assert configWe = configWeExpected report "Unexpected configWe." severity error; |
assert configAddr = configAddrExpected report "Unexpected configAddr." severity error; |
if (configWe = '1') then |
assert configDataWrite = configDataWriteExpected report "Unexpected configDataWrite." severity error; |
else |
configDataRead <= configDataReadExpected; |
end if; |
end loop; |
end process; |
|
----------------------------------------------------------------------------- |
-- Instantiate the test port array. |
----------------------------------------------------------------------------- |
|
TestPortGeneration: for portIndex in 0 to PORTS-1 generate |
TestPortInst: TestPort |
port map( |
clk=>clk, areset_n=>areset_n, |
frameValid_i=>frameValid(portIndex), |
frameWrite_i=>frameWrite(portIndex), |
frameComplete_o=>frameComplete(portIndex), |
frameExpected_i=>frameExpected(portIndex), |
frameRead_i=>frameRead(portIndex), |
frameReceived_o=>frameReceived(portIndex), |
readFrameEmpty_o=>readFrameEmpty(portIndex), |
readFrame_i=>readFrame(portIndex), |
readFrameRestart_i=>readFrameRestart(portIndex), |
readFrameAborted_o=>readFrameAborted(portIndex), |
readContentEmpty_o=>readContentEmpty(portIndex), |
readContent_i=>readContent(portIndex), |
readContentEnd_o=>readContentEnd(portIndex), |
readContentData_o=>readContentData(portIndex), |
writeFrameFull_o=>writeFrameFull(portIndex), |
writeFrame_i=>writeFrame(portIndex), |
writeFrameAbort_i=>writeFrameAbort(portIndex), |
writeContent_i=>writeContent(portIndex), |
writeContentData_i=>writeContentData(portIndex)); |
end generate; |
|
----------------------------------------------------------------------------- |
-- Instantiate the switch. |
----------------------------------------------------------------------------- |
|
TestSwitch: RioSwitch |
generic map( |
SWITCH_PORTS=>7, |
DEVICE_IDENTITY=>SWITCH_IDENTITY, |
DEVICE_VENDOR_IDENTITY=>SWITCH_VENDOR_IDENTITY, |
DEVICE_REV=>SWITCH_REV, |
ASSY_IDENTITY=>SWITCH_ASSY_IDENTITY, |
ASSY_VENDOR_IDENTITY=>SWITCH_ASSY_VENDOR_IDENTITY, |
ASSY_REV=>SWITCH_ASSY_REV) |
port map( |
clk=>clk, areset_n=>areset_n, |
writeFrameFull_i=>writeFrameFull, |
writeFrame_o=>writeFrame, writeFrameAbort_o=>writeFrameAbort, |
writeContent_o=>writeContent, writeContentData_o=>writeContentData, |
readFrameEmpty_i=>readFrameEmpty, |
readFrame_o=>readFrame, readFrameRestart_o=>readFrameRestart, |
readFrameAborted_i=>readFrameAborted, |
readContentEmpty_i=>readContentEmpty, |
readContent_o=>readContent, readContentEnd_i=>readContentEnd, |
readContentData_i=>readContentData, |
portLinkTimeout_o=>portLinkTimeout, |
linkInitialized_i=>linkInitialized, |
outputPortEnable_o=>outputPortEnable, inputPortEnable_o=>inputPortEnable, |
localAckIdWrite_o=>localAckIdWrite, |
clrOutstandingAckId_o=>clrOutstandingAckId, |
inboundAckId_o=>inboundAckIdWrite, |
outstandingAckId_o=>outstandingAckIdWrite, |
outboundAckId_o=>outboundAckIdWrite, |
inboundAckId_i=>inboundAckIdRead, |
outstandingAckId_i=>outstandingAckIdRead, |
outboundAckId_i=>outboundAckIdRead, |
configStb_o=>configStb, configWe_o=>configWe, configAddr_o=>configAddr, |
configData_o=>configDataWrite, configData_i=>configDataRead); |
|
|
end architecture; |
|
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
-- REMARK: Add support for testing partially complete frames, cut-through-routing... |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
library std; |
use std.textio.all; |
use work.rio_common.all; |
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
entity TestPort is |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
|
frameValid_i : in std_logic; |
frameWrite_i : in RioFrame; |
frameComplete_o : out std_logic; |
|
frameExpected_i : in std_logic; |
frameRead_i : in RioFrame; |
frameReceived_o : out std_logic; |
|
readFrameEmpty_o : out std_logic; |
readFrame_i : in std_logic; |
readFrameRestart_i : in std_logic; |
readFrameAborted_o : out std_logic; |
readContentEmpty_o : out std_logic; |
readContent_i : in std_logic; |
readContentEnd_o : out std_logic; |
readContentData_o : out std_logic_vector(31 downto 0); |
|
writeFrameFull_o : out std_logic; |
writeFrame_i : in std_logic; |
writeFrameAbort_i : in std_logic; |
writeContent_i : in std_logic; |
writeContentData_i : in std_logic_vector(31 downto 0)); |
end entity; |
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
architecture TestPortImpl of TestPort is |
begin |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
FrameReader: process |
type StateType is (STATE_IDLE, STATE_WRITE); |
variable state : StateType; |
variable frameIndex : natural range 0 to 69; |
begin |
writeFrameFull_o <= '1'; |
frameReceived_o <= '0'; |
wait until areset_n = '1'; |
|
state := STATE_IDLE; |
|
loop |
wait until clk'event and clk = '1'; |
|
case state is |
|
when STATE_IDLE => |
frameReceived_o <= '0'; |
if (frameExpected_i = '1') then |
writeFrameFull_o <= '0'; |
state := STATE_WRITE; |
frameIndex := 0; |
else |
writeFrameFull_o <= '1'; |
end if; |
assert writeFrame_i = '0' report "Unexpected frame." severity error; |
assert writeFrameAbort_i = '0' report "Unexpected frame abort." severity error; |
assert writeContent_i = '0' report "Unexpected data." severity error; |
|
when STATE_WRITE => |
if (writeContent_i = '1') then |
-- Writing content. |
if (frameIndex < frameRead_i.length) then |
assert writeContentData_i = frameRead_i.payload(frameIndex) |
report "Unexpected frame content received:" & |
" index=" & integer'image(frameIndex) & |
" expected=" & integer'image(to_integer(unsigned(frameRead_i.payload(frameIndex)))) & |
" got=" & integer'image(to_integer(unsigned(writeContentData_i))) |
severity error; |
|
frameIndex := frameIndex + 1; |
else |
report "Unexpected frame content received:" & |
" index=" & integer'image(frameIndex) & |
" expected=" & integer'image(to_integer(unsigned(frameRead_i.payload(frameIndex)))) & |
" got=" & integer'image(to_integer(unsigned(writeContentData_i))) |
severity error; |
|
frameIndex := frameIndex + 1; |
end if; |
else |
-- Not writing any content. |
end if; |
|
if (writeFrame_i = '1') then |
-- Writing a complete frame. |
assert frameIndex = frameRead_i.length report "Unexpected frame length received." severity error; |
state := STATE_IDLE; |
frameReceived_o <= '1'; |
writeFrameFull_o <= '1'; |
else |
-- Not writing any frame. |
end if; |
|
if (writeFrameAbort_i = '1') then |
-- The frame should be aborted. |
frameIndex := 0; |
else |
-- Not aborting any frame. |
end if; |
end case; |
end loop; |
end process; |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
-- REMARK: add support for these signals... |
-- readFrameEmpty_i : in std_logic; |
-- readFrameAborted_i : in std_logic; |
FrameSender: process |
type StateType is (STATE_IDLE, STATE_READ); |
variable state : StateType; |
variable frameIndex : natural range 0 to 69; |
begin |
readFrameEmpty_o <= '1'; |
readFrameAborted_o <= '0'; |
readContentEmpty_o <= '1'; |
readContentEnd_o <= '1'; |
readContentData_o <= (others => 'U'); |
frameComplete_o <= '0'; |
wait until areset_n = '1'; |
|
state := STATE_IDLE; |
|
loop |
wait until clk'event and clk = '1'; |
|
case state is |
|
when STATE_IDLE => |
frameComplete_o <= '0'; |
if (frameValid_i = '1') then |
state := STATE_READ; |
frameIndex := 0; |
readContentEmpty_o <= '0'; |
readFrameEmpty_o <= '0'; |
else |
readContentEmpty_o <= '1'; |
end if; |
|
when STATE_READ => |
if (readFrameRestart_i = '1') then |
readContentEnd_o <= '0'; |
frameIndex := 0; |
else |
-- Not restarting a frame. |
end if; |
|
if (readContent_i = '1') then |
if (frameIndex < frameWrite_i.length) then |
readContentData_o <= frameWrite_i.payload(frameIndex); |
readContentEnd_o <= '0'; |
frameIndex := frameIndex + 1; |
elsif (frameIndex = frameWrite_i.length) then |
readContentEnd_o <= '1'; |
else |
report "Reading empty frame." severity error; |
end if; |
else |
-- Not reading data. |
end if; |
|
if (readFrame_i = '1') then |
state := STATE_IDLE; |
assert frameIndex = frameWrite_i.length report "Unread frame data discarded." severity error; |
frameComplete_o <= '1'; |
readFrameEmpty_o <= '1'; |
readContentEmpty_o <= '1'; |
readContentData_o <= (others => 'U'); |
else |
-- Not reading a frame. |
end if; |
|
end case; |
end loop; |
end process; |
|
end architecture; |
bench/vhdl/TestRioSwitch.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: rtl/vhdl/RioCommon.vhd
===================================================================
--- rtl/vhdl/RioCommon.vhd (nonexistent)
+++ rtl/vhdl/RioCommon.vhd (revision 2)
@@ -0,0 +1,1078 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Contains commonly used types, functions, procedures and entities used in
+-- the RapidIO IP library project.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Magnus Rosenius, magro732@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE. See the GNU Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+
+-------------------------------------------------------------------------------
+-- RioCommon library.
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+use std.textio.all;
+
+
+-------------------------------------------------------------------------------
+-- RioCommon package description.
+-------------------------------------------------------------------------------
+package rio_common is
+ -----------------------------------------------------------------------------
+ -- Commonly used types.
+ -----------------------------------------------------------------------------
+ type Array1 is array (natural range <>) of
+ std_logic;
+ type Array2 is array (natural range <>) of
+ std_logic_vector(1 downto 0);
+ type Array3 is array (natural range <>) of
+ std_logic_vector(2 downto 0);
+ type Array4 is array (natural range <>) of
+ std_logic_vector(3 downto 0);
+ type Array5 is array (natural range <>) of
+ std_logic_vector(4 downto 0);
+ type Array8 is array (natural range <>) of
+ std_logic_vector(7 downto 0);
+ type Array9 is array (natural range <>) of
+ std_logic_vector(8 downto 0);
+ type Array10 is array (natural range <>) of
+ std_logic_vector(9 downto 0);
+ type Array16 is array (natural range <>) of
+ std_logic_vector(15 downto 0);
+ type Array32 is array (natural range <>) of
+ std_logic_vector(31 downto 0);
+ type Array34 is array (natural range <>) of
+ std_logic_vector(33 downto 0);
+
+ -----------------------------------------------------------------------------
+ -- Commonly used constants.
+ -----------------------------------------------------------------------------
+
+ -- Symbol types between the serial and the PCS layer.
+ constant SYMBOL_IDLE : std_logic_vector(1 downto 0) := "00";
+ constant SYMBOL_CONTROL : std_logic_vector(1 downto 0) := "01";
+ constant SYMBOL_ERROR : std_logic_vector(1 downto 0) := "10";
+ constant SYMBOL_DATA : std_logic_vector(1 downto 0) := "11";
+
+ -- STYPE0 constants.
+ constant STYPE0_PACKET_ACCEPTED : std_logic_vector(2 downto 0) := "000";
+ constant STYPE0_PACKET_RETRY : std_logic_vector(2 downto 0) := "001";
+ constant STYPE0_PACKET_NOT_ACCEPTED : std_logic_vector(2 downto 0) := "010";
+ constant STYPE0_RESERVED : std_logic_vector(2 downto 0) := "011";
+ constant STYPE0_STATUS : std_logic_vector(2 downto 0) := "100";
+ constant STYPE0_VC_STATUS : std_logic_vector(2 downto 0) := "101";
+ constant STYPE0_LINK_RESPONSE : std_logic_vector(2 downto 0) := "110";
+ constant STYPE0_IMPLEMENTATION_DEFINED : std_logic_vector(2 downto 0) := "111";
+
+ -- STYPE1 constants.
+ constant STYPE1_START_OF_PACKET : std_logic_vector(2 downto 0) := "000";
+ constant STYPE1_STOMP : std_logic_vector(2 downto 0) := "001";
+ constant STYPE1_END_OF_PACKET : std_logic_vector(2 downto 0) := "010";
+ constant STYPE1_RESTART_FROM_RETRY : std_logic_vector(2 downto 0) := "011";
+ constant STYPE1_LINK_REQUEST : std_logic_vector(2 downto 0) := "100";
+ constant STYPE1_MULTICAST_EVENT : std_logic_vector(2 downto 0) := "101";
+ constant STYPE1_RESERVED : std_logic_vector(2 downto 0) := "110";
+ constant STYPE1_NOP : std_logic_vector(2 downto 0) := "111";
+
+ -- FTYPE constants.
+ constant FTYPE_REQUEST_CLASS : std_logic_vector(3 downto 0) := "0010";
+ constant FTYPE_WRITE_CLASS : std_logic_vector(3 downto 0) := "0101";
+ constant FTYPE_STREAMING_WRITE_CLASS : std_logic_vector(3 downto 0) := "0110";
+ constant FTYPE_MAINTENANCE_CLASS : std_logic_vector(3 downto 0) := "1000";
+ constant FTYPE_RESPONSE_CLASS : std_logic_vector(3 downto 0) := "1101";
+ constant FTYPE_DOORBELL_CLASS : std_logic_vector(3 downto 0) := "1010";
+ constant FTYPE_MESSAGE_CLASS : std_logic_vector(3 downto 0) := "0010";
+
+ -- TTYPE Constants
+ constant TTYPE_MAINTENANCE_READ_REQUEST : std_logic_vector(3 downto 0) := "0000";
+ constant TTYPE_MAINTENANCE_WRITE_REQUEST : std_logic_vector(3 downto 0) := "0001";
+ constant TTYPE_MAINTENANCE_READ_RESPONSE : std_logic_vector(3 downto 0) := "0010";
+ constant TTYPE_MAINTENANCE_WRITE_RESPONSE : std_logic_vector(3 downto 0) := "0011";
+ constant TTYPE_NREAD_TRANSACTION : std_logic_vector(3 downto 0) := "0100";
+ constant TTYPE_NWRITE_TRANSACTION : std_logic_vector(3 downto 0) := "0100";
+
+ constant LINK_REQUEST_CMD_RESET_DEVICE : std_logic_vector(2 downto 0) := "011";
+ constant LINK_REQUEST_CMD_INPUT_STATUS : std_logic_vector(2 downto 0) := "100";
+
+ constant PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID : std_logic_vector(4 downto 0) := "00001";
+ constant PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC : std_logic_vector(4 downto 0) := "00010";
+ constant PACKET_NOT_ACCEPTED_CAUSE_NON_MAINTENANCE_STOPPED : std_logic_vector(4 downto 0) := "00011";
+ constant PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC : std_logic_vector(4 downto 0) := "00100";
+ constant PACKET_NOT_ACCEPTED_CAUSE_INVALID_CHARACTER : std_logic_vector(4 downto 0) := "00101";
+ constant PACKET_NOT_ACCEPTED_CAUSE_NO_RESOURCES : std_logic_vector(4 downto 0) := "00110";
+ constant PACKET_NOT_ACCEPTED_CAUSE_LOSS_DESCRAMBLER : std_logic_vector(4 downto 0) := "00111";
+ constant PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR : std_logic_vector(4 downto 0) := "11111";
+
+ -----------------------------------------------------------------------------
+ -- Types used in simulations.
+ -----------------------------------------------------------------------------
+ type ByteArray is array (natural range <>) of
+ std_logic_vector(7 downto 0);
+ type HalfwordArray is array (natural range <>) of
+ std_logic_vector(15 downto 0);
+ type WordArray is array (natural range <>) of
+ std_logic_vector(31 downto 0);
+ type DoublewordArray is array (natural range <>) of
+ std_logic_vector(63 downto 0);
+
+ -- Type defining a RapidIO frame.
+ type RioFrame is record
+ length : natural range 0 to 69;
+ payload : WordArray(0 to 68);
+ end record;
+ type RioFrameArray is array (natural range <>) of RioFrame;
+
+ -- Type defining a RapidIO payload.
+ type RioPayload is record
+ length : natural range 0 to 133;
+ data : HalfwordArray(0 to 132);
+ end record;
+
+ -----------------------------------------------------------------------------
+ -- Crc5 calculation function.
+ -- ITU, polynom=0x15.
+ -----------------------------------------------------------------------------
+ function Crc5(constant data : in std_logic_vector(18 downto 0);
+ constant crc : in std_logic_vector(4 downto 0))
+ return std_logic_vector;
+
+ ---------------------------------------------------------------------------
+ -- Create a RapidIO physical layer control symbol.
+ ---------------------------------------------------------------------------
+ function RioControlSymbolCreate(
+ constant stype0 : in std_logic_vector(2 downto 0);
+ constant parameter0 : in std_logic_vector(4 downto 0);
+ constant parameter1 : in std_logic_vector(4 downto 0);
+ constant stype1 : in std_logic_vector(2 downto 0);
+ constant cmd : in std_logic_vector(2 downto 0))
+ return std_logic_vector;
+
+ -----------------------------------------------------------------------------
+ -- Crc16 calculation function.
+ -- CITT, polynom=0x1021.
+ -----------------------------------------------------------------------------
+ function Crc16(constant data : in std_logic_vector(15 downto 0);
+ constant crc : in std_logic_vector(15 downto 0))
+ return std_logic_vector;
+
+ ---------------------------------------------------------------------------
+ -- Create a randomly initialized data array.
+ ---------------------------------------------------------------------------
+ procedure CreateRandomPayload(
+ variable payload : out HalfwordArray(0 to 132);
+ variable seed1 : inout positive;
+ variable seed2 : inout positive);
+ procedure CreateRandomPayload(
+ variable payload : out DoublewordArray(0 to 31);
+ variable seed1 : inout positive;
+ variable seed2 : inout positive);
+
+ ---------------------------------------------------------------------------
+ -- Create a generic RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioFrameCreate(
+ constant ackId : in std_logic_vector(4 downto 0);
+ constant vc : in std_logic;
+ constant crf : in std_logic;
+ constant prio : in std_logic_vector(1 downto 0);
+ constant tt : in std_logic_vector(1 downto 0);
+ constant ftype : in std_logic_vector(3 downto 0);
+ constant sourceId : in std_logic_vector(15 downto 0);
+ constant destId : in std_logic_vector(15 downto 0);
+ constant payload : in RioPayload)
+ return RioFrame;
+
+ ---------------------------------------------------------------------------
+ -- Create a NWRITE RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioNwrite(
+ constant wrsize : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant address : in std_logic_vector(28 downto 0);
+ constant wdptr : in std_logic;
+ constant xamsbs : in std_logic_vector(1 downto 0);
+ constant dataLength : in natural range 1 to 32;
+ constant data : in DoublewordArray(0 to 31))
+ return RioPayload;
+
+ ---------------------------------------------------------------------------
+ -- Create a NREAD RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioNread(
+ constant rdsize : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant address : in std_logic_vector(28 downto 0);
+ constant wdptr : in std_logic;
+ constant xamsbs : in std_logic_vector(1 downto 0))
+ return RioPayload;
+
+ ---------------------------------------------------------------------------
+ -- Create a RESPONSE RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioResponse(
+ constant status : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant dataLength : in natural range 0 to 32;
+ constant data : in DoublewordArray(0 to 31))
+ return RioPayload;
+
+ ---------------------------------------------------------------------------
+ -- Create a Maintenance RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioMaintenance(
+ constant transaction : in std_logic_vector(3 downto 0);
+ constant size : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant hopCount : in std_logic_vector(7 downto 0);
+ constant configOffset : in std_logic_vector(20 downto 0);
+ constant wdptr : in std_logic;
+ constant dataLength : in natural range 0 to 8;
+ constant data : in DoublewordArray(0 to 7))
+ return RioPayload;
+
+ -----------------------------------------------------------------------------
+ -- Function to convert a std_logic_vector to a string.
+ -----------------------------------------------------------------------------
+ function byteToString(constant byte : std_logic_vector(7 downto 0))
+ return string;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to print to report file and output
+ ---------------------------------------------------------------------------
+ procedure PrintR( constant str : string );
+
+ ---------------------------------------------------------------------------
+ -- Procedure to print to spec file
+ ---------------------------------------------------------------------------
+ procedure PrintS( constant str : string );
+
+ ---------------------------------------------------------------------------
+ -- Procedure to Assert Expression
+ ---------------------------------------------------------------------------
+ procedure AssertE( constant exp: boolean; constant str : string );
+
+ ---------------------------------------------------------------------------
+ -- Procedure to Print Error
+ ---------------------------------------------------------------------------
+ procedure PrintE( constant str : string );
+
+ ---------------------------------------------------------------------------
+ -- Procedure to end a test.
+ ---------------------------------------------------------------------------
+ procedure TestEnd;
+
+end package;
+
+-------------------------------------------------------------------------------
+-- RioCommon package body description.
+-------------------------------------------------------------------------------
+package body rio_common is
+ -----------------------------------------------------------------------------
+ -- Crc5 calculation function.
+ -- ITU, polynom=0x15.
+ -----------------------------------------------------------------------------
+ function Crc5(constant data : in std_logic_vector(18 downto 0);
+ constant crc : in std_logic_vector(4 downto 0))
+ return std_logic_vector is
+ type crcTableType is array (0 to 31) of std_logic_vector(7 downto 0);
+ constant crcTable : crcTableType := (
+ x"00", x"15", x"1f", x"0a", x"0b", x"1e", x"14", x"01",
+ x"16", x"03", x"09", x"1c", x"1d", x"08", x"02", x"17",
+ x"19", x"0c", x"06", x"13", x"12", x"07", x"0d", x"18",
+ x"0f", x"1a", x"10", x"05", x"04", x"11", x"1b", x"0e" );
+ variable index : natural range 0 to 31;
+ variable result : std_logic_vector(4 downto 0);
+ begin
+ result := crc;
+ index := to_integer(unsigned(data(18 downto 14) xor result));
+ result := crcTable(index)(4 downto 0);
+ index := to_integer(unsigned(data(13 downto 9) xor result));
+ result := crcTable(index)(4 downto 0);
+ index := to_integer(unsigned(data(8 downto 4) xor result));
+ result := crcTable(index)(4 downto 0);
+ index := to_integer(unsigned((data(3 downto 0) & '0') xor result));
+ return crcTable(index)(4 downto 0);
+ end Crc5;
+
+ ---------------------------------------------------------------------------
+ -- Create a RapidIO physical layer control symbol.
+ ---------------------------------------------------------------------------
+ function RioControlSymbolCreate(
+ constant stype0 : in std_logic_vector(2 downto 0);
+ constant parameter0 : in std_logic_vector(4 downto 0);
+ constant parameter1 : in std_logic_vector(4 downto 0);
+ constant stype1 : in std_logic_vector(2 downto 0);
+ constant cmd : in std_logic_vector(2 downto 0))
+ return std_logic_vector is
+ variable returnValue : std_logic_vector(31 downto 0);
+ variable symbolData : std_logic_vector(18 downto 0);
+ begin
+ symbolData(18 downto 16) := stype0;
+ symbolData(15 downto 11) := parameter0;
+ symbolData(10 downto 6) := parameter1;
+ symbolData(5 downto 3) := stype1;
+ symbolData(2 downto 0) := cmd;
+
+ returnValue(31 downto 13) := symbolData;
+ returnValue(12 downto 8) := Crc5(symbolData, "11111");
+ returnValue(7 downto 0) := x"00";
+
+ return returnValue;
+ end function;
+
+ -----------------------------------------------------------------------------
+ -- Crc16 calculation function.
+ -- CITT, polynom=0x1021.
+ -----------------------------------------------------------------------------
+ function Crc16(constant data : in std_logic_vector(15 downto 0);
+ constant crc : in std_logic_vector(15 downto 0))
+ return std_logic_vector is
+ type crcTableType is array (0 to 255) of std_logic_vector(15 downto 0);
+ constant crcTable : crcTableType := (
+ x"0000", x"1021", x"2042", x"3063", x"4084", x"50a5", x"60c6", x"70e7",
+ x"8108", x"9129", x"a14a", x"b16b", x"c18c", x"d1ad", x"e1ce", x"f1ef",
+ x"1231", x"0210", x"3273", x"2252", x"52b5", x"4294", x"72f7", x"62d6",
+ x"9339", x"8318", x"b37b", x"a35a", x"d3bd", x"c39c", x"f3ff", x"e3de",
+ x"2462", x"3443", x"0420", x"1401", x"64e6", x"74c7", x"44a4", x"5485",
+ x"a56a", x"b54b", x"8528", x"9509", x"e5ee", x"f5cf", x"c5ac", x"d58d",
+ x"3653", x"2672", x"1611", x"0630", x"76d7", x"66f6", x"5695", x"46b4",
+ x"b75b", x"a77a", x"9719", x"8738", x"f7df", x"e7fe", x"d79d", x"c7bc",
+ x"48c4", x"58e5", x"6886", x"78a7", x"0840", x"1861", x"2802", x"3823",
+ x"c9cc", x"d9ed", x"e98e", x"f9af", x"8948", x"9969", x"a90a", x"b92b",
+ x"5af5", x"4ad4", x"7ab7", x"6a96", x"1a71", x"0a50", x"3a33", x"2a12",
+ x"dbfd", x"cbdc", x"fbbf", x"eb9e", x"9b79", x"8b58", x"bb3b", x"ab1a",
+ x"6ca6", x"7c87", x"4ce4", x"5cc5", x"2c22", x"3c03", x"0c60", x"1c41",
+ x"edae", x"fd8f", x"cdec", x"ddcd", x"ad2a", x"bd0b", x"8d68", x"9d49",
+ x"7e97", x"6eb6", x"5ed5", x"4ef4", x"3e13", x"2e32", x"1e51", x"0e70",
+ x"ff9f", x"efbe", x"dfdd", x"cffc", x"bf1b", x"af3a", x"9f59", x"8f78",
+ x"9188", x"81a9", x"b1ca", x"a1eb", x"d10c", x"c12d", x"f14e", x"e16f",
+ x"1080", x"00a1", x"30c2", x"20e3", x"5004", x"4025", x"7046", x"6067",
+ x"83b9", x"9398", x"a3fb", x"b3da", x"c33d", x"d31c", x"e37f", x"f35e",
+ x"02b1", x"1290", x"22f3", x"32d2", x"4235", x"5214", x"6277", x"7256",
+ x"b5ea", x"a5cb", x"95a8", x"8589", x"f56e", x"e54f", x"d52c", x"c50d",
+ x"34e2", x"24c3", x"14a0", x"0481", x"7466", x"6447", x"5424", x"4405",
+ x"a7db", x"b7fa", x"8799", x"97b8", x"e75f", x"f77e", x"c71d", x"d73c",
+ x"26d3", x"36f2", x"0691", x"16b0", x"6657", x"7676", x"4615", x"5634",
+ x"d94c", x"c96d", x"f90e", x"e92f", x"99c8", x"89e9", x"b98a", x"a9ab",
+ x"5844", x"4865", x"7806", x"6827", x"18c0", x"08e1", x"3882", x"28a3",
+ x"cb7d", x"db5c", x"eb3f", x"fb1e", x"8bf9", x"9bd8", x"abbb", x"bb9a",
+ x"4a75", x"5a54", x"6a37", x"7a16", x"0af1", x"1ad0", x"2ab3", x"3a92",
+ x"fd2e", x"ed0f", x"dd6c", x"cd4d", x"bdaa", x"ad8b", x"9de8", x"8dc9",
+ x"7c26", x"6c07", x"5c64", x"4c45", x"3ca2", x"2c83", x"1ce0", x"0cc1",
+ x"ef1f", x"ff3e", x"cf5d", x"df7c", x"af9b", x"bfba", x"8fd9", x"9ff8",
+ x"6e17", x"7e36", x"4e55", x"5e74", x"2e93", x"3eb2", x"0ed1", x"1ef0" );
+ variable index : natural range 0 to 255;
+ variable result : std_logic_vector(15 downto 0);
+ begin
+ result := crc;
+ index := to_integer(unsigned(data(15 downto 8) xor result(15 downto 8)));
+ result := crcTable(index) xor (result(7 downto 0) & x"00");
+ index := to_integer(unsigned(data(7 downto 0) xor result(15 downto 8)));
+ result := crcTable(index) xor (result(7 downto 0) & x"00");
+ return result;
+ end Crc16;
+
+ ---------------------------------------------------------------------------
+ -- Create a randomly initialized data array.
+ ---------------------------------------------------------------------------
+ procedure CreateRandomPayload(
+ variable payload : out HalfwordArray(0 to 132);
+ variable seed1 : inout positive;
+ variable seed2 : inout positive) is
+ variable rand: real;
+ variable int_rand: integer;
+ variable stim: std_logic_vector(7 downto 0);
+ begin
+ for i in payload'range loop
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(7 downto 0) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(15 downto 8) := std_logic_vector(to_unsigned(int_rand, 8));
+ end loop;
+ end procedure;
+
+ procedure CreateRandomPayload(
+ variable payload : out DoublewordArray(0 to 31);
+ variable seed1 : inout positive;
+ variable seed2 : inout positive) is
+ variable rand: real;
+ variable int_rand: integer;
+ variable stim: std_logic_vector(7 downto 0);
+ begin
+ for i in payload'range loop
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(7 downto 0) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(15 downto 8) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(23 downto 16) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(31 downto 24) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(39 downto 32) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(47 downto 40) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(55 downto 48) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(63 downto 56) := std_logic_vector(to_unsigned(int_rand, 8));
+ end loop;
+ end procedure;
+ ---------------------------------------------------------------------------
+ -- Create a generic RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioFrameCreate(
+ constant ackId : in std_logic_vector(4 downto 0);
+ constant vc : in std_logic;
+ constant crf : in std_logic;
+ constant prio : in std_logic_vector(1 downto 0);
+ constant tt : in std_logic_vector(1 downto 0);
+ constant ftype : in std_logic_vector(3 downto 0);
+ constant sourceId : in std_logic_vector(15 downto 0);
+ constant destId : in std_logic_vector(15 downto 0);
+ constant payload : in RioPayload) return RioFrame is
+ variable frame : RioFrame;
+ variable result : HalfwordArray(0 to 137);
+ variable crc : std_logic_vector(15 downto 0) := x"ffff";
+ begin
+ -- Add the header and addresses.
+ result(0) := ackId & "0" & vc & crf & prio & tt & ftype;
+ result(1) := destId;
+ result(2) := sourceId;
+
+ -- Update the calculated CRC with the header contents.
+ crc := Crc16("00000" & result(0)(10 downto 0), crc);
+ crc := Crc16(result(1), crc);
+ crc := Crc16(result(2), crc);
+
+ -- Check if a single CRC should be added or two.
+ if (payload.length <= 37) then
+ -- Single CRC.
+ for i in 0 to payload.length-1 loop
+ result(i+3) := payload.data(i);
+ crc := Crc16(payload.data(i), crc);
+ end loop;
+ result(payload.length+3) := crc;
+
+ -- Check if paddning is needed to make the payload even 32-bit.
+ if ((payload.length mod 2) = 1) then
+ result(payload.length+4) := x"0000";
+ frame.length := (payload.length+5) / 2;
+ else
+ frame.length := (payload.length+4) / 2;
+ end if;
+ else
+ -- Double CRC.
+ for i in 0 to 36 loop
+ result(i+3) := payload.data(i);
+ crc := Crc16(payload.data(i), crc);
+ end loop;
+
+ -- Add in-the-middle crc.
+ result(40) := crc;
+ crc := Crc16(crc, crc);
+
+ for i in 37 to payload.length-1 loop
+ result(i+4) := payload.data(i);
+ crc := Crc16(payload.data(i), crc);
+ end loop;
+ result(payload.length+4) := crc;
+
+ -- Check if paddning is needed to make the payload even 32-bit.
+ if ((payload.length mod 2) = 0) then
+ result(payload.length+5) := x"0000";
+ frame.length := (payload.length+6) / 2;
+ else
+ frame.length := (payload.length+5) / 2;
+ end if;
+ end if;
+
+ -- Update the result length.
+ for i in 0 to frame.length-1 loop
+ frame.payload(i) := result(2*i) & result(2*i+1);
+ end loop;
+
+ return frame;
+ end function;
+
+ -----------------------------------------------------------------------------
+ --
+ -----------------------------------------------------------------------------
+ function RioNwrite(
+ constant wrsize : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant address : in std_logic_vector(28 downto 0);
+ constant wdptr : in std_logic;
+ constant xamsbs : in std_logic_vector(1 downto 0);
+ constant dataLength : in natural range 1 to 32;
+ constant data : in DoublewordArray(0 to 31))
+ return RioPayload is
+ variable payload : RioPayload;
+ begin
+ payload.data(0)(15 downto 12) := "0100";
+ payload.data(0)(11 downto 8) := wrsize;
+ payload.data(0)(7 downto 0) := tid;
+
+ payload.data(1) := address(28 downto 13);
+
+ payload.data(2)(15 downto 3) := address(12 downto 0);
+ payload.data(2)(2) := wdptr;
+ payload.data(2)(1 downto 0) := xamsbs;
+
+ for i in 0 to dataLength-1 loop
+ payload.data(3+4*i) := data(i)(63 downto 48);
+ payload.data(4+4*i) := data(i)(47 downto 32);
+ payload.data(5+4*i) := data(i)(31 downto 16);
+ payload.data(6+4*i) := data(i)(15 downto 0);
+ end loop;
+
+ payload.length := 3 + 4*dataLength;
+
+ return payload;
+ end function;
+
+ -----------------------------------------------------------------------------
+ --
+ -----------------------------------------------------------------------------
+ function RioNread(
+ constant rdsize : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant address : in std_logic_vector(28 downto 0);
+ constant wdptr : in std_logic;
+ constant xamsbs : in std_logic_vector(1 downto 0))
+ return RioPayload is
+ variable payload : RioPayload;
+ begin
+ payload.data(0)(15 downto 12) := "0100";
+ payload.data(0)(11 downto 8) := rdsize;
+ payload.data(0)(7 downto 0) := tid;
+
+ payload.data(1) := address(28 downto 13);
+
+ payload.data(2)(15 downto 3) := address(12 downto 0);
+ payload.data(2)(2) := wdptr;
+ payload.data(2)(1 downto 0) := xamsbs;
+
+ payload.length := 3;
+
+ return payload;
+ end function;
+
+ ---------------------------------------------------------------------------
+ -- Create a RESPONSE RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioResponse(
+ constant status : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant dataLength : in natural range 0 to 32;
+ constant data : in DoublewordArray(0 to 31))
+ return RioPayload is
+ variable payload : RioPayload;
+ begin
+ payload.data(0)(11 downto 8) := status;
+ payload.data(0)(7 downto 0) := tid;
+
+ if (dataLength = 0) then
+ payload.data(0)(15 downto 12) := "0000";
+ payload.length := 1;
+ else
+ payload.data(0)(15 downto 12) := "1000";
+
+ for i in 0 to dataLength-1 loop
+ payload.data(1+4*i) := data(i)(63 downto 48);
+ payload.data(2+4*i) := data(i)(47 downto 32);
+ payload.data(3+4*i) := data(i)(31 downto 16);
+ payload.data(4+4*i) := data(i)(15 downto 0);
+ end loop;
+
+ payload.length := 1 + 4*dataLength;
+ end if;
+
+ return payload;
+ end function;
+
+ ---------------------------------------------------------------------------
+ -- Create a Maintenance RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioMaintenance(
+ constant transaction : in std_logic_vector(3 downto 0);
+ constant size : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant hopCount : in std_logic_vector(7 downto 0);
+ constant configOffset : in std_logic_vector(20 downto 0);
+ constant wdptr : in std_logic;
+ constant dataLength : in natural range 0 to 8;
+ constant data : in DoublewordArray(0 to 7))
+ return RioPayload is
+ variable payload : RioPayload;
+ begin
+ payload.data(0)(15 downto 12) := transaction;
+ payload.data(0)(11 downto 8) := size;
+ payload.data(0)(7 downto 0) := tid;
+
+ payload.data(1)(15 downto 8) := hopCount;
+ payload.data(1)(7 downto 0) := configOffset(20 downto 13);
+
+ payload.data(2)(15 downto 3) := configOffset(12 downto 0);
+ payload.data(2)(2) := wdptr;
+ payload.data(2)(1 downto 0) := "00";
+
+ if (dataLength = 0) then
+ payload.length := 3;
+ else
+ for i in 0 to dataLength-1 loop
+ payload.data(3+4*i) := data(i)(63 downto 48);
+ payload.data(4+4*i) := data(i)(47 downto 32);
+ payload.data(5+4*i) := data(i)(31 downto 16);
+ payload.data(6+4*i) := data(i)(15 downto 0);
+ end loop;
+
+ payload.length := 3 + 4*dataLength;
+ end if;
+
+ return payload;
+ end function;
+
+ -----------------------------------------------------------------------------
+ -- Function to convert a std_logic_vector to a string.
+ -----------------------------------------------------------------------------
+ function byteToString(constant byte : std_logic_vector(7 downto 0))
+ return string is
+ constant table : string(1 to 16) := "0123456789abcdef";
+ variable returnValue : string(1 to 2);
+ begin
+ returnValue(1) := table(to_integer(unsigned(byte(7 downto 4))) + 1);
+ returnValue(2) := table(to_integer(unsigned(byte(3 downto 0))) + 1);
+ return returnValue;
+ end function;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to print test report
+ ---------------------------------------------------------------------------
+ procedure PrintR( constant str : string ) is
+ file reportFile : text;
+ variable reportLine, outputLine : line;
+ variable fStatus: FILE_OPEN_STATUS;
+ begin
+ --Write report note to wave/transcript window
+ report str severity NOTE;
+ end PrintR;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to print test spec
+ ---------------------------------------------------------------------------
+ procedure PrintS( constant str : string ) is
+ file specFile : text;
+ variable specLine, outputLine : line;
+ variable fStatus: FILE_OPEN_STATUS;
+ begin
+ --Write to spec file
+ file_open(fStatus, specFile, "testspec.txt", append_mode);
+ write(specLine, string'(str));
+ writeline (specFile, specLine);
+ file_close(specFile);
+ end PrintS;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to Assert Expression
+ ---------------------------------------------------------------------------
+ procedure AssertE( constant exp: boolean; constant str : string ) is
+ file reportFile : text;
+ variable reportLine, outputLine : line;
+ variable fStatus: FILE_OPEN_STATUS;
+ begin
+ if (not exp) then
+ --Write to STD_OUTPUT
+ report(str) severity error;
+ else
+ PrintR("Status: Passed");
+ PrintS("Status: Passed");
+ end if;
+ end AssertE;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to Print Error
+ ---------------------------------------------------------------------------
+ procedure PrintE( constant str : string ) is
+ file reportFile : text;
+ variable reportLine, outputLine : line;
+ variable fStatus: FILE_OPEN_STATUS;
+ begin
+ --Write to STD_OUTPUT
+ report str severity error;
+ end PrintE;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to end a test.
+ ---------------------------------------------------------------------------
+ procedure TestEnd is
+ begin
+ assert false report "Test complete." severity failure;
+ wait;
+ end TestEnd;
+
+end rio_common;
+
+
+
+-------------------------------------------------------------------------------
+-- Crc16CITT
+-- A CRC-16 calculator following the implementation proposed in the 2.2
+-- standard.
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for Crc16CITT.
+-------------------------------------------------------------------------------
+entity Crc16CITT is
+ port(
+ d_i : in std_logic_vector(15 downto 0);
+ crc_i : in std_logic_vector(15 downto 0);
+ crc_o : out std_logic_vector(15 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for Crc16CITT.
+-------------------------------------------------------------------------------
+architecture Crc16Impl of Crc16CITT is
+ signal d : std_logic_vector(0 to 15);
+ signal c : std_logic_vector(0 to 15);
+ signal e : std_logic_vector(0 to 15);
+ signal cc : std_logic_vector(0 to 15);
+begin
+
+ -- Reverse the bit vector indexes to make them the same as in the standard.
+ d(15) <= d_i(0); d(14) <= d_i(1); d(13) <= d_i(2); d(12) <= d_i(3);
+ d(11) <= d_i(4); d(10) <= d_i(5); d(9) <= d_i(6); d(8) <= d_i(7);
+ d(7) <= d_i(8); d(6) <= d_i(9); d(5) <= d_i(10); d(4) <= d_i(11);
+ d(3) <= d_i(12); d(2) <= d_i(13); d(1) <= d_i(14); d(0) <= d_i(15);
+
+ -- Reverse the bit vector indexes to make them the same as in the standard.
+ c(15) <= crc_i(0); c(14) <= crc_i(1); c(13) <= crc_i(2); c(12) <= crc_i(3);
+ c(11) <= crc_i(4); c(10) <= crc_i(5); c(9) <= crc_i(6); c(8) <= crc_i(7);
+ c(7) <= crc_i(8); c(6) <= crc_i(9); c(5) <= crc_i(10); c(4) <= crc_i(11);
+ c(3) <= crc_i(12); c(2) <= crc_i(13); c(1) <= crc_i(14); c(0) <= crc_i(15);
+
+ -- Calculate the resulting crc.
+ e <= c xor d;
+ cc(0) <= e(4) xor e(5) xor e(8) xor e(12);
+ cc(1) <= e(5) xor e(6) xor e(9) xor e(13);
+ cc(2) <= e(6) xor e(7) xor e(10) xor e(14);
+ cc(3) <= e(0) xor e(7) xor e(8) xor e(11) xor e(15);
+ cc(4) <= e(0) xor e(1) xor e(4) xor e(5) xor e(9);
+ cc(5) <= e(1) xor e(2) xor e(5) xor e(6) xor e(10);
+ cc(6) <= e(0) xor e(2) xor e(3) xor e(6) xor e(7) xor e(11);
+ cc(7) <= e(0) xor e(1) xor e(3) xor e(4) xor e(7) xor e(8) xor e(12);
+ cc(8) <= e(0) xor e(1) xor e(2) xor e(4) xor e(5) xor e(8) xor e(9) xor e(13);
+ cc(9) <= e(1) xor e(2) xor e(3) xor e(5) xor e(6) xor e(9) xor e(10) xor e(14);
+ cc(10) <= e(2) xor e(3) xor e(4) xor e(6) xor e(7) xor e(10) xor e(11) xor e(15);
+ cc(11) <= e(0) xor e(3) xor e(7) xor e(11);
+ cc(12) <= e(0) xor e(1) xor e(4) xor e(8) xor e(12);
+ cc(13) <= e(1) xor e(2) xor e(5) xor e(9) xor e(13);
+ cc(14) <= e(2) xor e(3) xor e(6) xor e(10) xor e(14);
+ cc(15) <= e(3) xor e(4) xor e(7) xor e(11) xor e(15);
+
+ -- Reverse the bit vector indexes to make them the same as in the standard.
+ crc_o(15) <= cc(0); crc_o(14) <= cc(1); crc_o(13) <= cc(2); crc_o(12) <= cc(3);
+ crc_o(11) <= cc(4); crc_o(10) <= cc(5); crc_o(9) <= cc(6); crc_o(8) <= cc(7);
+ crc_o(7) <= cc(8); crc_o(6) <= cc(9); crc_o(5) <= cc(10); crc_o(4) <= cc(11);
+ crc_o(3) <= cc(12); crc_o(2) <= cc(13); crc_o(1) <= cc(14); crc_o(0) <= cc(15);
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- MemoryDualPort
+-- Generic synchronous memory with one read/write port and one read port.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for MemoryDualPort.
+-------------------------------------------------------------------------------
+entity MemoryDualPort is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ writeEnableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ dataA_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ clkB_i : in std_logic;
+ enableB_i : in std_logic;
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for MemoryDualPort.
+-------------------------------------------------------------------------------
+architecture MemoryDualPortImpl of MemoryDualPort is
+ type MemoryType is array (natural range <>) of
+ std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1);
+
+begin
+ process(clkA_i)
+ begin
+ if (clkA_i'event and clkA_i = '1') then
+ if (enableA_i = '1') then
+ if (writeEnableA_i = '1') then
+ memory(to_integer(unsigned(addressA_i))) <= dataA_i;
+ end if;
+
+ dataA_o <= memory(to_integer(unsigned(addressA_i)));
+ end if;
+ end if;
+ end process;
+
+ process(clkB_i)
+ begin
+ if (clkB_i'event and clkB_i = '1') then
+ if (enableB_i = '1') then
+ dataB_o <= memory(to_integer(unsigned(addressB_i)));
+ end if;
+ end if;
+ end process;
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- MemorySimpleDualPort
+-- Generic synchronous memory with one write port and one read port.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for MemorySimpleDualPort.
+-------------------------------------------------------------------------------
+entity MemorySimpleDualPort is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ clkB_i : in std_logic;
+ enableB_i : in std_logic;
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for MemorySimpleDualPort.
+-------------------------------------------------------------------------------
+architecture MemorySimpleDualPortImpl of MemorySimpleDualPort is
+ type MemoryType is array (natural range <>) of
+ std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1);
+
+begin
+ process(clkA_i)
+ begin
+ if (clkA_i'event and clkA_i = '1') then
+ if (enableA_i = '1') then
+ memory(to_integer(unsigned(addressA_i))) <= dataA_i;
+ end if;
+ end if;
+ end process;
+
+ process(clkB_i)
+ begin
+ if (clkB_i'event and clkB_i = '1') then
+ if (enableB_i = '1') then
+ dataB_o <= memory(to_integer(unsigned(addressB_i)));
+ end if;
+ end if;
+ end process;
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- MemorySinglePort
+-- Generic synchronous memory with one read/write port.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for MemorySinglePort.
+-------------------------------------------------------------------------------
+entity MemorySinglePort is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clk_i : in std_logic;
+ enable_i : in std_logic;
+ writeEnable_i : in std_logic;
+ address_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ data_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ data_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for MemorySinglePort.
+-------------------------------------------------------------------------------
+architecture MemorySinglePortImpl of MemorySinglePort is
+ type MemoryType is array (natural range <>) of
+ std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1);
+
+begin
+ process(clk_i)
+ begin
+ if (clk_i'event and clk_i = '1') then
+ if (enable_i = '1') then
+ if (writeEnable_i = '1') then
+ memory(to_integer(unsigned(address_i))) <= data_i;
+ end if;
+
+ data_o <= memory(to_integer(unsigned(address_i)));
+ end if;
+ end if;
+ end process;
+
+end architecture;
+
+
+
+
+-------------------------------------------------------------------------------
+-- MemorySimpleDualPortAsync
+-- Generic memory with one synchronous write port and one asynchronous read port.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for MemorySimpleDualPortAsync.
+-------------------------------------------------------------------------------
+entity MemorySimpleDualPortAsync is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1;
+ INIT_VALUE : std_logic := 'U');
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for MemorySimpleDualPortAsync.
+-------------------------------------------------------------------------------
+architecture MemorySimpleDualPortAsyncImpl of MemorySimpleDualPortAsync is
+ type MemoryType is array (natural range <>) of
+ std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1) := (others=>(others=>INIT_VALUE));
+
+begin
+ process(clkA_i)
+ begin
+ if (clkA_i'event and clkA_i = '1') then
+ if (enableA_i = '1') then
+ memory(to_integer(unsigned(addressA_i))) <= dataA_i;
+ end if;
+ end if;
+ end process;
+
+ dataB_o <= memory(to_integer(unsigned(addressB_i)));
+
+end architecture;
+
+
+
+
+
rtl/vhdl/RioCommon.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: rtl/vhdl/RioSwitch.vhd
===================================================================
--- rtl/vhdl/RioSwitch.vhd (nonexistent)
+++ rtl/vhdl/RioSwitch.vhd (revision 2)
@@ -0,0 +1,2510 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Containing RapidIO packet switching functionality contained in the top
+-- entity RioSwitch.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Magnus Rosenius, magro732@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE. See the GNU Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+
+-------------------------------------------------------------------------------
+-- RioSwitch
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+-------------------------------------------------------------------------------
+-- Entity for RioSwitch.
+-------------------------------------------------------------------------------
+entity RioSwitch is
+ generic(
+ SWITCH_PORTS : natural range 3 to 255 := 4;
+ DEVICE_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_REV : std_logic_vector(31 downto 0);
+ ASSY_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_REV : std_logic_vector(15 downto 0));
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ writeFrameFull_i : in Array1(SWITCH_PORTS-1 downto 0);
+ writeFrame_o : out Array1(SWITCH_PORTS-1 downto 0);
+ writeFrameAbort_o : out Array1(SWITCH_PORTS-1 downto 0);
+ writeContent_o : out Array1(SWITCH_PORTS-1 downto 0);
+ writeContentData_o : out Array32(SWITCH_PORTS-1 downto 0);
+
+ readFrameEmpty_i : in Array1(SWITCH_PORTS-1 downto 0);
+ readFrame_o : out Array1(SWITCH_PORTS-1 downto 0);
+ readFrameRestart_o : out Array1(SWITCH_PORTS-1 downto 0);
+ readFrameAborted_i : in Array1(SWITCH_PORTS-1 downto 0);
+ readContentEmpty_i : in Array1(SWITCH_PORTS-1 downto 0);
+ readContent_o : out Array1(SWITCH_PORTS-1 downto 0);
+ readContentEnd_i : in Array1(SWITCH_PORTS-1 downto 0);
+ readContentData_i : in Array32(SWITCH_PORTS-1 downto 0);
+
+ portLinkTimeout_o : out std_logic_vector(23 downto 0);
+
+ linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0);
+ outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
+ inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
+
+ localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0);
+ clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0);
+ inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+ outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+ outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+
+ configStb_o : out std_logic;
+ configWe_o : out std_logic;
+ configAddr_o : out std_logic_vector(23 downto 0);
+ configData_o : out std_logic_vector(31 downto 0);
+ configData_i : in std_logic_vector(31 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for RioSwitch.
+-------------------------------------------------------------------------------
+architecture RioSwitchImpl of RioSwitch is
+
+ component RouteTableInterconnect is
+ generic(
+ WIDTH : natural range 1 to 256 := 8);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ stb_i : in Array1(WIDTH-1 downto 0);
+ addr_i : in Array16(WIDTH-1 downto 0);
+ dataM_o : out Array8(WIDTH-1 downto 0);
+ ack_o : out Array1(WIDTH-1 downto 0);
+
+ stb_o : out std_logic;
+ addr_o : out std_logic_vector(15 downto 0);
+ dataS_i : in std_logic_vector(7 downto 0);
+ ack_i : in std_logic);
+ end component;
+
+ component SwitchPortInterconnect is
+ generic(
+ WIDTH : natural range 1 to 256 := 8);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ masterCyc_i : in Array1(WIDTH-1 downto 0);
+ masterStb_i : in Array1(WIDTH-1 downto 0);
+ masterWe_i : in Array1(WIDTH-1 downto 0);
+ masterAddr_i : in Array10(WIDTH-1 downto 0);
+ masterData_i : in Array32(WIDTH-1 downto 0);
+ masterData_o : out Array1(WIDTH-1 downto 0);
+ masterAck_o : out Array1(WIDTH-1 downto 0);
+
+ slaveCyc_o : out Array1(WIDTH-1 downto 0);
+ slaveStb_o : out Array1(WIDTH-1 downto 0);
+ slaveWe_o : out Array1(WIDTH-1 downto 0);
+ slaveAddr_o : out Array10(WIDTH-1 downto 0);
+ slaveData_o : out Array32(WIDTH-1 downto 0);
+ slaveData_i : in Array1(WIDTH-1 downto 0);
+ slaveAck_i : in Array1(WIDTH-1 downto 0));
+ end component;
+
+ component SwitchPortMaintenance is
+ generic(
+ SWITCH_PORTS : natural range 0 to 255;
+ DEVICE_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_REV : std_logic_vector(31 downto 0);
+ ASSY_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_REV : std_logic_vector(15 downto 0));
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ lookupStb_i : in std_logic;
+ lookupAddr_i : in std_logic_vector(15 downto 0);
+ lookupData_o : out std_logic_vector(7 downto 0);
+ lookupAck_o : out std_logic;
+
+ masterCyc_o : out std_logic;
+ masterStb_o : out std_logic;
+ masterWe_o : out std_logic;
+ masterAddr_o : out std_logic_vector(9 downto 0);
+ masterData_o : out std_logic_vector(31 downto 0);
+ masterData_i : in std_logic;
+ masterAck_i : in std_logic;
+
+ slaveCyc_i : in std_logic;
+ slaveStb_i : in std_logic;
+ slaveWe_i : in std_logic;
+ slaveAddr_i : in std_logic_vector(9 downto 0);
+ slaveData_i : in std_logic_vector(31 downto 0);
+ slaveData_o : out std_logic;
+ slaveAck_o : out std_logic;
+
+ lookupStb_o : out std_logic;
+ lookupAddr_o : out std_logic_vector(15 downto 0);
+ lookupData_i : in std_logic_vector(7 downto 0);
+ lookupAck_i : in std_logic;
+
+ portLinkTimeout_o : out std_logic_vector(23 downto 0);
+
+ linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0);
+ outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
+ inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
+ localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0);
+ clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0);
+ inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+ outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+ outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+
+ configStb_o : out std_logic;
+ configWe_o : out std_logic;
+ configAddr_o : out std_logic_vector(23 downto 0);
+ configData_o : out std_logic_vector(31 downto 0);
+ configData_i : in std_logic_vector(31 downto 0));
+ end component;
+
+ component SwitchPort is
+ generic(
+ PORT_INDEX : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ masterCyc_o : out std_logic;
+ masterStb_o : out std_logic;
+ masterWe_o : out std_logic;
+ masterAddr_o : out std_logic_vector(9 downto 0);
+ masterData_o : out std_logic_vector(31 downto 0);
+ masterData_i : in std_logic;
+ masterAck_i : in std_logic;
+
+ slaveCyc_i : in std_logic;
+ slaveStb_i : in std_logic;
+ slaveWe_i : in std_logic;
+ slaveAddr_i : in std_logic_vector(9 downto 0);
+ slaveData_i : in std_logic_vector(31 downto 0);
+ slaveData_o : out std_logic;
+ slaveAck_o : out std_logic;
+
+ lookupStb_o : out std_logic;
+ lookupAddr_o : out std_logic_vector(15 downto 0);
+ lookupData_i : in std_logic_vector(7 downto 0);
+ lookupAck_i : in std_logic;
+
+ readFrameEmpty_i : in std_logic;
+ readFrame_o : out std_logic;
+ readFrameRestart_o : out std_logic;
+ readFrameAborted_i : in std_logic;
+ readContentEmpty_i : in std_logic;
+ readContent_o : out std_logic;
+ readContentEnd_i : in std_logic;
+ readContentData_i : in std_logic_vector(31 downto 0);
+ writeFrameFull_i : in std_logic;
+ writeFrame_o : out std_logic;
+ writeFrameAbort_o : out std_logic;
+ writeContent_o : out std_logic;
+ writeContentData_o : out std_logic_vector(31 downto 0));
+ end component;
+
+ signal masterLookupStb : Array1(SWITCH_PORTS downto 0);
+ signal masterLookupAddr : Array16(SWITCH_PORTS downto 0);
+ signal masterLookupData : Array8(SWITCH_PORTS downto 0);
+ signal masterLookupAck : Array1(SWITCH_PORTS downto 0);
+
+ signal slaveLookupStb : std_logic;
+ signal slaveLookupAddr : std_logic_vector(15 downto 0);
+ signal slaveLookupData : std_logic_vector(7 downto 0);
+ signal slaveLookupAck : std_logic;
+
+ signal masterCyc : Array1(SWITCH_PORTS downto 0);
+ signal masterStb : Array1(SWITCH_PORTS downto 0);
+ signal masterWe : Array1(SWITCH_PORTS downto 0);
+ signal masterAddr : Array10(SWITCH_PORTS downto 0);
+ signal masterDataWrite : Array32(SWITCH_PORTS downto 0);
+ signal masterDataRead : Array1(SWITCH_PORTS downto 0);
+ signal masterAck : Array1(SWITCH_PORTS downto 0);
+
+ signal slaveCyc : Array1(SWITCH_PORTS downto 0);
+ signal slaveStb : Array1(SWITCH_PORTS downto 0);
+ signal slaveWe : Array1(SWITCH_PORTS downto 0);
+ signal slaveAddr : Array10(SWITCH_PORTS downto 0);
+ signal slaveDataWrite : Array32(SWITCH_PORTS downto 0);
+ signal slaveDataRead : Array1(SWITCH_PORTS downto 0);
+ signal slaveAck : Array1(SWITCH_PORTS downto 0);
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- The routing table interconnect.
+ -----------------------------------------------------------------------------
+ RouteInterconnect: RouteTableInterconnect
+ generic map(
+ WIDTH=>SWITCH_PORTS+1)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ stb_i=>masterLookupStb, addr_i=>masterLookupAddr,
+ dataM_o=>masterLookupData, ack_o=>masterLookupAck,
+ stb_o=>slaveLookupStb, addr_o=>slaveLookupAddr,
+ dataS_i=>slaveLookupData, ack_i=>slaveLookupAck);
+
+ -----------------------------------------------------------------------------
+ -- The port interconnect.
+ -----------------------------------------------------------------------------
+ PortInterconnect: SwitchPortInterconnect
+ generic map(
+ WIDTH=>SWITCH_PORTS+1)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ masterCyc_i=>masterCyc, masterStb_i=>masterStb, masterWe_i=>masterWe, masterAddr_i=>masterAddr,
+ masterData_i=>masterDataWrite, masterData_o=>masterDataRead, masterAck_o=>masterAck,
+ slaveCyc_o=>slaveCyc, slaveStb_o=>slaveStb, slaveWe_o=>slaveWe, slaveAddr_o=>slaveAddr,
+ slaveData_o=>slaveDataWrite, slaveData_i=>slaveDataRead, slaveAck_i=>slaveAck);
+
+ -----------------------------------------------------------------------------
+ -- Data relaying port instantiation.
+ -----------------------------------------------------------------------------
+ PortGeneration: for portIndex in 0 to SWITCH_PORTS-1 generate
+ PortInst: SwitchPort
+ generic map(
+ PORT_INDEX=>portIndex)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ masterCyc_o=>masterCyc(portIndex), masterStb_o=>masterStb(portIndex),
+ masterWe_o=>masterWe(portIndex), masterAddr_o=>masterAddr(portIndex),
+ masterData_o=>masterDataWrite(portIndex),
+ masterData_i=>masterDataRead(portIndex), masterAck_i=>masterAck(portIndex),
+ slaveCyc_i=>slaveCyc(portIndex), slaveStb_i=>slaveStb(portIndex),
+ slaveWe_i=>slaveWe(portIndex), slaveAddr_i=>slaveAddr(portIndex),
+ slaveData_i=>slaveDataWrite(portIndex),
+ slaveData_o=>slaveDataRead(portIndex), slaveAck_o=>slaveAck(portIndex),
+ lookupStb_o=>masterLookupStb(portIndex),
+ lookupAddr_o=>masterLookupAddr(portIndex),
+ lookupData_i=>masterLookupData(portIndex), lookupAck_i=>masterLookupAck(portIndex),
+ readFrameEmpty_i=>readFrameEmpty_i(portIndex), readFrame_o=>readFrame_o(portIndex),
+ readFrameRestart_o=>readFrameRestart_o(portIndex),
+ readFrameAborted_i=>readFrameAborted_i(portIndex),
+ readContentEmpty_i=>readContentEmpty_i(portIndex), readContent_o=>readContent_o(portIndex),
+ readContentEnd_i=>readContentEnd_i(portIndex), readContentData_i=>readContentData_i(portIndex),
+ writeFrameFull_i=>writeFrameFull_i(portIndex), writeFrame_o=>writeFrame_o(portIndex),
+ writeFrameAbort_o=>writeFrameAbort_o(portIndex), writeContent_o=>writeContent_o(portIndex),
+ writeContentData_o=>writeContentData_o(portIndex));
+ end generate;
+
+ -----------------------------------------------------------------------------
+ -- Maintenance port instantiation.
+ -----------------------------------------------------------------------------
+ MaintenancePort: SwitchPortMaintenance
+ generic map(
+ SWITCH_PORTS=>SWITCH_PORTS,
+ DEVICE_IDENTITY=>DEVICE_IDENTITY,
+ DEVICE_VENDOR_IDENTITY=>DEVICE_VENDOR_IDENTITY,
+ DEVICE_REV=>DEVICE_REV,
+ ASSY_IDENTITY=>ASSY_IDENTITY,
+ ASSY_VENDOR_IDENTITY=>ASSY_VENDOR_IDENTITY,
+ ASSY_REV=>ASSY_REV)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ lookupStb_i=>slaveLookupStb, lookupAddr_i=>slaveLookupAddr,
+ lookupData_o=>slaveLookupData, lookupAck_o=>slaveLookupAck,
+ masterCyc_o=>masterCyc(SWITCH_PORTS), masterStb_o=>masterStb(SWITCH_PORTS),
+ masterWe_o=>masterWe(SWITCH_PORTS), masterAddr_o=>masterAddr(SWITCH_PORTS),
+ masterData_o=>masterDataWrite(SWITCH_PORTS),
+ masterData_i=>masterDataRead(SWITCH_PORTS), masterAck_i=>masterAck(SWITCH_PORTS),
+ slaveCyc_i=>slaveCyc(SWITCH_PORTS), slaveStb_i=>slaveStb(SWITCH_PORTS),
+ slaveWe_i=>slaveWe(SWITCH_PORTS), slaveAddr_i=>slaveAddr(SWITCH_PORTS),
+ slaveData_i=>slaveDataWrite(SWITCH_PORTS),
+ slaveData_o=>slaveDataRead(SWITCH_PORTS), slaveAck_o=>slaveAck(SWITCH_PORTS),
+ lookupStb_o=>masterLookupStb(SWITCH_PORTS),
+ lookupAddr_o=>masterLookupAddr(SWITCH_PORTS),
+ lookupData_i=>masterLookupData(SWITCH_PORTS), lookupAck_i=>masterLookupAck(SWITCH_PORTS),
+ portLinkTimeout_o=>portLinkTimeout_o,
+ linkInitialized_i=>linkInitialized_i,
+ outputPortEnable_o=>outputPortEnable_o, inputPortEnable_o=>inputPortEnable_o,
+ localAckIdWrite_o=>localAckIdWrite_o, clrOutstandingAckId_o=>clrOutstandingAckId_o,
+ inboundAckId_o=>inboundAckId_o, outstandingAckId_o=>outstandingAckId_o,
+ outboundAckId_o=>outboundAckId_o, inboundAckId_i=>inboundAckId_i,
+ outstandingAckId_i=>outstandingAckId_i, outboundAckId_i=>outboundAckId_i,
+ configStb_o=>configStb_o, configWe_o=>configWe_o, configAddr_o=>configAddr_o,
+ configData_o=>configData_o, configData_i=>configData_i);
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- SwitchPort
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for SwitchPort.
+-------------------------------------------------------------------------------
+entity SwitchPort is
+ generic(
+ PORT_INDEX : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ -- Master port signals.
+ -- Write frames to other ports.
+ masterCyc_o : out std_logic;
+ masterStb_o : out std_logic;
+ masterWe_o : out std_logic;
+ masterAddr_o : out std_logic_vector(9 downto 0);
+ masterData_o : out std_logic_vector(31 downto 0);
+ masterData_i : in std_logic;
+ masterAck_i : in std_logic;
+
+ -- Slave port signals.
+ -- Receives frames from other ports.
+ slaveCyc_i : in std_logic;
+ slaveStb_i : in std_logic;
+ slaveWe_i : in std_logic;
+ slaveAddr_i : in std_logic_vector(9 downto 0);
+ slaveData_i : in std_logic_vector(31 downto 0);
+ slaveData_o : out std_logic;
+ slaveAck_o : out std_logic;
+
+ -- Address-lookup interface.
+ lookupStb_o : out std_logic;
+ lookupAddr_o : out std_logic_vector(15 downto 0);
+ lookupData_i : in std_logic_vector(7 downto 0);
+ lookupAck_i : in std_logic;
+
+ -- Physical port frame buffer interface.
+ readFrameEmpty_i : in std_logic;
+ readFrame_o : out std_logic;
+ readFrameRestart_o : out std_logic;
+ readFrameAborted_i : in std_logic;
+ readContentEmpty_i : in std_logic;
+ readContent_o : out std_logic;
+ readContentEnd_i : in std_logic;
+ readContentData_i : in std_logic_vector(31 downto 0);
+ writeFrameFull_i : in std_logic;
+ writeFrame_o : out std_logic;
+ writeFrameAbort_o : out std_logic;
+ writeContent_o : out std_logic;
+ writeContentData_o : out std_logic_vector(31 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for SwitchPort.
+-------------------------------------------------------------------------------
+architecture SwitchPortImpl of SwitchPort is
+
+ type MasterStateType is (STATE_IDLE,
+ STATE_WAIT_HEADER_0, STATE_READ_HEADER_0,
+ STATE_READ_PORT_LOOKUP,
+ STATE_READ_TARGET_PORT,
+ STATE_WAIT_TARGET_PORT,
+ STATE_WAIT_TARGET_WRITE,
+ STATE_WAIT_COMPLETE);
+ signal masterState : MasterStateType;
+
+ type SlaveStateType is (STATE_IDLE, STATE_SEND_ACK);
+ signal slaveState : SlaveStateType;
+
+ alias ftype : std_logic_vector(3 downto 0) is readContentData_i(19 downto 16);
+ alias tt : std_logic_vector(1 downto 0) is readContentData_i(21 downto 20);
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Master interface process.
+ -----------------------------------------------------------------------------
+ Master: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ masterState <= STATE_IDLE;
+
+ lookupStb_o <= '0';
+ lookupAddr_o <= (others => '0');
+
+ masterCyc_o <= '0';
+ masterStb_o <= '0';
+ masterWe_o <= '0';
+ masterAddr_o <= (others => '0');
+ masterData_o <= (others => '0');
+
+ readContent_o <= '0';
+ readFrame_o <= '0';
+ readFrameRestart_o <= '0';
+ elsif (clk'event and clk = '1') then
+ readContent_o <= '0';
+ readFrame_o <= '0';
+ readFrameRestart_o <= '0';
+
+ -- REMARK: Add support for aborted frames...
+ case masterState is
+
+ when STATE_IDLE =>
+ ---------------------------------------------------------------------
+ -- Wait for a new packet or content of a new packet.
+ ---------------------------------------------------------------------
+
+ -- Reset bus signals.
+ masterCyc_o <= '0';
+ masterStb_o <= '0';
+
+ -- Wait for frame content to be available.
+ -- Use different signals to trigger the forwarding of packets depending
+ -- on the switch philosofy.
+ if (readFrameEmpty_i = '0') then
+ readContent_o <= '1';
+ masterState <= STATE_WAIT_HEADER_0;
+ end if;
+
+ when STATE_WAIT_HEADER_0 =>
+ ---------------------------------------------------------------------
+ -- Wait for the frame buffer output to be updated.
+ ---------------------------------------------------------------------
+
+ -- Wait for frame buffer output to be updated.
+ masterState <= STATE_READ_HEADER_0;
+
+ when STATE_READ_HEADER_0 =>
+ ---------------------------------------------------------------------
+ -- Check the FTYPE and forward it to the maintenance port if it is a
+ -- maintenance packet. Otherwise, initiate an address lookup and wait
+ -- for the result.
+ ---------------------------------------------------------------------
+
+ -- Check if the frame has ended.
+ if (readContentEnd_i = '0') then
+ -- The frame has not ended.
+ -- This word contains the header and the source id.
+
+ -- Read the tt-field to check the source and destination id size.
+ if (tt = "01") then
+ -- This frame contains 16-bit addresses.
+
+ -- Read the new content.
+ readContent_o <= '1';
+
+ -- Save the content of the header and destination.
+ masterData_o <= readContentData_i;
+
+ -- Check if this is a maintenance frame.
+ if (ftype = FTYPE_MAINTENANCE_CLASS) then
+ -- This is a maintenance frame.
+
+ -- Always route these frames to the maintenance module in the
+ -- switch by setting the MSB bit of the port address.
+ masterAddr_o <= '1' & std_logic_vector(to_unsigned(PORT_INDEX, 8)) & '0';
+
+ -- Start an access to the maintenance port.
+ masterState <= STATE_READ_TARGET_PORT;
+ else
+ -- This is not a maintenance frame.
+
+ -- Lookup the destination address and proceed to wait for the
+ -- result.
+ lookupStb_o <= '1';
+ lookupAddr_o <= readContentData_i(15 downto 0);
+
+ -- Wait for the port lookup to return a result.
+ masterState <= STATE_READ_PORT_LOOKUP;
+ end if;
+ else
+ -- Unsupported tt-value, discard the frame.
+ readFrame_o <= '1';
+ masterState <= STATE_IDLE;
+ end if;
+ else
+ -- End of frame.
+ -- The frame is too short to contain a valid frame. Discard it.
+ readFrame_o <= '1';
+ masterState <= STATE_IDLE;
+ end if;
+
+ when STATE_READ_PORT_LOOKUP =>
+ ---------------------------------------------------------------------
+ -- Wait for the address lookup to be complete.
+ ---------------------------------------------------------------------
+
+ -- Wait for the routing table to complete the request.
+ if (lookupAck_i = '1') then
+ -- The address lookup is complete.
+
+ -- Terminate the lookup cycle.
+ lookupStb_o <= '0';
+
+ -- Proceed to read the target port.
+ masterAddr_o <= '0' & lookupData_i & '0';
+ masterState <= STATE_READ_TARGET_PORT;
+ else
+ -- Wait until the address lookup is complete.
+ -- REMARK: Timeout here???
+ end if;
+
+ when STATE_READ_TARGET_PORT =>
+ ---------------------------------------------------------------------
+ -- Initiate an access to the target port.
+ ---------------------------------------------------------------------
+
+ -- Read the status of the target port using the result from the
+ -- lookup in the routing table.
+ masterCyc_o <= '1';
+ masterStb_o <= '1';
+ masterWe_o <= '0';
+ masterState <= STATE_WAIT_TARGET_PORT;
+
+ when STATE_WAIT_TARGET_PORT =>
+ ---------------------------------------------------------------------
+ -- Wait to get access to the target port. When the port is ready
+ -- check if it is ready to accept a new frame. If it cannot accept a
+ -- new frame, terminate the access and go back and start a new one.
+ -- This is to free the interconnect to let other ports access it if
+ -- it is a shared bus. If the port is ready, initiate a write access
+ -- to the selected port.
+ ---------------------------------------------------------------------
+
+ -- Wait for the target port to complete the request.
+ if (masterAck_i = '1') then
+ -- Target port has completed the request.
+
+ -- Check the status of the target port.
+ if (masterData_i = '0') then
+ -- The target port has empty buffers to receive the frame.
+
+ -- Hold the bus with cyc until the cycle is complete.
+ -- Write the first word of the frame to the target port.
+ -- The masterData_o has already been assigned.
+ masterCyc_o <= '1';
+ masterStb_o <= '1';
+ masterWe_o <= '1';
+ masterAddr_o(0) <= '1';
+
+ -- Change state to transfer the frame.
+ masterState <= STATE_WAIT_TARGET_WRITE;
+ else
+ -- The target port has no empty buffer to receive the frame.
+ -- Terminate the cycle and retry later.
+ masterCyc_o <= '0';
+ masterStb_o <= '0';
+ masterState <= STATE_READ_TARGET_PORT;
+ end if;
+ else
+ -- Target port has not completed the request.
+ -- Dont to anything.
+ end if;
+
+ when STATE_WAIT_TARGET_WRITE =>
+ ---------------------------------------------------------------------
+ -- Wait for the write access to complete. When complete, write the
+ -- next content and update the content to the next. If the frame does
+ -- not have any more data ready, terminate the access but keep the
+ -- cycle active and proceed to wait for new data.
+ ---------------------------------------------------------------------
+
+ -- Wait for the target port to complete the request.
+ -- REMARK: Remove the ack-condition, we know that the write takes one
+ -- cycle...
+ if (masterAck_i = '1') then
+ -- The target port is ready.
+
+ -- Check if the frame has ended.
+ if (readContentEnd_i = '0') then
+ -- The frame has not ended.
+
+ -- There are more data to transfer.
+ masterData_o <= readContentData_i;
+ readContent_o <= '1';
+ else
+ -- There are no more data to transfer.
+
+ -- Update to the next frame.
+ readFrame_o <= '1';
+
+ -- Tell the target port that the frame is complete.
+ masterWe_o <= '1';
+ masterAddr_o(0) <= '0';
+ masterData_o <= x"00000001";
+
+ -- Change state to wait for the target port to finalize the write
+ -- of the full frame.
+ masterState <= STATE_WAIT_COMPLETE;
+ end if;
+ else
+ -- Wait for the target port to reply.
+ -- Dont do anything.
+ end if;
+
+ when STATE_WAIT_COMPLETE =>
+ ---------------------------------------------------------------------
+ -- Wait for the target port to signal that the frame has been
+ -- completed.
+ ---------------------------------------------------------------------
+
+ -- Wait for the target port to complete the final request.
+ if (masterAck_i = '1') then
+ -- The target port has finalized the write of the frame.
+
+ -- Reset master bus signals.
+ masterCyc_o <= '0';
+ masterStb_o <= '0';
+ masterState <= STATE_IDLE;
+ else
+ -- Wait for the target port to reply.
+ -- REMARK: Timeout here???
+ end if;
+
+ when others =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+ end case;
+ end if;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Slave interface process.
+ -----------------------------------------------------------------------------
+ -- Addr | Read | Write
+ -- 0 | full | abort & complete
+ -- 1 | full | frameData
+ writeContentData_o <= slaveData_i;
+ Slave: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ slaveState <= STATE_IDLE;
+
+ slaveData_o <= '0';
+
+ writeFrame_o <= '0';
+ writeFrameAbort_o <= '0';
+ writeContent_o <= '0';
+ elsif (clk'event and clk = '1') then
+ writeFrame_o <= '0';
+ writeFrameAbort_o <= '0';
+ writeContent_o <= '0';
+
+ case slaveState is
+
+ when STATE_IDLE =>
+ ---------------------------------------------------------------------
+ -- Wait for an access from a master.
+ ---------------------------------------------------------------------
+
+ -- Check if any cycle is active.
+ if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then
+ -- Cycle is active.
+
+ -- Check if the cycle is accessing the status- or data address.
+ if (slaveAddr_i(0) = '0') then
+ -- Accessing port status address.
+
+ -- Check if writing.
+ if (slaveWe_i = '1') then
+ -- Writing the status address.
+ -- Update the buffering output signals according to the input
+ -- data.
+ writeFrame_o <= slaveData_i(0);
+ writeFrameAbort_o <= slaveData_i(1);
+ else
+ -- Reading the status address.
+ slaveData_o <= writeFrameFull_i;
+ end if;
+ else
+ -- Accessing port data address.
+
+ -- Check if writing.
+ if (slaveWe_i = '1') then
+ -- Write frame content into the frame buffer.
+ writeContent_o <= '1';
+ else
+ slaveData_o <= writeFrameFull_i;
+ end if;
+ end if;
+
+ -- Change state to send an ack to the master.
+ slaveState <= STATE_SEND_ACK;
+ end if;
+
+ when STATE_SEND_ACK =>
+ ---------------------------------------------------------------------
+ -- Wait for acknowledge to be received by the master.
+ ---------------------------------------------------------------------
+
+ -- Go back to the idle state and wait for a new cycle.
+ slaveState <= STATE_IDLE;
+
+ when others =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+ null;
+
+ end case;
+ end if;
+ end process;
+
+ -- Assign the acknowledge depending on the current slave state.
+ slaveAck_o <= '1' when (slaveState = STATE_SEND_ACK) else '0';
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- SwitchPortMaintenance
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for SwitchPortMaintenance.
+-------------------------------------------------------------------------------
+entity SwitchPortMaintenance is
+ generic(
+ SWITCH_PORTS : natural range 0 to 255;
+ DEVICE_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_REV : std_logic_vector(31 downto 0);
+ ASSY_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_REV : std_logic_vector(15 downto 0));
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ -- Routing table port lookup signals.
+ lookupStb_i : in std_logic;
+ lookupAddr_i : in std_logic_vector(15 downto 0);
+ lookupData_o : out std_logic_vector(7 downto 0);
+ lookupAck_o : out std_logic;
+
+ -- Master port signals.
+ -- Write frames to other ports.
+ masterCyc_o : out std_logic;
+ masterStb_o : out std_logic;
+ masterWe_o : out std_logic;
+ masterAddr_o : out std_logic_vector(9 downto 0);
+ masterData_o : out std_logic_vector(31 downto 0);
+ masterData_i : in std_logic;
+ masterAck_i : in std_logic;
+
+ -- Slave port signals.
+ -- Receives frames from other ports.
+ slaveCyc_i : in std_logic;
+ slaveStb_i : in std_logic;
+ slaveWe_i : in std_logic;
+ slaveAddr_i : in std_logic_vector(9 downto 0);
+ slaveData_i : in std_logic_vector(31 downto 0);
+ slaveData_o : out std_logic;
+ slaveAck_o : out std_logic;
+
+ -- Address-lookup interface.
+ lookupStb_o : out std_logic;
+ lookupAddr_o : out std_logic_vector(15 downto 0);
+ lookupData_i : in std_logic_vector(7 downto 0);
+ lookupAck_i : in std_logic;
+
+ -- Port common access interface.
+ portLinkTimeout_o : out std_logic_vector(23 downto 0);
+
+ -- Port specific access interface.
+ linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0);
+ outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
+ inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
+ localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0);
+ clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0);
+ inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+ outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+ outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+
+ -- Configuration space for implementation-defined space.
+ configStb_o : out std_logic;
+ configWe_o : out std_logic;
+ configAddr_o : out std_logic_vector(23 downto 0);
+ configData_o : out std_logic_vector(31 downto 0);
+ configData_i : in std_logic_vector(31 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for SwitchPort.
+-------------------------------------------------------------------------------
+architecture SwitchPortMaintenanceImpl of SwitchPortMaintenance is
+
+ component MemoryDualPort is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ writeEnableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ dataA_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ clkB_i : in std_logic;
+ enableB_i : in std_logic;
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+ end component;
+
+ component MemorySinglePort is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clk_i : in std_logic;
+ enable_i : in std_logic;
+ writeEnable_i : in std_logic;
+ address_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ data_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ data_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+ end component;
+
+ component Crc16CITT is
+ port(
+ d_i : in std_logic_vector(15 downto 0);
+ crc_i : in std_logic_vector(15 downto 0);
+ crc_o : out std_logic_vector(15 downto 0));
+ end component;
+
+ type MasterStateType is (STATE_IDLE,
+ STATE_CHECK_FRAME,
+ STATE_RELAY_READ_RESPONSE,
+ STATE_RELAY_WRITE_RESPONSE,
+ STATE_SEND_READ_REQUEST,
+ STATE_SEND_WRITE_REQUEST,
+ STATE_SEND_READ_RESPONSE,
+ STATE_SEND_WRITE_RESPONSE,
+ STATE_START_PORT_LOOKUP,
+ STATE_READ_PORT_LOOKUP,
+ STATE_READ_TARGET_PORT,
+ STATE_WAIT_TARGET_PORT,
+ STATE_WAIT_TARGET_WRITE,
+ STATE_WAIT_COMPLETE,
+ STATE_WAIT_SLAVE);
+ signal masterState : MasterStateType;
+
+ signal crc16Data : std_logic_vector(31 downto 0);
+ signal crc16Current : std_logic_vector(15 downto 0);
+ signal crc16Temp : std_logic_vector(15 downto 0);
+ signal crc16Next : std_logic_vector(15 downto 0);
+
+ signal configEnable : std_logic;
+ signal configWrite : std_logic;
+ signal configAddress : std_logic_vector(23 downto 0);
+ signal configDataWrite : std_logic_vector(31 downto 0);
+ signal configDataRead, configDataReadInternal : std_logic_vector(31 downto 0);
+
+ signal outboundFrameEnable : std_logic;
+ signal outboundFrameWrite : std_logic;
+ signal outboundFrameAddress : std_logic_vector(2 downto 0);
+ signal outboundFrameDataWrite : std_logic_vector(31 downto 0);
+ signal outboundFrameDataRead : std_logic_vector(31 downto 0);
+ signal outboundFrameLength : std_logic_vector(2 downto 0);
+
+ type SlaveStateType is (STATE_READY,
+ STATE_BUSY);
+ signal slaveState : SlaveStateType;
+ signal slaveAck : std_logic;
+
+ signal inboundFrameReady : std_logic;
+ signal inboundFramePort : std_logic_vector(7 downto 0);
+ signal inboundFrameLength : natural range 0 to 7;
+ signal inboundFrameComplete : std_logic;
+
+ signal vc : std_logic;
+ signal crf : std_logic;
+ signal prio : std_logic_vector(1 downto 0);
+ signal tt : std_logic_vector(1 downto 0);
+ signal ftype : std_logic_vector(3 downto 0);
+ signal destinationId : std_logic_vector(15 downto 0);
+ signal sourceId : std_logic_vector(15 downto 0);
+ signal transaction : std_logic_vector(3 downto 0);
+ signal size : std_logic_vector(3 downto 0);
+ signal srcTid : std_logic_vector(7 downto 0);
+ signal hopCount : std_logic_vector(7 downto 0);
+ signal configOffset : std_logic_vector(20 downto 0);
+ signal wdptr : std_logic;
+ signal content : std_logic_vector(63 downto 0);
+
+ -----------------------------------------------------------------------------
+ -- Route table access signals.
+ -----------------------------------------------------------------------------
+
+ signal address0 : std_logic_vector(7 downto 0);
+ signal address1 : std_logic_vector(7 downto 0);
+ signal address2 : std_logic_vector(7 downto 0);
+ signal address3 : std_logic_vector(7 downto 0);
+
+ signal lookupEnable : std_logic;
+ signal lookupAddress : std_logic_vector(10 downto 0);
+ signal lookupData : std_logic_vector(7 downto 0);
+ signal lookupAck : std_logic;
+
+ signal routeTableEnable : std_logic;
+ signal routeTableWrite : std_logic;
+ signal routeTableAddress : std_logic_vector(10 downto 0);
+ signal routeTablePortWrite : std_logic_vector(7 downto 0);
+ signal routeTablePortRead : std_logic_vector(7 downto 0);
+
+ signal routeTablePortDefault : std_logic_vector(7 downto 0);
+
+ -----------------------------------------------------------------------------
+ -- Configuration space signals.
+ -----------------------------------------------------------------------------
+
+ signal discovered : std_logic;
+
+ signal hostBaseDeviceIdLocked : std_logic;
+ signal hostBaseDeviceId : std_logic_vector(15 downto 0);
+ signal componentTag : std_logic_vector(31 downto 0);
+
+ signal portLinkTimeout : std_logic_vector(23 downto 0);
+
+ signal outputPortEnable : Array1(SWITCH_PORTS-1 downto 0);
+ signal inputPortEnable : Array1(SWITCH_PORTS-1 downto 0);
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Memory to contain the outbound frame.
+ -----------------------------------------------------------------------------
+
+ OutboundFrameMemory: MemorySinglePort
+ generic map(
+ ADDRESS_WIDTH=>3, DATA_WIDTH=>32)
+ port map(
+ clk_i=>clk,
+ enable_i=>outboundFrameEnable, writeEnable_i=>outboundFrameWrite,
+ address_i=>outboundFrameAddress,
+ data_i=>outboundFrameDataWrite, data_o=>outboundFrameDataRead);
+
+ -----------------------------------------------------------------------------
+ -- CRC generation for outbound frames.
+ -----------------------------------------------------------------------------
+
+ crc16Data <= outboundFrameDataWrite;
+
+ -- REMARK: Insert FFs here to make the critical path shorter...
+ Crc16High: Crc16CITT
+ port map(
+ d_i=>crc16Data(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp);
+ Crc16Low: Crc16CITT
+ port map(
+ d_i=>crc16Data(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next);
+
+ -----------------------------------------------------------------------------
+ -- Master interface process.
+ -----------------------------------------------------------------------------
+ Master: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ masterState <= STATE_IDLE;
+
+ lookupStb_o <= '0';
+ lookupAddr_o <= (others => '0');
+
+ masterCyc_o <= '0';
+ masterStb_o <= '0';
+ masterWe_o <= '0';
+ masterAddr_o <= (others => '0');
+ masterData_o <= (others => '0');
+
+ configEnable <= '0';
+ configWrite <= '0';
+ configAddress <= (others => '0');
+ configDataWrite <= (others => '0');
+
+ outboundFrameEnable <= '0';
+ outboundFrameWrite <= '0';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameDataWrite <= (others=>'0');
+ outboundFrameLength <= (others=>'0');
+
+ inboundFrameComplete <= '0';
+ elsif (clk'event and clk = '1') then
+ configEnable <= '0';
+ configWrite <= '0';
+ inboundFrameComplete <= '0';
+
+ case masterState is
+
+ when STATE_IDLE =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Wait for a full frame to be available.
+ if (inboundFrameReady = '1') then
+ if (inboundFrameLength > 3) then
+ masterState <= STATE_CHECK_FRAME;
+ else
+ -- Frame is too short.
+ -- REMARK: Discard the frame.
+ end if;
+ end if;
+
+ when STATE_CHECK_FRAME =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Check if the frame has 16-bit addresses and is a maintenance frame.
+ if (tt = "01") and (ftype = FTYPE_MAINTENANCE_CLASS) then
+ -- Maintenance class frame and 16-bit addresses.
+
+ -- Check the frame type.
+ case transaction is
+
+ when "0000" =>
+ ---------------------------------------------------------------
+ -- Maintenance read request.
+ ---------------------------------------------------------------
+
+ -- Check if the frame is for us.
+ if (hopCount = x"00") then
+ -- This frame is for us.
+ configEnable <= '1';
+ configWrite <= '0';
+ configAddress <= configOffset & wdptr & "00";
+
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & sourceId;
+ crc16Current <= x"ffff";
+
+ masterState <= STATE_SEND_READ_RESPONSE;
+ else
+ -- This frame is not for us.
+ -- Decrement hop_count and relay.
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId;
+ crc16Current <= x"ffff";
+
+ masterState <= STATE_SEND_READ_REQUEST;
+ end if;
+
+ when "0001" =>
+ ---------------------------------------------------------------
+ -- Maintenance write request.
+ ---------------------------------------------------------------
+
+ -- Check if the frame is for us.
+ if (hopCount = x"00") then
+ -- This frame is for us.
+ configEnable <= '1';
+ configWrite <= '1';
+ configAddress <= configOffset & wdptr & "00";
+
+ if (wdptr = '0') then
+ configDataWrite <= content(63 downto 32);
+ else
+ configDataWrite <= content(31 downto 0);
+ end if;
+
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & sourceId;
+ crc16Current <= x"ffff";
+
+ masterState <= STATE_SEND_WRITE_RESPONSE;
+ else
+ -- This frame is not for us.
+ -- Decrement hop_count and relay.
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId;
+ crc16Current <= x"ffff";
+
+ masterState <= STATE_SEND_WRITE_REQUEST;
+ end if;
+
+ when "0010" =>
+ ---------------------------------------------------------------
+ -- Maintenance read response frame.
+ ---------------------------------------------------------------
+
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId;
+ crc16Current <= x"ffff";
+
+ -- Relay frame.
+ masterState <= STATE_RELAY_READ_RESPONSE;
+
+ when "0011" =>
+ ---------------------------------------------------------------
+ -- Maintenance write response frame.
+ ---------------------------------------------------------------
+
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId;
+ crc16Current <= x"ffff";
+
+ -- Relay frame.
+ masterState <= STATE_RELAY_WRITE_RESPONSE;
+
+ when "0100" =>
+ ---------------------------------------------------------------
+ -- Maintenance port write frame.
+ ---------------------------------------------------------------
+
+ -- REMARK: Support these???
+
+ when others =>
+ ---------------------------------------------------------------
+ -- Unsupported frame type.
+ ---------------------------------------------------------------
+
+ -- REMARK: Support these???
+ end case;
+ else
+ -- Non-maintenance class frame or unsupported address type.
+ -- REMARK: These should not end up here... discard them???
+ end if;
+
+ when STATE_RELAY_READ_RESPONSE =>
+ ---------------------------------------------------------------------
+ -- A maintenance response has been received. It should be relayed as
+ -- is using the destinationId.
+ ---------------------------------------------------------------------
+
+ case to_integer(unsigned(outboundFrameAddress)) is
+ when 0 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= sourceId & transaction & size & srcTid;
+ crc16Current <= crc16Next;
+ when 1 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= hopCount & configOffset & wdptr & "00";
+ crc16Current <= crc16Next;
+ when 2 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= content(63 downto 32);
+ crc16Current <= crc16Next;
+ when 3 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= content(31 downto 0);
+ crc16Current <= crc16Next;
+ when 4 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite(31 downto 16) <= crc16Next;
+ outboundFrameDataWrite(15 downto 0) <= x"0000";
+ when others =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '0';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ masterState <= STATE_START_PORT_LOOKUP;
+ end case;
+
+ when STATE_RELAY_WRITE_RESPONSE =>
+ ---------------------------------------------------------------------
+ -- A maintenance response has been received. It should be relayed as
+ -- is using the destinationId.
+ ---------------------------------------------------------------------
+
+ case to_integer(unsigned(outboundFrameAddress)) is
+ when 0 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= sourceId & transaction & size & srcTid;
+ crc16Current <= crc16Next;
+ when 1 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= hopCount & configOffset & wdptr & "00";
+ crc16Current <= crc16Next;
+ when 2 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite(31 downto 16) <= crc16Next;
+ outboundFrameDataWrite(15 downto 0) <= x"0000";
+ when others =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '0';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ masterState <= STATE_START_PORT_LOOKUP;
+ end case;
+
+ when STATE_SEND_READ_REQUEST =>
+ ---------------------------------------------------------------------
+ -- A read request has been received but the hopcount is larger than
+ -- zero. Decrement the hopcount, recalculate the crc and relay the
+ -- frame using the destinationId.
+ ---------------------------------------------------------------------
+
+ case to_integer(unsigned(outboundFrameAddress)) is
+ when 0 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= sourceId & transaction & size & srcTid;
+ crc16Current <= crc16Next;
+ when 1 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= std_logic_vector(unsigned(hopCount) - 1) & configOffset & wdptr & "00";
+ crc16Current <= crc16Next;
+ when 2 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite(31 downto 16) <= crc16Next;
+ outboundFrameDataWrite(15 downto 0) <= x"0000";
+ when others =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '0';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ masterState <= STATE_START_PORT_LOOKUP;
+ end case;
+
+ when STATE_SEND_WRITE_REQUEST =>
+ ---------------------------------------------------------------------
+ -- A write request has been received but the hopcount is larger than
+ -- zero. Decrement the hopcount, recalculate the crc and relay the
+ -- frame using the destinationId.
+ ---------------------------------------------------------------------
+
+ case to_integer(unsigned(outboundFrameAddress)) is
+ when 0 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= sourceId & transaction & size & srcTid;
+ crc16Current <= crc16Next;
+ when 1 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= std_logic_vector(unsigned(hopCount) - 1) & configOffset & wdptr & "00";
+ crc16Current <= crc16Next;
+ when 2 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= content(63 downto 32);
+ crc16Current <= crc16Next;
+ when 3 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= content(31 downto 0);
+ crc16Current <= crc16Next;
+ when 4 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite(31 downto 16) <= crc16Next;
+ outboundFrameDataWrite(15 downto 0) <= x"0000";
+ when others =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '0';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ masterState <= STATE_START_PORT_LOOKUP;
+ end case;
+
+ when STATE_SEND_READ_RESPONSE =>
+ ---------------------------------------------------------------------
+ -- A read request has been received with a hopcount that are zero.
+ -- Create a read response, calculate crc and write it to the port it
+ -- came from.
+ ---------------------------------------------------------------------
+
+ case to_integer(unsigned(outboundFrameAddress)) is
+ when 0 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= destinationId & "0010" & "0000" & srcTid;
+ crc16Current <= crc16Next;
+ when 1 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= x"ff" & x"000000";
+ crc16Current <= crc16Next;
+ when 2 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ if (wdptr = '1') then
+ outboundFrameDataWrite <= (others => '0');
+ else
+ outboundFrameDataWrite <= configDataRead(31 downto 0);
+ end if;
+ crc16Current <= crc16Next;
+ when 3 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ if (wdptr = '1') then
+ outboundFrameDataWrite <= configDataRead(31 downto 0);
+ else
+ outboundFrameDataWrite <= (others => '0');
+ end if;
+ crc16Current <= crc16Next;
+ when 4 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite(31 downto 16) <= crc16Next;
+ outboundFrameDataWrite(15 downto 0) <= x"0000";
+ when others =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '0';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ masterAddr_o <= '0' & inboundFramePort & '0';
+ masterState <= STATE_READ_TARGET_PORT;
+ end case;
+
+ when STATE_SEND_WRITE_RESPONSE =>
+ ---------------------------------------------------------------------
+ -- A write request has been received with a hopcount that are zero.
+ -- Create a write response, calculate crc and write it to the port it
+ -- came from.
+ ---------------------------------------------------------------------
+
+ case to_integer(unsigned(outboundFrameAddress)) is
+ when 0 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= destinationId & "0011" & "0000" & srcTid;
+ crc16Current <= crc16Next;
+ when 1 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= x"ff" & x"000000";
+ crc16Current <= crc16Next;
+ when 2 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite(31 downto 16) <= crc16Next;
+ outboundFrameDataWrite(15 downto 0) <= x"0000";
+ when others =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '0';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ masterAddr_o <= '0' & inboundFramePort & '0';
+ masterState <= STATE_READ_TARGET_PORT;
+ end case;
+
+ when STATE_START_PORT_LOOKUP =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Initiate a port-lookup of the destination address.
+ lookupStb_o <= '1';
+ lookupAddr_o <= destinationId;
+ masterState <= STATE_READ_PORT_LOOKUP;
+
+ when STATE_READ_PORT_LOOKUP =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Wait for the routing table to complete the request.
+ if (lookupAck_i = '1') then
+ -- The address lookup is complete.
+
+ -- Terminate the lookup cycle.
+ lookupStb_o <= '0';
+
+ -- Wait for the target port to reply.
+ masterAddr_o <= '0' & lookupData_i & '0';
+ masterState <= STATE_READ_TARGET_PORT;
+ else
+ -- Wait until the address lookup is complete.
+ -- REMARK: Timeout here???
+ end if;
+
+ when STATE_READ_TARGET_PORT =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Read the status of the target port using the result from the
+ -- lookup in the routing table.
+ masterCyc_o <= '1';
+ masterStb_o <= '1';
+ masterWe_o <= '0';
+ masterState <= STATE_WAIT_TARGET_PORT;
+
+ when STATE_WAIT_TARGET_PORT =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Wait for the target port to complete the request.
+ if (masterAck_i = '1') then
+ if (masterData_i = '0') then
+ -- The target port has empty buffers to receive the frame.
+
+ -- Write the first word of the frame to the target port.
+ -- The masterData_o has already been assigned.
+ masterCyc_o <= '1';
+ masterStb_o <= '1';
+ masterWe_o <= '1';
+ masterAddr_o(0) <= '1';
+
+ -- Read the first word in the frame and update the frame address.
+ masterData_o <= outboundFrameDataRead;
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+
+ -- Change state to transfer the frame.
+ masterState <= STATE_WAIT_TARGET_WRITE;
+ else
+ -- The target port has no empty buffer to receive the frame.
+ -- Terminate the cycle and retry later.
+ masterCyc_o <= '0';
+ masterStb_o <= '0';
+ masterState <= STATE_READ_TARGET_PORT;
+ end if;
+ else
+ -- Wait for the target port to reply.
+ -- REMARK: Timeout here???
+ end if;
+
+ when STATE_WAIT_TARGET_WRITE =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Wait for the target port to complete the request.
+ if (masterAck_i = '1') then
+ -- The target port is ready.
+
+ -- Check if the frame has ended.
+ if (outboundFrameLength /= outboundFrameAddress) then
+ -- The frame has not ended.
+
+ -- There are more data to transfer.
+ masterData_o <= outboundFrameDataRead;
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ else
+ -- There are no more data to transfer.
+
+ -- Tell the target port that the frame is complete.
+ masterWe_o <= '1';
+ masterAddr_o(0) <= '0';
+ masterData_o <= x"00000001";
+ outboundFrameAddress <= (others=>'0');
+
+ -- Change state to wait for the target port to finalize the write
+ -- of the full frame.
+ masterState <= STATE_WAIT_COMPLETE;
+ end if;
+ else
+ -- Wait for the target port to reply.
+ -- REMARK: Timeout here???
+ end if;
+
+ when STATE_WAIT_COMPLETE =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Wait for the target port to complete the final request.
+ if (masterAck_i = '1') then
+ -- The target port has finalized the write of the frame.
+ masterCyc_o <= '0';
+ masterStb_o <= '0';
+ masterState <= STATE_WAIT_SLAVE;
+
+ -- Indicate the frame has been read.
+ inboundFrameComplete <= '1';
+ else
+ -- Wait for the target port to reply.
+ -- REMARK: Timeout here???
+ end if;
+
+ when STATE_WAIT_SLAVE =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+ masterState <= STATE_IDLE;
+
+ when others =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+ end case;
+ end if;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Slave interface process.
+ -----------------------------------------------------------------------------
+ -- Addr | Read | Write
+ -- 0 | full | abort & complete
+ -- 1 | full | frameData
+ Slave: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ slaveState <= STATE_READY;
+ slaveData_o <= '0';
+ slaveAck <= '0';
+
+ vc <= '0';
+ crf <= '0';
+ prio <= (others=>'0');
+ tt <= (others=>'0');
+ ftype <= (others=>'0');
+ destinationId <= (others=>'0');
+ sourceId <= (others=>'0');
+ transaction <= (others=>'0');
+ size <= (others=>'0');
+ srcTid <= (others=>'0');
+ hopCount <= (others=>'0');
+ configOffset <= (others=>'0');
+ wdptr <= '0';
+ content <= (others=>'0');
+
+ inboundFrameReady <= '0';
+ inboundFramePort <= (others => '0');
+ inboundFrameLength <= 0;
+ elsif (clk'event and clk = '1') then
+ slaveAck <= '0';
+
+ case slaveState is
+ when STATE_READY =>
+ ---------------------------------------------------------------------
+ -- Ready to receive a new frame.
+ ---------------------------------------------------------------------
+
+ -- Check if any cycle is active.
+ if ((slaveCyc_i = '1') and (slaveStb_i = '1') and (slaveAck = '0')) then
+ -- Cycle is active.
+
+ -- Check if writing.
+ if (slaveWe_i = '1') then
+ -- Writing request.
+
+ -- Check if the cycle is accessing the status- or data address.
+ if (slaveAddr_i(0) = '0') then
+ -- Writing to port status address.
+
+ if (slaveData_i(0) = '1') and (slaveData_i(1) = '0') then
+ -- A frame has been written.
+
+ -- Indicate the frame is ready for processing.
+ -- The slave address contains the number of the accessing port.
+ inboundFrameReady <= '1';
+ inboundFramePort <= slaveAddr_i(8 downto 1);
+
+ -- Change state until the frame has been processed.
+ slaveState <= STATE_BUSY;
+ else
+ -- The frame has been aborted.
+ -- Reset the received frame length.
+ inboundFrameLength <= 0;
+ end if;
+ else
+ -- Write frame content into the frame buffer.
+
+ -- Check which frame index that is written.
+ case inboundFrameLength is
+ when 0 =>
+ vc <= slaveData_i(25);
+ crf <= slaveData_i(24);
+ prio <= slaveData_i(23 downto 22);
+ tt <= slaveData_i(21 downto 20);
+ ftype <= slaveData_i(19 downto 16);
+ destinationId <= slaveData_i(15 downto 0);
+ inboundFrameLength <= inboundFrameLength + 1;
+ when 1 =>
+ sourceId <= slaveData_i(31 downto 16);
+ transaction <= slaveData_i(15 downto 12);
+ size <= slaveData_i(11 downto 8);
+ srcTid <= slaveData_i(7 downto 0);
+ inboundFrameLength <= inboundFrameLength + 1;
+ when 2 =>
+ hopCount <= slaveData_i(31 downto 24);
+ configOffset <= slaveData_i(23 downto 3);
+ wdptr <= slaveData_i(2);
+ inboundFrameLength <= inboundFrameLength + 1;
+ when 3 =>
+ -- Note that crc will be assigned here if there are no
+ -- content in the frame.
+ content(63 downto 32) <= slaveData_i;
+ inboundFrameLength <= inboundFrameLength + 1;
+ when 4 =>
+ content(31 downto 0) <= slaveData_i;
+ inboundFrameLength <= inboundFrameLength + 1;
+ when others =>
+ -- Dont support longer frames.
+ -- REMARK: Add support for longer frames??? Especially
+ -- received frames that only should be routed...
+ end case;
+ end if;
+
+ -- Send acknowledge.
+ slaveAck <= '1';
+ else
+ -- Reading request.
+
+ -- Reading the status address.
+ -- Always indicate that we are ready to accept a new frame.
+ slaveData_o <= '0';
+
+ -- Send acknowledge.
+ slaveAck <= '1';
+ end if;
+ else
+ -- No cycle is active.
+ end if;
+
+ when STATE_BUSY =>
+ ---------------------------------------------------------------------
+ -- Waiting for a received frame to be processed.
+ ---------------------------------------------------------------------
+
+ -- Check if any cycle is active.
+ if ((slaveCyc_i = '1') and (slaveStb_i = '1') and (slaveAck = '0')) then
+ -- Cycle is active.
+
+ -- Check if writing.
+ if (slaveWe_i = '1') then
+ -- Writing.
+ -- Dont do anything.
+
+ -- Send acknowledge.
+ slaveAck <= '1';
+ else
+ -- Read port data address.
+
+ -- Reading the status address.
+ -- Always indicate that we are busy.
+ slaveData_o <= '1';
+
+ -- Send acknowledge.
+ slaveAck <= '1';
+ end if;
+ else
+ -- No cycle is active.
+ -- Dont do anything.
+ end if;
+
+ -- Check if the master process has processed the received frame.
+ if (inboundFrameComplete = '1') then
+ -- The master has processed the frame.
+ inboundFrameReady <= '0';
+ inboundFrameLength <= 0;
+ slaveState <= STATE_READY;
+ else
+ -- The master is not ready yet.
+ -- Dont do anything.
+ end if;
+
+ when others =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+ null;
+
+ end case;
+ end if;
+ end process;
+
+ slaveAck_o <= slaveAck;
+
+ -----------------------------------------------------------------------------
+ -- Logic implementing the routing table access.
+ -----------------------------------------------------------------------------
+
+ -- Lookup interface port memory signals.
+ lookupEnable <= '1' when (lookupStb_i = '1') and (lookupAddr_i(15 downto 11) = "00000") else '0';
+ lookupAddress <= lookupAddr_i(10 downto 0);
+ lookupData_o <= lookupData when (lookupEnable = '1') else routeTablePortDefault;
+ lookupAck_o <= lookupAck;
+ LookupProcess: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ lookupAck <= '0';
+ elsif (clk'event and clk = '1') then
+ if ((lookupStb_i = '1') and (lookupAck = '0')) then
+ lookupAck <= '1';
+ else
+ lookupAck <= '0';
+ end if;
+ end if;
+ end process;
+
+ -- Dual port memory containing the routing table.
+ RoutingTable: MemoryDualPort
+ generic map(
+ ADDRESS_WIDTH=>11, DATA_WIDTH=>8)
+ port map(
+ clkA_i=>clk, enableA_i=>routeTableEnable, writeEnableA_i=>routeTableWrite,
+ addressA_i=>routeTableAddress,
+ dataA_i=>routeTablePortWrite, dataA_o=>routeTablePortRead,
+ clkB_i=>clk, enableB_i=>lookupEnable,
+ addressB_i=>lookupAddress, dataB_o=>lookupData);
+
+ -----------------------------------------------------------------------------
+ -- Configuration memory.
+ -----------------------------------------------------------------------------
+
+ portLinkTimeout_o <= portLinkTimeout;
+ outputPortEnable_o <= outputPortEnable;
+ inputPortEnable_o <= inputPortEnable;
+
+ configStb_o <= '1' when ((configEnable = '1') and (configAddress(23 downto 16) /= x"00")) else '0';
+ configWe_o <= configWrite;
+ configAddr_o <= configAddress;
+ configData_o <= configDataWrite;
+ configDataRead <= configData_i when (configAddress(23 downto 16) /= x"00") else
+ configDataReadInternal;
+
+ ConfigMemory: process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ configDataReadInternal <= (others => '0');
+
+ routeTableEnable <= '1';
+ routeTableWrite <= '0';
+ routeTableAddress <= (others => '0');
+ routeTablePortWrite <= (others => '0');
+ routeTablePortDefault <= (others => '0');
+
+ discovered <= '0';
+
+ hostBaseDeviceIdLocked <= '0';
+ hostBaseDeviceId <= (others => '1');
+ componentTag <= (others => '0');
+
+ portLinkTimeout <= (others => '1');
+
+ -- REMARK: These should be set to zero when a port gets initialized...
+ outputPortEnable <= (others => '0');
+ inputPortEnable <= (others => '0');
+
+ localAckIdWrite_o <= (others => '0');
+ elsif (clk'event and clk = '1') then
+ routeTableWrite <= '0';
+ localAckIdWrite_o <= (others => '0');
+
+ if (configEnable = '1') then
+ -- Check if the access is into implementation defined space or if the
+ -- access should be handled here.
+ if (configAddress(23 downto 16) /= x"00") then
+ -- Accessing implementation defined space.
+ -- Make an external access and return the resonse.
+ configDataReadInternal <= (others=>'0');
+ else
+ -- Access should be handled here.
+
+ case (configAddress) is
+ when x"000000" =>
+ -----------------------------------------------------------------
+ -- Device Identity CAR. Read-only.
+ -----------------------------------------------------------------
+
+ configDataReadInternal(31 downto 16) <= DEVICE_IDENTITY;
+ configDataReadInternal(15 downto 0) <= DEVICE_VENDOR_IDENTITY;
+
+ when x"000004" =>
+ -----------------------------------------------------------------
+ -- Device Information CAR. Read-only.
+ -----------------------------------------------------------------
+
+ configDataReadInternal(31 downto 0) <= DEVICE_REV;
+
+ when x"000008" =>
+ -----------------------------------------------------------------
+ -- Assembly Identity CAR. Read-only.
+ -----------------------------------------------------------------
+
+ configDataReadInternal(31 downto 16) <= ASSY_IDENTITY;
+ configDataReadInternal(15 downto 0) <= ASSY_VENDOR_IDENTITY;
+
+ when x"00000c" =>
+ -----------------------------------------------------------------
+ -- Assembly Informaiton CAR. Read-only.
+ -----------------------------------------------------------------
+
+ configDataReadInternal(31 downto 16) <= ASSY_REV;
+ configDataReadInternal(15 downto 0) <= x"0100";
+
+ when x"000010" =>
+ -----------------------------------------------------------------
+ -- Processing Element Features CAR. Read-only.
+ -----------------------------------------------------------------
+
+ -- Bridge.
+ configDataReadInternal(31) <= '0';
+
+ -- Memory.
+ configDataReadInternal(30) <= '0';
+
+ -- Processor.
+ configDataReadInternal(29) <= '0';
+
+ -- Switch.
+ configDataReadInternal(28) <= '1';
+
+ -- Reserved.
+ configDataReadInternal(27 downto 10) <= (others => '0');
+
+ -- Extended route table configuration support.
+ configDataReadInternal(9) <= '0';
+
+ -- Standard route table configuration support.
+ configDataReadInternal(8) <= '1';
+
+ -- Reserved.
+ configDataReadInternal(7 downto 5) <= (others => '0');
+
+ -- Common transport large system support.
+ configDataReadInternal(4) <= '1';
+
+ -- Extended features.
+ configDataReadInternal(3) <= '1';
+
+ -- Extended addressing support.
+ -- Not a processing element.
+ configDataReadInternal(2 downto 0) <= "000";
+
+ when x"000014" =>
+ -----------------------------------------------------------------
+ -- Switch Port Information CAR. Read-only.
+ -----------------------------------------------------------------
+
+ -- Reserved.
+ configDataReadInternal(31 downto 16) <= (others => '0');
+
+ -- PortTotal.
+ configDataReadInternal(15 downto 8) <=
+ std_logic_vector(to_unsigned(SWITCH_PORTS, 8));
+
+ -- PortNumber.
+ configDataReadInternal(7 downto 0) <= inboundFramePort;
+
+ when x"000034" =>
+ -----------------------------------------------------------------
+ -- Switch Route Table Destination ID Limit CAR.
+ -----------------------------------------------------------------
+
+ -- Max_destId.
+ -- Support 2048 addresses.
+ configDataReadInternal(15 downto 0) <= x"0800";
+
+ when x"000068" =>
+ -----------------------------------------------------------------
+ -- Host Base Device ID Lock CSR.
+ -----------------------------------------------------------------
+
+ if (configWrite = '1') then
+ -- Check if this field has been written before.
+ if (hostBaseDeviceIdLocked = '0') then
+ -- The field has not been written.
+ -- Lock the field and set the host base device id.
+ hostBaseDeviceIdLocked <= '1';
+ hostBaseDeviceId <= configDataWrite(15 downto 0);
+ else
+ -- The field has been written.
+ -- Check if the written data is the same as the stored.
+ if (hostBaseDeviceId = configDataWrite(15 downto 0)) then
+ -- Same as stored, reset the value to its initial value.
+ hostBaseDeviceIdLocked <= '0';
+ hostBaseDeviceId <= (others => '1');
+ else
+ -- Not writing the same as the stored value.
+ -- Ignore the write.
+ end if;
+ end if;
+ end if;
+
+ configDataReadInternal(31 downto 16) <= (others => '0');
+ configDataReadInternal(15 downto 0) <= hostBaseDeviceId;
+
+ when x"00006c" =>
+ -----------------------------------------------------------------
+ -- Component TAG CSR.
+ -----------------------------------------------------------------
+
+ if (configWrite = '1') then
+ componentTag <= configDataWrite;
+ end if;
+
+ configDataReadInternal <= componentTag;
+
+ when x"000070" =>
+ -----------------------------------------------------------------
+ -- Standard Route Configuration Destination ID Select CSR.
+ -----------------------------------------------------------------
+
+ if (configWrite = '1') then
+ -- Write the address to access the routing table.
+ routeTableAddress <= configDataWrite(10 downto 0);
+ end if;
+
+ configDataReadInternal(31 downto 11) <= (others => '0');
+ configDataReadInternal(10 downto 0) <= routeTableAddress;
+
+ when x"000074" =>
+ -----------------------------------------------------------------
+ -- Standard Route Configuration Port Select CSR.
+ -----------------------------------------------------------------
+
+ if (configWrite = '1') then
+ -- Write the port information for the address selected by the
+ -- above register.
+ routeTableWrite <= '1';
+ routeTablePortWrite <= configDataWrite(7 downto 0);
+ end if;
+
+ configDataReadInternal(31 downto 8) <= (others => '0');
+ configDataReadInternal(7 downto 0) <= routeTablePortRead;
+
+ when x"000078" =>
+ -----------------------------------------------------------------
+ -- Standard Route Default Port CSR.
+ -----------------------------------------------------------------
+
+ if (configWrite = '1') then
+ -- Write the default route device id.
+ routeTablePortDefault <= configDataWrite(7 downto 0);
+ end if;
+
+ configDataReadInternal(31 downto 8) <= (others => '0');
+ configDataReadInternal(7 downto 0) <= routeTablePortDefault;
+
+ when x"000100" =>
+ -----------------------------------------------------------------
+ -- Extended features. LP-Serial Register Block Header.
+ -----------------------------------------------------------------
+
+ -- One feature only, 0x0003=Generic End Point Free Device.
+ configDataReadInternal(31 downto 16) <= x"0000";
+ configDataReadInternal(15 downto 0) <= x"0003";
+
+ when x"000120" =>
+ -----------------------------------------------------------------
+ -- Port Link Timeout Control CSR.
+ -----------------------------------------------------------------
+
+ if (configWrite = '1') then
+ portLinkTimeout <= configDataWrite(31 downto 8);
+ end if;
+
+ configDataReadInternal(31 downto 8) <= portLinkTimeout;
+ configDataReadInternal(7 downto 0) <= x"00";
+
+ when x"00013c" =>
+ -----------------------------------------------------------------
+ -- Port General Control CSR.
+ -----------------------------------------------------------------
+
+ if (configWrite = '1') then
+ discovered <= configDataWrite(29);
+ end if;
+
+ configDataReadInternal(31 downto 30) <= "00";
+ configDataReadInternal(29) <= discovered;
+ configDataReadInternal(28 downto 0) <= (others => '0');
+
+ when others =>
+ -----------------------------------------------------------------
+ -- Other port specific registers.
+ -----------------------------------------------------------------
+
+ -- Make sure the output is always set to something.
+ configDataReadInternal <= (others=>'0');
+
+ -- Iterate through all active ports.
+ for portIndex in 0 to SWITCH_PORTS-1 loop
+
+ if(unsigned(configAddress) = (x"000148" + (x"000020"*portIndex))) then
+ -----------------------------------------------------------------
+ -- Port N Local ackID CSR.
+ -----------------------------------------------------------------
+ if (configWrite = '1') then
+ localAckIdWrite_o(portIndex) <= '1';
+ clrOutstandingAckId_o(portIndex) <= configDataWrite(31);
+ inboundAckId_o(portIndex) <= configDataWrite(28 downto 24);
+ outstandingAckId_o(portIndex) <= configDataWrite(12 downto 8);
+ outboundAckId_o(portIndex) <= configDataWrite(4 downto 0);
+ end if;
+ configDataReadInternal(31 downto 29) <= (others => '0');
+ configDataReadInternal(28 downto 24) <= inboundAckId_i(portIndex);
+ configDataReadInternal(23 downto 13) <= (others => '0');
+ configDataReadInternal(12 downto 8) <= outstandingAckId_i(portIndex);
+ configDataReadInternal(7 downto 5) <= (others => '0');
+ configDataReadInternal(4 downto 0) <= outboundAckId_i(portIndex);
+
+ elsif(unsigned(configAddress) = (x"000154" + (x"000020"*portIndex))) then
+ -----------------------------------------------------------------
+ -- Port N Control 2 CSR.
+ -----------------------------------------------------------------
+ configDataReadInternal <= (others => '0');
+
+ elsif(unsigned(configAddress) = (x"000158" + (x"000020"*portIndex))) then
+ -----------------------------------------------------------------
+ -- Port N Error and Status CSR.
+ -----------------------------------------------------------------
+ -- Idle Sequence 2 Support.
+ configDataReadInternal(31) <= '0';
+
+ -- Idle Sequence 2 Enable.
+ configDataReadInternal(30) <= '0';
+
+ -- Idle Sequence.
+ configDataReadInternal(29) <= '0';
+
+ -- Reserved.
+ configDataReadInternal(28) <= '0';
+
+ -- Flow Control Mode.
+ configDataReadInternal(27) <= '0';
+
+ -- Reserved.
+ configDataReadInternal(26 downto 21) <= (others => '0');
+
+ -- Output retry-encountered.
+ configDataReadInternal(20) <= '0';
+
+ -- Output retried.
+ configDataReadInternal(19) <= '0';
+
+ -- Output retried-stopped.
+ configDataReadInternal(18) <= '0';
+
+ -- Output error-encountered.
+ configDataReadInternal(17) <= '0';
+
+ -- Output error-stopped.
+ configDataReadInternal(16) <= '0';
+
+ -- Reserved.
+ configDataReadInternal(15 downto 11) <= (others => '0');
+
+ -- Input retry-stopped.
+ configDataReadInternal(10) <= '0';
+
+ -- Input error-encountered.
+ configDataReadInternal(9) <= '0';
+
+ -- Input error-stopped.
+ configDataReadInternal(8) <= '0';
+
+ -- Reserved.
+ configDataReadInternal(7 downto 5) <= (others => '0');
+
+ -- Port-write pending.
+ configDataReadInternal(4) <= '0';
+
+ -- Port unavailable.
+ configDataReadInternal(3) <= '0';
+
+ -- Port error.
+ configDataReadInternal(2) <= '0';
+
+ -- Port OK.
+ configDataReadInternal(1) <= linkInitialized_i(portIndex);
+
+ -- Port uninitialized.
+ configDataReadInternal(0) <= not linkInitialized_i(portIndex);
+
+ elsif(unsigned(configAddress) = (x"00015c" + (x"000020"*portIndex))) then
+ -----------------------------------------------------------------
+ -- Port N Control CSR.
+ -----------------------------------------------------------------
+
+ -- Port Width Support.
+ configDataReadInternal(31 downto 30) <= (others=>'0');
+
+ -- Initialized Port Width.
+ configDataReadInternal(29 downto 27) <= (others=>'0');
+
+ -- Port Width Override.
+ configDataReadInternal(26 downto 24) <= (others=>'0');
+
+ -- Port disable.
+ configDataReadInternal(23) <= '0';
+
+ -- Output Port Enable.
+ if (configWrite = '1') then
+ outputPortEnable(portIndex) <= configDataWrite(22);
+ end if;
+ configDataReadInternal(22) <= outputPortEnable(portIndex);
+
+ -- Input Port Enable.
+ if (configWrite = '1') then
+ inputPortEnable(portIndex) <= configDataWrite(21);
+ end if;
+ configDataReadInternal(21) <= inputPortEnable(portIndex);
+
+ -- Error Checking Disabled.
+ configDataReadInternal(20) <= '0';
+
+ -- Multicast-event Participant.
+ configDataReadInternal(19) <= '0';
+
+ -- Reserved.
+ configDataReadInternal(18) <= '0';
+
+ -- Enumeration Boundry.
+ configDataReadInternal(17) <= '0';
+
+ -- Reserved.
+ configDataReadInternal(16) <= '0';
+
+ -- Extended Port Width Override.
+ configDataReadInternal(15 downto 14) <= (others=>'0');
+
+ -- Extended Port Width Support.
+ configDataReadInternal(13 downto 12) <= (others=>'0');
+
+ -- Implementation defined.
+ configDataReadInternal(11 downto 4) <= (others=>'0');
+
+ -- Reserved.
+ configDataReadInternal(3 downto 1) <= (others=>'0');
+
+ -- Port Type.
+ configDataReadInternal(0) <= '1';
+ end if;
+ end loop;
+
+ end case;
+ end if;
+ else
+ -- Config memory not enabled.
+ end if;
+ end if;
+ end process;
+
+end architecture;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+entity RouteTableInterconnect is
+ generic(
+ WIDTH : natural range 1 to 256 := 8);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ stb_i : in Array1(WIDTH-1 downto 0);
+ addr_i : in Array16(WIDTH-1 downto 0);
+ dataM_o : out Array8(WIDTH-1 downto 0);
+ ack_o : out Array1(WIDTH-1 downto 0);
+
+ stb_o : out std_logic;
+ addr_o : out std_logic_vector(15 downto 0);
+ dataS_i : in std_logic_vector(7 downto 0);
+ ack_i : in std_logic);
+end entity;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+architecture RouteTableInterconnectImpl of RouteTableInterconnect is
+ signal activeCycle : std_logic;
+ signal selectedMaster : natural range 0 to WIDTH-1;
+begin
+
+ -----------------------------------------------------------------------------
+ -- Arbitration.
+ -----------------------------------------------------------------------------
+ Arbiter: process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ activeCycle <= '0';
+ selectedMaster <= 0;
+ elsif (clk'event and clk = '1') then
+ if (activeCycle = '0') then
+ for i in 0 to WIDTH-1 loop
+ if (stb_i(i) = '1') then
+ activeCycle <= '1';
+ selectedMaster <= i;
+ end if;
+ end loop;
+ else
+ if (stb_i(selectedMaster) = '0') then
+ activeCycle <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Interconnection.
+ -----------------------------------------------------------------------------
+ stb_o <= stb_i(selectedMaster);
+ addr_o <= addr_i(selectedMaster);
+
+ Interconnect: for i in 0 to WIDTH-1 generate
+ dataM_o(i) <= dataS_i;
+ ack_o(i) <= ack_i when (selectedMaster = i) else '0';
+ end generate;
+
+end architecture;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+entity SwitchPortInterconnect is
+ generic(
+ WIDTH : natural range 1 to 256 := 8);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ masterCyc_i : in Array1(WIDTH-1 downto 0);
+ masterStb_i : in Array1(WIDTH-1 downto 0);
+ masterWe_i : in Array1(WIDTH-1 downto 0);
+ masterAddr_i : in Array10(WIDTH-1 downto 0);
+ masterData_i : in Array32(WIDTH-1 downto 0);
+ masterData_o : out Array1(WIDTH-1 downto 0);
+ masterAck_o : out Array1(WIDTH-1 downto 0);
+
+ slaveCyc_o : out Array1(WIDTH-1 downto 0);
+ slaveStb_o : out Array1(WIDTH-1 downto 0);
+ slaveWe_o : out Array1(WIDTH-1 downto 0);
+ slaveAddr_o : out Array10(WIDTH-1 downto 0);
+ slaveData_o : out Array32(WIDTH-1 downto 0);
+ slaveData_i : in Array1(WIDTH-1 downto 0);
+ slaveAck_i : in Array1(WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+architecture SwitchPortInterconnectImpl of SwitchPortInterconnect is
+ --component ChipscopeIcon1 is
+ -- port (
+ -- CONTROL0 : inout STD_LOGIC_VECTOR ( 35 downto 0 )
+ -- );
+ --end component;
+ --component ChipscopeIlaWb is
+ -- port (
+ -- CLK : in STD_LOGIC := 'X';
+ -- TRIG0 : in STD_LOGIC_VECTOR ( 46 downto 0);
+ -- CONTROL : inout STD_LOGIC_VECTOR ( 35 downto 0 )
+ -- );
+ --end component;
+ --signal control : std_logic_vector(35 downto 0);
+ --signal trig : std_logic_vector(46 downto 0);
+
+ signal activeCycle : std_logic;
+ signal selectedMaster : natural range 0 to WIDTH-1;
+ signal selectedSlave : natural range 0 to WIDTH-1;
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Arbitration process.
+ -----------------------------------------------------------------------------
+
+ RoundRobinArbiter: process(areset_n, clk)
+ variable index : natural range 0 to WIDTH-1;
+ begin
+ if (areset_n = '0') then
+ activeCycle <= '0';
+ selectedMaster <= 0;
+ elsif (clk'event and clk = '1') then
+ -- Check if a cycle is ongoing.
+ if (activeCycle = '0') then
+ -- No ongoing cycles.
+
+ -- Iterate through all ports and check if any new cycle has started.
+ for i in 0 to WIDTH-1 loop
+ if ((selectedMaster+i) >= WIDTH) then
+ index := (selectedMaster+i) - WIDTH;
+ else
+ index := (selectedMaster+i);
+ end if;
+
+ if (masterCyc_i(index) = '1') then
+ activeCycle <= '1';
+ selectedMaster <= index;
+ end if;
+ end loop;
+ else
+ -- Ongoing cycle.
+
+ -- Check if the cycle has ended.
+ if (masterCyc_i(selectedMaster) = '0') then
+ -- Cycle has ended.
+ activeCycle <= '0';
+
+ -- Check if a new cycle has started from another master.
+ -- Start to check from the one that ended its cycle, this way, the
+ -- ports will be scheduled like round-robin.
+ for i in 0 to WIDTH-1 loop
+ if ((selectedMaster+i) >= WIDTH) then
+ index := (selectedMaster+i) - WIDTH;
+ else
+ index := (selectedMaster+i);
+ end if;
+
+ if (masterCyc_i(index) = '1') then
+ activeCycle <= '1';
+ selectedMaster <= index;
+ end if;
+ end loop;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Address decoding.
+ -----------------------------------------------------------------------------
+
+ -- Select the last port when the top bit is set.
+ -- The last port must be the maintenance slave port.
+ selectedSlave <= WIDTH-1 when masterAddr_i(selectedMaster)(9) = '1' else
+ to_integer(unsigned(masterAddr_i(selectedMaster)(8 downto 1)));
+
+ -----------------------------------------------------------------------------
+ -- Interconnection matrix.
+ -----------------------------------------------------------------------------
+ Interconnect: for i in 0 to WIDTH-1 generate
+ slaveCyc_o(i) <= masterCyc_i(selectedMaster) when (selectedSlave = i) else '0';
+ slaveStb_o(i) <= masterStb_i(selectedMaster) when (selectedSlave = i) else '0';
+ slaveWe_o(i) <= masterWe_i(selectedMaster);
+ slaveAddr_o(i) <= masterAddr_i(selectedMaster);
+ slaveData_o(i) <= masterData_i(selectedMaster);
+ masterData_o(i) <= slaveData_i(selectedSlave);
+ masterAck_o(i) <= slaveAck_i(selectedSlave) when (selectedMaster = i) else '0';
+ end generate;
+
+ -----------------------------------------------------------------------------
+ -- Chipscope debugging probe.
+ -----------------------------------------------------------------------------
+ --trig <= masterCyc_i(selectedMaster) & masterStb_i(selectedMaster) &
+ -- masterWe_i(selectedMaster) & masterAddr_i(selectedMaster) &
+ -- masterData_i(selectedMaster) & slaveData_i(selectedSlave) &
+ -- slaveAck_i(selectedSlave);
+ --ChipscopeIconInst: ChipscopeIcon1
+ -- port map(CONTROL0=>control);
+ --ChipscopeIlaInst: ChipscopeIlaWb
+ -- port map(CLK=>clk, TRIG0=>trig, CONTROL=>control);
+
+end architecture;
+
+
+
rtl/vhdl/RioSwitch.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property