Line 19... |
Line 19... |
-- - Connect linkInitialized to all ports and read it from the source port
|
-- - Connect linkInitialized to all ports and read it from the source port
|
-- using the interconnect. This will allow alternative routes since the
|
-- using the interconnect. This will allow alternative routes since the
|
-- sending port can see if a receiving port is up or not.
|
-- sending port can see if a receiving port is up or not.
|
-- - Add support for extended route.
|
-- - Add support for extended route.
|
-- - Add validity-bit to know if a route has been activly set for a particular
|
-- - Add validity-bit to know if a route has been activly set for a particular
|
-- deviceId.
|
-- deviceId. Currently, we rely on that the routing table memory is
|
|
-- initialized in the enumeration or at device startup.
|
--
|
--
|
-- Author(s):
|
-- Author(s):
|
-- - Magnus Rosenius, magro732@opencores.org
|
-- - Magnus Rosenius, magro732@opencores.org
|
--
|
--
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
Line 50... |
Line 51... |
-- You should have received a copy of the GNU Lesser General
|
-- You should have received a copy of the GNU Lesser General
|
-- Public License along with this source; if not, download it
|
-- Public License along with this source; if not, download it
|
-- from http://www.opencores.org/lgpl.shtml
|
-- from http://www.opencores.org/lgpl.shtml
|
--
|
--
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Revision history.
|
|
-- - Adding support for all sizes of maintenance packets.
|
|
-- - Adding configAck to external config-space interface.
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- RioSwitch
|
-- RioSwitch
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
use work.rio_common.all;
|
use work.rio_common.all;
|
|
|
Line 510... |
Line 506... |
elsif (clk'event and clk = '1') then
|
elsif (clk'event and clk = '1') then
|
readContent_o <= '0';
|
readContent_o <= '0';
|
readFrame_o <= '0';
|
readFrame_o <= '0';
|
readFrameRestart_o <= '0';
|
readFrameRestart_o <= '0';
|
|
|
-- REMARK: Add support for aborted frames...
|
|
case masterState is
|
case masterState is
|
|
|
when STATE_IDLE =>
|
when STATE_IDLE =>
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- Wait for a new packet or content of a new packet.
|
-- Wait for a new packet or content of a new packet.
|
Line 674... |
Line 669... |
-- not have any more data ready, terminate the access but keep the
|
-- not have any more data ready, terminate the access but keep the
|
-- cycle active and proceed to wait for new data.
|
-- cycle active and proceed to wait for new data.
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
|
|
-- Wait for the target port to complete the request.
|
-- Wait for the target port to complete the request.
|
-- REMARK: Remove the ack-condition, we know that the write takes one
|
-- REMARK: Remove the ack-condition to increase performance, we know
|
-- cycle...
|
-- that the write takes one cycle.
|
if (masterAck_i = '1') then
|
if (masterAck_i = '1') then
|
-- The target port is ready.
|
-- The target port is ready.
|
|
|
-- Check if the frame has ended.
|
-- Check if the frame has ended.
|
if (readContentEnd_i = '0') then
|
if (readContentEnd_i = '0') then
|
Line 996... |
Line 991... |
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- Signals between RioLogicalCommon and PacketHandler.
|
-- Signals between RioLogicalCommon and PacketHandler.
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
|
|
signal inboundCyc : std_logic;
|
|
signal inboundStb : std_logic;
|
signal inboundStb : std_logic;
|
signal inboundAdr : std_logic_vector(7 downto 0);
|
signal inboundAdr : std_logic_vector(3 downto 0);
|
signal inboundDat : std_logic_vector(31 downto 0);
|
signal inboundDat : std_logic_vector(31 downto 0);
|
signal inboundAck : std_logic;
|
signal inboundStall : std_logic;
|
signal outboundCyc : std_logic_vector(0 downto 0);
|
|
signal outboundStb : std_logic_vector(0 downto 0);
|
signal outboundStb : std_logic_vector(0 downto 0);
|
|
signal outboundAdr : std_logic_vector(0 downto 0);
|
signal outboundDat : std_logic_vector(31 downto 0);
|
signal outboundDat : std_logic_vector(31 downto 0);
|
signal outboundAck : std_logic_vector(0 downto 0);
|
signal outboundStall : std_logic_vector(0 downto 0);
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- Signals between PacketHandlers and maintenance controllers.
|
-- Signals between PacketHandlers and maintenance controllers.
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
|
|
Line 1093... |
Line 1087... |
signal configAdr : std_logic_vector(23 downto 0);
|
signal configAdr : std_logic_vector(23 downto 0);
|
signal configDataWrite : std_logic_vector(31 downto 0);
|
signal configDataWrite : std_logic_vector(31 downto 0);
|
signal configDataRead, configDataReadInternal : std_logic_vector(31 downto 0);
|
signal configDataRead, configDataReadInternal : std_logic_vector(31 downto 0);
|
signal configAck, configAckInternal : std_logic;
|
signal configAck, configAckInternal : std_logic;
|
|
|
-- REMARK: Make these variables instead...
|
|
signal discovered : std_logic;
|
signal discovered : std_logic;
|
signal hostBaseDeviceIdLocked : std_logic;
|
signal hostBaseDeviceIdLocked : std_logic;
|
signal hostBaseDeviceId : std_logic_vector(15 downto 0);
|
signal hostBaseDeviceId : std_logic_vector(15 downto 0);
|
signal componentTag : std_logic_vector(31 downto 0);
|
signal componentTag : std_logic_vector(31 downto 0);
|
signal portLinkTimeout : std_logic_vector(23 downto 0);
|
signal portLinkTimeout : std_logic_vector(23 downto 0);
|
Line 1107... |
Line 1100... |
begin
|
begin
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- Normal switch port instance interfacing the switch interconnect.
|
-- Normal switch port instance interfacing the switch interconnect.
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- REMARK: PORT_INDEX is not used in this instantiation.
|
-- Note that PORT_INDEX is not used in this instantiation and set to zero.
|
-- REMARK: Add generic to disable the maintenance routing to this port...
|
|
PortInst: SwitchPort
|
PortInst: SwitchPort
|
generic map(
|
generic map(
|
MAINTENANCE_LOOKUP=>true,
|
MAINTENANCE_LOOKUP=>true,
|
PORT_INDEX=>0)
|
PORT_INDEX=>0)
|
port map(
|
port map(
|
Line 1164... |
Line 1156... |
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- Packet queue.
|
-- Packet queue.
|
-- This queue should only contain one packet.
|
-- This queue should only contain one packet.
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- REMARK: Use a packet-buffer with a configurable maximum sized packet...
|
-- REMARK: Use a packet-buffer with a configurable maximum sized packet. The
|
-- the size of the memory is too large...
|
-- size of the resulting memory is larger than needed since maintenance
|
|
-- packets never contain more than 8 double-words.
|
PacketQueue: RioPacketBuffer
|
PacketQueue: RioPacketBuffer
|
generic map(SIZE_ADDRESS_WIDTH=>1, CONTENT_ADDRESS_WIDTH=>7)
|
generic map(SIZE_ADDRESS_WIDTH=>1, CONTENT_ADDRESS_WIDTH=>7)
|
port map(
|
port map(
|
clk=>clk, areset_n=>areset_n,
|
clk=>clk, areset_n=>areset_n,
|
inboundWriteFrameFull_o=>inboundWriteFrameFull,
|
inboundWriteFrameFull_o=>inboundWriteFrameFull,
|
Line 1216... |
Line 1209... |
writeFrameFull_i=>outboundWriteFrameFull,
|
writeFrameFull_i=>outboundWriteFrameFull,
|
writeFrame_o=>outboundWriteFrame,
|
writeFrame_o=>outboundWriteFrame,
|
writeFrameAbort_o=>outboundWriteFrameAbort,
|
writeFrameAbort_o=>outboundWriteFrameAbort,
|
writeContent_o=>outboundWriteContent,
|
writeContent_o=>outboundWriteContent,
|
writeContentData_o=>outboundWriteContentData,
|
writeContentData_o=>outboundWriteContentData,
|
inboundCyc_o=>inboundCyc,
|
|
inboundStb_o=>inboundStb,
|
inboundStb_o=>inboundStb,
|
inboundAdr_o=>inboundAdr,
|
inboundAdr_o=>inboundAdr,
|
inboundDat_o=>inboundDat,
|
inboundDat_o=>inboundDat,
|
inboundAck_i=>inboundAck,
|
inboundStall_i=>inboundStall,
|
outboundCyc_i=>outboundCyc,
|
|
outboundStb_i=>outboundStb,
|
outboundStb_i=>outboundStb,
|
|
outboundAdr_i=>outboundAdr,
|
outboundDat_i=>outboundDat,
|
outboundDat_i=>outboundDat,
|
outboundAck_o=>outboundAck);
|
outboundStall_o=>outboundStall);
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- Inbound maintenance packet parser.
|
-- Inbound maintenance packet parser.
|
-- Unpack inbound maintenance packets.
|
-- Unpack inbound maintenance packets.
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- REMARK: add another receiver that discards all other packet types...
|
|
-- REMARK: Connect enable to something...
|
|
payloadIndexInbound <= payloadIndexOutbound when (forwardPacket = '1') else payloadIndexMaint;
|
payloadIndexInbound <= payloadIndexOutbound when (forwardPacket = '1') else payloadIndexMaint;
|
doneInbound <= doneOutbound when (forwardPacket = '1') else doneMaint;
|
doneInbound <= doneOutbound when (forwardPacket = '1') else doneMaint;
|
InboundPacket: MaintenanceInbound
|
InboundPacket: MaintenanceInbound
|
port map(
|
port map(
|
clk=>clk, areset_n=>areset_n, enable=>'1',
|
clk=>clk, areset_n=>areset_n, enable=>'1',
|
Line 1258... |
Line 1248... |
wdptr_o=>wdptrInbound,
|
wdptr_o=>wdptrInbound,
|
payloadLength_o=>payloadLengthInbound,
|
payloadLength_o=>payloadLengthInbound,
|
payloadIndex_i=>payloadIndexInbound,
|
payloadIndex_i=>payloadIndexInbound,
|
payload_o=>payloadInbound,
|
payload_o=>payloadInbound,
|
done_i=>doneInbound,
|
done_i=>doneInbound,
|
inboundCyc_i=>inboundCyc,
|
|
inboundStb_i=>inboundStb,
|
inboundStb_i=>inboundStb,
|
inboundAdr_i=>inboundAdr,
|
inboundAdr_i=>inboundAdr,
|
inboundDat_i=>inboundDat,
|
inboundDat_i=>inboundDat,
|
inboundAck_o=>inboundAck);
|
inboundStall_o=>inboundStall);
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- Outbound maintenance packet generator.
|
-- Outbound maintenance packet generator.
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
readRequestOutbound <= (readRequestInbound and sendPacket) when (forwardPacket = '1') else '0';
|
readRequestOutbound <= (readRequestInbound and sendPacket) when (forwardPacket = '1') else '0';
|
Line 1278... |
Line 1267... |
dstIdOutbound <= dstIdInbound when (forwardPacket = '1') else srcIdInbound;
|
dstIdOutbound <= dstIdInbound when (forwardPacket = '1') else srcIdInbound;
|
statusOutbound <= statusInbound when (forwardPacket = '1') else statusMaint;
|
statusOutbound <= statusInbound when (forwardPacket = '1') else statusMaint;
|
hopOutbound <= std_logic_vector(unsigned(hopInbound)-1) when (forwardPacket = '1') else x"ff";
|
hopOutbound <= std_logic_vector(unsigned(hopInbound)-1) when (forwardPacket = '1') else x"ff";
|
payloadLengthOutbound <= payloadLengthInbound when (forwardPacket = '1') else payloadLengthMaint;
|
payloadLengthOutbound <= payloadLengthInbound when (forwardPacket = '1') else payloadLengthMaint;
|
payloadOutbound <= payloadInbound when (forwardPacket = '1') else payloadMaint;
|
payloadOutbound <= payloadInbound when (forwardPacket = '1') else payloadMaint;
|
-- REMARK: Connect enable to something...
|
|
OutboundPacket: MaintenanceOutbound
|
OutboundPacket: MaintenanceOutbound
|
port map(
|
port map(
|
clk=>clk, areset_n=>areset_n, enable=>'1',
|
clk=>clk, areset_n=>areset_n, enable=>'1',
|
readRequestReady_i=>readRequestOutbound,
|
readRequestReady_i=>readRequestOutbound,
|
writeRequestReady_i=>writeRequestOutbound,
|
writeRequestReady_i=>writeRequestOutbound,
|
Line 1303... |
Line 1291... |
wdptr_i=>wdptrInbound,
|
wdptr_i=>wdptrInbound,
|
payloadLength_i=>payloadLengthOutbound,
|
payloadLength_i=>payloadLengthOutbound,
|
payloadIndex_o=>payloadIndexOutbound,
|
payloadIndex_o=>payloadIndexOutbound,
|
payload_i=>payloadOutbound,
|
payload_i=>payloadOutbound,
|
done_o=>doneOutbound,
|
done_o=>doneOutbound,
|
outboundCyc_o=>outboundCyc(0),
|
|
outboundStb_o=>outboundStb(0),
|
outboundStb_o=>outboundStb(0),
|
|
outboundAdr_o=>outboundAdr(0),
|
outboundDat_o=>outboundDat,
|
outboundDat_o=>outboundDat,
|
outboundAck_i=>outboundAck(0));
|
outboundStall_i=>outboundStall(0));
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- Main switch maintenance controller.
|
-- Main switch maintenance controller.
|
-- This controller decides when to forward packets and when to consume and
|
-- This controller decides when to forward packets and when to consume and
|
-- produce responses instead.
|
-- produce responses instead.
|
-- It also determines when portWrite-packets are allowed to be sent.
|
-- It also determines when portWrite-packets are allowed to be sent.
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
RioSwitchMaintenance: process(clk, areset_n)
|
RioSwitchMaintenance: process(clk, areset_n)
|
type MasterStateType is (STATE_IDLE,
|
type MasterStateType is (STATE_IDLE,
|
STATE_START_PORT_LOOKUP,
|
STATE_START_PORT_LOOKUP,
|
STATE_READ_PORT_LOOKUP,
|
STATE_WAIT_PORT_LOOKUP,
|
STATE_WAIT_COMPLETE);
|
STATE_WAIT_COMPLETE);
|
variable masterState : MasterStateType;
|
variable masterState : MasterStateType;
|
begin
|
begin
|
if (areset_n = '0') then
|
if (areset_n = '0') then
|
masterState := STATE_IDLE;
|
masterState := STATE_IDLE;
|
Line 1335... |
Line 1323... |
elsif (clk'event and clk = '1') then
|
elsif (clk'event and clk = '1') then
|
case masterState is
|
case masterState is
|
|
|
when STATE_IDLE =>
|
when STATE_IDLE =>
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
--
|
|
---------------------------------------------------------------------
|
|
-- Wait for frame to be available.
|
-- Wait for frame to be available.
|
|
---------------------------------------------------------------------
|
-- REMARK: Discard erronous frames.
|
-- REMARK: Discard erronous frames.
|
sendPacket <= '0';
|
sendPacket <= '0';
|
if (((readRequestInbound = '1') or (writeRequestInbound = '1')) and (hopInbound = x"00")) then
|
if (((readRequestInbound = '1') or (writeRequestInbound = '1')) and (hopInbound = x"00")) then
|
masterState := STATE_WAIT_COMPLETE;
|
masterState := STATE_WAIT_COMPLETE;
|
forwardPacket <= '0';
|
forwardPacket <= '0';
|
outboundFramePort <= inboundFramePort;
|
outboundFramePort <= inboundFramePort;
|
elsif (((readResponseInbound = '1') or ((readRequestInbound = '1') and (hopInbound /= x"00"))) or
|
elsif ((readResponseInbound = '1') or
|
((writeResponseInbound = '1') or ((writeRequestInbound = '1') and (hopInbound /= x"00"))) or
|
((readRequestInbound = '1') and (hopInbound /= x"00")) or
|
|
(writeResponseInbound = '1') or
|
|
((writeRequestInbound = '1') and (hopInbound /= x"00")) or
|
(portWriteInbound = '1')) then
|
(portWriteInbound = '1')) then
|
masterState := STATE_START_PORT_LOOKUP;
|
masterState := STATE_START_PORT_LOOKUP;
|
forwardPacket <= '1';
|
forwardPacket <= '1';
|
end if;
|
end if;
|
|
|
when STATE_START_PORT_LOOKUP =>
|
when STATE_START_PORT_LOOKUP =>
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
--
|
-- The destination port of the packet should be read from the routing
|
|
-- table.
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
|
|
-- Initiate a port-lookup of the destination address.
|
-- Initiate a port-lookup of the destination address.
|
lookupStb_o <= '1';
|
lookupStb_o <= '1';
|
lookupAddr_o <= dstIdInbound(15 downto 0);
|
lookupAddr_o <= dstIdInbound(15 downto 0);
|
masterState := STATE_READ_PORT_LOOKUP;
|
masterState := STATE_WAIT_PORT_LOOKUP;
|
|
|
when STATE_READ_PORT_LOOKUP =>
|
when STATE_WAIT_PORT_LOOKUP =>
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
--
|
-- Wait for the destination port lookup to complete.
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
|
|
-- Wait for the routing table to complete the request.
|
|
if (lookupAck_i = '1') then
|
if (lookupAck_i = '1') then
|
-- The address lookup is complete.
|
-- The address lookup is complete.
|
|
|
-- Terminate the lookup cycle.
|
-- Terminate the lookup cycle.
|
lookupStb_o <= '0';
|
lookupStb_o <= '0';
|
Line 1383... |
Line 1372... |
-- REMARK: Timeout here???
|
-- REMARK: Timeout here???
|
end if;
|
end if;
|
|
|
when STATE_WAIT_COMPLETE =>
|
when STATE_WAIT_COMPLETE =>
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
--
|
-- Indicate that the packet can be sent and wait for it to be
|
|
-- transmitted.
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- REMARK: Wait for the packet to be fully transmitted to the target
|
|
-- port. Then reset everything for the reception of a new packet.
|
|
sendPacket <= '1';
|
sendPacket <= '1';
|
if (doneInbound = '1') then
|
if (doneInbound = '1') then
|
masterState := STATE_IDLE;
|
masterState := STATE_IDLE;
|
end if;
|
end if;
|
|
|
Line 1404... |
Line 1392... |
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- Bridge between the inbound RapidIO maintenance packets to the internal
|
-- Bridge between the inbound RapidIO maintenance packets to the internal
|
-- config-space bus.
|
-- config-space bus.
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- REMARK: Connect enable...
|
|
readRequestMaint <= (readRequestInbound and sendPacket) when (forwardPacket = '0') else '0';
|
readRequestMaint <= (readRequestInbound and sendPacket) when (forwardPacket = '0') else '0';
|
writeRequestMaint <= (writeRequestInbound and sendPacket) when (forwardPacket = '0') else '0';
|
writeRequestMaint <= (writeRequestInbound and sendPacket) when (forwardPacket = '0') else '0';
|
MaintenanceBridge: RioLogicalMaintenance
|
MaintenanceBridge: RioLogicalMaintenance
|
port map(
|
port map(
|
clk=>clk, areset_n=>areset_n, enable=>'1',
|
clk=>clk, areset_n=>areset_n, enable=>'1',
|