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

Subversion Repositories rio

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /rio
    from Rev 45 to Rev 46
    Reverse comparison

Rev 45 → Rev 46

/branches/2.0.0-development/rtl/vhdl/RioWbBridge.vhd
10,26 → 10,32
-- NWRITE, NWRITER and NREAD are currently supported.
--
-- To Do:
-- REMARK: Set the stb_o to '0' in between read accesses to conform better to a
-- block transfer in the Wishbone standard.
-- REMARK: Clean up cyc-signals, only stb-signals are needed (between
-- RioLogicalCommon and the packet handlers).
-- REMARK: Add support for the lock_o to be sure to transfer all the packet
-- content atomically?
-- REMARK: Add support for EXTENDED_ADDRESS.
-- REMARK: Use the baseDeviceId when sending packets? Currently, all responses
-- are sent with destination<->source exchanged so the baseDeviceId is not
-- needed.
-- REMARK: Support inbound data with full bandwidth, not just half, applies to
-- RioLogicalCommon and the packet handlers.
-- REMARK: Move the packet handlers to seperate files.
-- REMARK: Increase the priority of the response-packet when sent?
-- REMARK: Implement error indications if erronous packets are received.
-- REMARK: Implement error indications if err_i is received on the Wishbone bus.
-- REMARK: Add support for extended features to dynamically configure the status
-- from the port this block is connected to. Needed for the discovered- and
-- masterEnable-bits.
-- REMARK: Add support for outbound doorbells connected to interrupt input pins.
-- - Move packet handlers to RioLogicalPackets.
-- - Move component declarations to riocommon.
-- - Update the Maintenance handler to the new interface. It currently does not
-- compile.
-- - Set the stb_o to '0' in between read accesses to conform better to a
-- block transfer in the Wishbone standard.
-- - Clean up cyc-signals, only stb-signals are needed (between
-- RioLogicalCommon and the packet handlers).
-- - Add support for the lock_o to be sure to transfer all the packet
-- content atomically?
-- - Add support for EXTENDED_ADDRESS.
-- - Add support for addressing to implementation defined config space by
-- adding interface to top entity.
-- - Use the baseDeviceId when sending packets? Currently, all responses
-- are sent with destination<->source exchanged so the baseDeviceId is not
-- needed.
-- - Support inbound data with full bandwidth, not just half, applies to
-- RioLogicalCommon and the packet handlers.
-- - Move the packet handlers to seperate files.
-- - Increase the priority of the response-packet when sent?
-- - Implement error indications if erronous packets are received.
-- - Implement error indications if err_i is received on the Wishbone bus.
-- - Add support for extended features to dynamically configure the status
-- from the port this block is connected to. Needed for the discovered- and
-- masterEnable-bits.
-- - Add support for outbound doorbells connected to interrupt input pins.
--
-- Author(s):
-- - Magnus Rosenius, magro732@opencores.org
205,63 → 211,6
outboundAck_i : in std_logic);
end component;
 
component RioLogicalMaintenance is
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
configStb_o : out std_logic;
configWe_o : out std_logic;
configAdr_o : out std_logic_vector(21 downto 0);
configDat_o : out std_logic_vector(31 downto 0);
configDat_i : in std_logic_vector(31 downto 0);
configAck_i : in std_logic;
inboundCyc_i : in std_logic;
inboundStb_i : in std_logic;
inboundAdr_i : in std_logic_vector(7 downto 0);
inboundDat_i : in std_logic_vector(31 downto 0);
inboundAck_o : out std_logic;
 
outboundCyc_o : out std_logic;
outboundStb_o : out std_logic;
outboundDat_o : out std_logic_vector(31 downto 0);
outboundAck_i : in std_logic);
end component;
 
component RioLogicalCommon is
generic(
PORTS : natural);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
readFrameEmpty_i : in std_logic;
readFrame_o : out std_logic;
readContent_o : out std_logic;
readContentEnd_i : in std_logic;
readContentData_i : in std_logic_vector(31 downto 0);
 
writeFrameFull_i : in std_logic;
writeFrame_o : out std_logic;
writeFrameAbort_o : out std_logic;
writeContent_o : out std_logic;
writeContentData_o : out std_logic_vector(31 downto 0);
 
inboundCyc_o : out std_logic;
inboundStb_o : out std_logic;
inboundAdr_o : out std_logic_vector(7 downto 0);
inboundDat_o : out std_logic_vector(31 downto 0);
inboundAck_i : in std_logic;
outboundCyc_i : in std_logic_vector(PORTS-1 downto 0);
outboundStb_i : in std_logic_vector(PORTS-1 downto 0);
outboundDat_i : in std_logic_vector(32*PORTS-1 downto 0);
outboundAck_o : out std_logic_vector(PORTS-1 downto 0));
end component;
 
constant PORTS : natural := 2;
 
type StateType is (IDLE,
318,6 → 267,31
signal responsePayload : std_logic_vector(63 downto 0);
signal responseDone : std_logic;
 
signal readRequestInbound : std_logic;
signal writeRequestInbound : std_logic;
signal vcInbound : std_logic;
signal crfInbound : std_logic;
signal prioInbound : std_logic_vector(1 downto 0);
signal ttInbound : std_logic_vector(1 downto 0);
signal dstIdInbound : std_logic_vector(31 downto 0);
signal srcIdInbound : std_logic_vector(31 downto 0);
signal tidInbound : std_logic_vector(7 downto 0);
signal offsetInbound : std_logic_vector(20 downto 0);
signal wdptrInbound : std_logic;
signal payloadLengthInbound : std_logic_vector(3 downto 0);
signal payloadInbound : std_logic_vector(31 downto 0);
 
signal readResponseMaint : std_logic;
signal writeResponseMaint : std_logic;
signal wdptrMaint : std_logic;
signal payloadLengthMaint : std_logic_vector(3 downto 0);
signal payloadIndexMaint : std_logic_vector(3 downto 0);
signal payloadMaint : std_logic_vector(31 downto 0);
signal doneMaint : std_logic;
signal payloadIndexOutbound : std_logic_vector(3 downto 0);
signal doneOutbound : std_logic;
 
signal configStb : std_logic;
signal configWe : std_logic;
signal configAdr : std_logic_vector(21 downto 0);
581,28 → 555,90
outboundDat_o=>outboundDat(31 downto 0),
outboundAck_i=>outboundAck(0));
 
-----------------------------------------------------------------------------
-- Maintenance packet processing.
MaintenanceInst: RioLogicalMaintenance
-----------------------------------------------------------------------------
InboundMaintenance: MaintenanceInbound
port map(
clk=>clk,
areset_n=>areset_n,
enable=>enable,
configStb_o=>configStb,
configWe_o=>configWe,
configAdr_o=>configAdr,
configDat_o=>configDatWrite,
configDat_i=>configDatRead,
configAck_i=>configAck,
inboundCyc_i=>inboundCyc,
inboundStb_i=>inboundStb,
inboundAdr_i=>inboundAdr,
inboundDat_i=>inboundDat,
inboundAck_o=>maintenanceAck,
outboundCyc_o=>outboundCyc(1),
outboundStb_o=>outboundStb(1),
outboundDat_o=>outboundDat(63 downto 32),
clk=>clk, areset_n=>areset_n, enable=>enable,
readRequestReady_o=>readRequestInbound,
writeRequestReady_o=>writeRequestInbound,
readResponseReady_o=>open,
writeResponseReady_o=>open,
portWriteReady_o=>open,
vc_o=>vcInbound,
crf_o=>crfInbound,
prio_o=>prioInbound,
tt_o=>ttInbound,
dstid_o=>dstIdInbound,
srcid_o=>srcIdInbound,
tid_o=>tidInbound,
hop_o=>open,
offset_o=>offsetInbound,
wdptr_o=>wdptrInbound,
payloadLength_o=>payloadLengthInbound,
payloadIndex_i=>payloadIndexMaint,
payload_o=>payloadInbound,
done_i=>doneMaint,
inboundCyc_i=>inboundCyc,
inboundStb_i=>inboundStb,
inboundAdr_i=>inboundAdr,
inboundDat_i=>inboundDat,
inboundAck_o=>maintenanceAck);
 
OutboundMaintenance: MaintenanceOutbound
port map(
clk=>clk, areset_n=>areset_n, enable=>enable,
readRequestReady_i=>'0',
writeRequestReady_i=>'0',
readResponseReady_i=>readResponseMaint,
writeResponseReady_i=>writeResponseMaint,
portWriteReady_i=>'0',
vc_i=>vcInbound,
crf_i=>crfInbound,
prio_i=>prioInbound,
tt_i=>ttInbound,
dstid_i=>srcIdInbound,
srcid_i=>dstIdInbound,
status_i=>"0000",
tid_i=>tidInbound,
hop_i=>x"ff",
offset_i=>(others=>'0'),
wdptr_i=>wdptrMaint,
payloadLength_i=>payloadLengthMaint,
payloadIndex_o=>payloadIndexOutbound,
payload_i=>payloadMaint,
done_o=>doneOutbound,
outboundCyc_o=>outboundCyc(1),
outboundStb_o=>outboundStb(1),
outboundDat_o=>outboundDat(63 downto 32),
outboundAck_i=>outboundAck(1));
 
MaintenanceBridge: RioLogicalMaintenance
port map(
clk=>clk, areset_n=>areset_n, enable=>enable,
readRequestReady_i=>readRequestInbound,
writeRequestReady_i=>writeRequestInbound,
offset_i=>offsetInbound,
wdptr_i=>wdptrInbound,
payloadLength_i=>payloadLengthInbound,
payloadIndex_o=>payloadIndexMaint,
payload_i=>payloadInbound,
done_o=>doneMaint,
readResponseReady_o=>readResponseMaint,
writeResponseReady_o=>writeResponseMaint,
wdptr_o=>wdptrMaint,
payloadLength_o=>payloadLengthMaint,
payloadIndex_i=>payloadIndexOutbound,
payload_o=>payloadMaint,
done_i=>doneOutbound,
configStb_o=>configStb,
configWe_o=>configWe,
configAdr_o=>configAdr,
configDat_o=>configDatWrite,
configDat_i=>configDatRead,
configAck_i=>configAck);
 
-----------------------------------------------------------------------------
-- Common interface toward the packet queues.
-----------------------------------------------------------------------------
/branches/2.0.0-development/rtl/vhdl/RioLogicalPackets.vhd
0,0 → 1,617
-------------------------------------------------------------------------------
--
-- RapidIO IP Library Core
--
-- This file is part of the RapidIO IP library project
-- http://www.opencores.org/cores/rio/
--
-- Description
-- Containing RapidIO packet parsers and generators.
--
-- To Do:
-- - Add support for maint-request and response in both directions.
-- - Add support for portWrite in both directions.
-- - Add generic to disable support for specified packets.
-- - Dont set complete before the packet is ready in inbound packet
-- handler.
-- - Add error indication if erronous sizes are received.
--
-- Author(s):
-- - Magnus Rosenius, magro732@opencores.org
--
-------------------------------------------------------------------------------
--
-- Copyright (C) 2014 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
--
-------------------------------------------------------------------------------
 
 
-------------------------------------------------------------------------------
-- MaintenanceInbound
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
 
-------------------------------------------------------------------------------
-- Entity for MaintenanceInbound.
-------------------------------------------------------------------------------
entity MaintenanceInbound is
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
readRequestReady_o : out std_logic;
writeRequestReady_o : out std_logic;
readResponseReady_o : out std_logic;
writeResponseReady_o : out std_logic;
portWriteReady_o : out std_logic;
vc_o : out std_logic;
crf_o : out std_logic;
prio_o : out std_logic_vector(1 downto 0);
tt_o : out std_logic_vector(1 downto 0);
dstid_o : out std_logic_vector(31 downto 0);
srcid_o : out std_logic_vector(31 downto 0);
tid_o : out std_logic_vector(7 downto 0);
hop_o : out std_logic_vector(7 downto 0);
offset_o : out std_logic_vector(20 downto 0);
wdptr_o : out std_logic;
payloadLength_o : out std_logic_vector(3 downto 0);
payloadIndex_i : in std_logic_vector(3 downto 0);
payload_o : out std_logic_vector(31 downto 0);
done_i : in std_logic;
inboundCyc_i : in std_logic;
inboundStb_i : in std_logic;
inboundAdr_i : in std_logic_vector(7 downto 0);
inboundDat_i : in std_logic_vector(31 downto 0);
inboundAck_o : out std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
-- Architecture for MaintenanceInbound.
-------------------------------------------------------------------------------
architecture MaintenanceInbound of MaintenanceInbound is
 
type StateType is (RECEIVE_PACKET, READY);
signal state : StateType;
 
signal wdptr : std_logic;
signal size : std_logic_vector(3 downto 0);
signal words : natural range 0 to 32;
 
signal inboundAck : std_logic;
signal maintReadComplete : std_logic;
signal maintWriteComplete : std_logic;
 
signal packetIndex : natural range 0 to 33;
signal packetData : std_logic_vector(31 downto 0);
 
signal memoryWrite : std_logic;
signal memoryAddress : std_logic_vector(3 downto 0);
signal memoryDataIn : std_logic_vector(31 downto 0);
 
begin
 
readRequestReady_o <= maintReadComplete when (state = READY) else '0';
writeRequestReady_o <= maintWriteComplete when (state = READY) else '0';
readResponseReady_o <= '0';
writeResponseReady_o <= '0';
portWriteReady_o <= '0';
 
inboundAck_o <= inboundAck;
MaintenanceRequest: process(clk, areset_n)
begin
if (areset_n = '0') then
inboundAck <= '0';
 
maintReadComplete <= '0';
maintWriteComplete <= '0';
vc_o <= '0';
crf_o <= '0';
prio_o <= "00";
tt_o <= "00";
dstid_o <= (others=>'0');
srcid_o <= (others=>'0');
tid_o <= (others=>'0');
hop_o <= (others=>'0');
offset_o <= (others=>'0');
 
wdptr <= '0';
size <= (others=>'0');
packetIndex <= 0;
memoryWrite <= '0';
memoryAddress <= (others=>'0');
memoryDataIn <= (others=>'0');
elsif (clk'event and clk = '1') then
case state is
when RECEIVE_PACKET =>
---------------------------------------------------------------------
-- This state waits for a new maintenance packet, receives it
-- and parses it.
---------------------------------------------------------------------
if (inboundCyc_i = '1') then
if (inboundAck = '0') then
if (inboundStb_i = '1') then
if (inboundAdr_i = x"80") then
-------------------------------------------------------------
-- Maintenance Read Request packet parser.
-------------------------------------------------------------
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
vc_o <= inboundDat_i(9);
crf_o <= inboundDat_i(8);
prio_o <= inboundDat_i(7 downto 6);
tt_o <= inboundDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- dstid
dstid_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcid
srcid_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & rdsize & srcTID & hop & config_offset(20:13)
size <= inboundDat_i(27 downto 24);
tid_o <= inboundDat_i(23 downto 16);
hop_o <= inboundDat_i(15 downto 8);
offset_o(20 downto 13) <= inboundDat_i(7 downto 0);
packetIndex <= packetIndex + 1;
when 4 =>
-- config_offset(12:0) & wdptr & rsrv & crc(15:0)
offset_o(12 downto 0) <= inboundDat_i(31 downto 19);
wdptr <= inboundDat_i(18);
packetIndex <= packetIndex + 1;
maintReadComplete <= '1';
when others =>
-- There should be no more content in a maintenance read request.
-- Discard.
end case;
inboundAck <= '1';
elsif (inboundAdr_i = x"81") then
-------------------------------------------------------------
-- Maintenance Write Request packet parser.
-------------------------------------------------------------
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
vc_o <= inboundDat_i(9);
crf_o <= inboundDat_i(8);
prio_o <= inboundDat_i(7 downto 6);
tt_o <= inboundDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- destId
dstid_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcId
srcid_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & wrsize & srcTID & hop & config_offset(20:13)
size <= inboundDat_i(27 downto 24);
tid_o <= inboundDat_i(23 downto 16);
hop_o <= inboundDat_i(15 downto 8);
offset_o(20 downto 13) <= inboundDat_i(7 downto 0);
packetIndex <= packetIndex + 1;
when 4 =>
-- config_offset(12:0) & wdptr & rsrv & double-word(63:48)
offset_o(12 downto 0) <= inboundDat_i(31 downto 19);
wdptr <= inboundDat_i(18);
packetData(31 downto 16) <= inboundDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 =>
-- double-word(47:16)
packetData(31 downto 16) <= inboundDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
 
if (not ((size = "1000") and (wdptr = '1'))) then
memoryWrite <= '1';
memoryDataIn <= packetData(31 downto 16) & inboundDat_i(31 downto 16);
end if;
when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 =>
-- double-word(15:0) & double-word(63:48)
packetData(31 downto 16) <= inboundDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
 
memoryWrite <= '1';
memoryDataIn <= packetData(31 downto 16) & inboundDat_i(31 downto 16);
-- REMARK: Dont set complete before the packet is ready...
maintWriteComplete <= '1';
when others =>
-- There should be no more content in a maintenance write request.
-- Discard.
end case;
inboundAck <= '1';
elsif (inboundAdr_i = x"82") then
-------------------------------------------------------------
-- Maintenance Read Response packet parser.
-------------------------------------------------------------
elsif (inboundAdr_i = x"83") then
-------------------------------------------------------------
-- Maintenance Write Response packet parser.
-------------------------------------------------------------
elsif (inboundAdr_i = x"84") then
-------------------------------------------------------------
-- Maintenance Port-Write Request packet parser.
-------------------------------------------------------------
else
-------------------------------------------------------------
-- Unsupported maintenance packet.
-------------------------------------------------------------
-- REMARK: Cannot handle these, dont answer. Or answer and
-- discard?
end if;
end if;
else
if (memoryWrite = '1') then
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
end if;
memoryWrite <= '0';
inboundAck <= '0';
end if;
else
if (maintReadComplete = '1') or (maintWriteComplete = '1') then
state <= READY;
end if;
packetIndex <= 0;
memoryAddress <= (others=>'0');
end if;
 
when READY =>
---------------------------------------------------------------------
-- Wait for the handler of the packet to signal that it has been
-- processed.
---------------------------------------------------------------------
if (done_i = '1') then
maintReadComplete <= '0';
maintWriteComplete <= '0';
state <= RECEIVE_PACKET;
end if;
when others =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
 
end case;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Transformation of rdsize/wrsize into length of access and byte lanes.
-----------------------------------------------------------------------------
process(clk, areset_n)
begin
if (areset_n = '0') then
payloadLength_o <= (others=>'0');
wdptr_o <= '0';
elsif (clk'event and clk = '1') then
if (maintReadComplete = '1') or (maintWriteComplete = '1') then
if (wdptr = '0') then
case size is
when "1000" =>
-- Read 1 word.
payloadLength_o <= "0000";
wdptr_o <= '0';
when "1011" =>
-- Read 2 words.
payloadLength_o <= "0001";
wdptr_o <= '0';
when "1100" =>
-- Read 8 words.
payloadLength_o <= "0111";
wdptr_o <= '0';
when others =>
-- REMARK: Not allowed for a maintenance packet.
payloadLength_o <= "0000";
wdptr_o <= '0';
end case;
else
case size is
when "1000" =>
-- Read 1 word.
payloadLength_o <= "0000";
wdptr_o <= '1';
when "1011" =>
-- Read 4 words.
payloadLength_o <= "0011";
wdptr_o <= '0';
when "1100" =>
-- Read 16 words.
payloadLength_o <= "1111";
wdptr_o <= '0';
when others =>
-- REMARK: Not allowed for a maintenance packet.
payloadLength_o <= "0000";
wdptr_o <= '0';
end case;
end if;
end if;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Payload content memory.
-----------------------------------------------------------------------------
PayloadMemory: MemorySimpleDualPort
generic map(ADDRESS_WIDTH=>4, DATA_WIDTH=>32)
port map(clkA_i=>clk,
enableA_i=>memoryWrite,
addressA_i=>memoryAddress,
dataA_i=>memoryDataIn,
clkB_i=>clk,
enableB_i=>enable,
addressB_i=>payloadIndex_i,
dataB_o=>payload_o);
 
end architecture;
 
 
-------------------------------------------------------------------------------
-- MaintenanceOutbound.
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
-------------------------------------------------------------------------------
-- Entity for MaintenanceOutbound.
-------------------------------------------------------------------------------
entity MaintenanceOutbound is
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
readRequestReady_i : in std_logic;
writeRequestReady_i : in std_logic;
readResponseReady_i : in std_logic;
writeResponseReady_i : in std_logic;
portWriteReady_i : in std_logic;
vc_i : in std_logic;
crf_i : in std_logic;
prio_i : in std_logic_vector(1 downto 0);
tt_i : in std_logic_vector(1 downto 0);
dstid_i : in std_logic_vector(31 downto 0);
srcid_i : in std_logic_vector(31 downto 0);
status_i : in std_logic_vector(3 downto 0);
tid_i : in std_logic_vector(7 downto 0);
hop_i : in std_logic_vector(7 downto 0);
wdptr_i : in std_logic;
offset_i : in std_logic_vector(20 downto 0);
payloadLength_i : in std_logic_vector(3 downto 0);
payloadIndex_o : out std_logic_vector(3 downto 0);
payload_i : in std_logic_vector(31 downto 0);
done_o : out std_logic;
outboundCyc_o : out std_logic;
outboundStb_o : out std_logic;
outboundDat_o : out std_logic_vector(31 downto 0);
outboundAck_i : in std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
-- Architecture for MaintenanceOutbound.
-------------------------------------------------------------------------------
architecture MaintenanceOutbound of MaintenanceOutbound is
type StateType is (WAIT_PACKET,
READ_RESPONSE, WRITE_RESPONSE,
WAIT_COMPLETE, RESPONSE_DONE);
signal state : StateType;
 
signal packetIndex : natural range 0 to 33;
signal header : std_logic_vector(31 downto 0);
signal payload : std_logic_vector(15 downto 0);
signal payloadIndex : std_logic_vector(3 downto 0);
begin
 
-- unused(31:16) | ackId(15:10) | vc(9) | crf(8) | prio(7:6) | tt(5:4) | ftype(3:0).
header <= x"0000" & "000000" & vc_i & crf_i & prio_i & tt_i & x"8";
 
payloadIndex_o <= payloadIndex;
MaintenanceResponse: process(clk, areset_n)
begin
if (areset_n = '0') then
state <= WAIT_PACKET;
packetIndex <= 0;
 
payload <= (others=>'0');
payloadIndex <= (others=>'0');
outboundCyc_o <= '0';
outboundStb_o <= '0';
 
done_o <= '0';
elsif (clk'event and clk = '1') then
if (enable = '1') then
case state is
when WAIT_PACKET =>
-------------------------------------------------------------------
--
-------------------------------------------------------------------
if (readResponseReady_i = '1') then
outboundCyc_o <= '1';
outboundStb_o <= '1';
outboundDat_o <= header;
packetIndex <= 1;
payloadIndex <= (others=>'0');
state <= READ_RESPONSE;
elsif (writeResponseReady_i = '1') then
outboundCyc_o <= '1';
outboundStb_o <= '1';
outboundDat_o <= header;
packetIndex <= 1;
state <= WRITE_RESPONSE;
end if;
 
when READ_RESPONSE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (outboundAck_i = '1') then
case (packetIndex) is
when 1 =>
-- destination
outboundDat_o <= dstid_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- source
outboundDat_o <= srcid_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & status & targetTID & hop & reserved(7:0)
outboundDat_o <= "0010" & status_i & tid_i & hop_i & x"00";
packetIndex <= packetIndex + 1;
when 4 =>
-- reserved(15:0) & double-wordN(63:48)
if (payloadLength_i = "0000") and (wdptr_i = '0') then
outboundDat_o <= x"0000" & payload_i(31 downto 16);
payload <= payload_i(15 downto 0);
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
elsif (payloadLength_i = "0000") and (wdptr_i = '1') then
outboundDat_o <= x"0000" & x"0000";
else
outboundDat_o <= x"0000" & payload_i(31 downto 16);
payload <= payload_i(15 downto 0);
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
end if;
packetIndex <= packetIndex + 1;
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 =>
-- double-wordN(47:16)
if (payloadLength_i = "0000") and (wdptr_i = '0') then
outboundDat_o <= payload & x"0000";
elsif (payloadLength_i = "0000") and (wdptr_i = '1') then
outboundDat_o <= x"0000" & payload_i(31 downto 16);
payload <= payload_i(15 downto 0);
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
else
outboundDat_o <= payload & payload_i(31 downto 16);
payload <= payload_i(15 downto 0);
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
end if;
packetIndex <= packetIndex + 1;
when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 =>
-- double-wordN(15:0) & double-wordN(63:48)
if (payloadLength_i = "0000") and (wdptr_i = '0') then
outboundDat_o <= x"0000" & x"0000";
elsif (payloadLength_i = "0000") and (wdptr_i = '1') then
outboundDat_o <= payload & x"0000";
else
if (payloadIndex /= payloadLength_i) then
outboundDat_o <= payload & payload_i(31 downto 16);
payload <= payload_i(15 downto 0);
else
outboundDat_o <= payload & x"0000";
payload <= payload_i(15 downto 0);
end if;
end if;
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
if (payloadIndex(3 downto 1) = payloadLength_i(3 downto 1)) then
state <= WAIT_COMPLETE;
else
packetIndex <= packetIndex + 1;
end if;
when others =>
-- Unallowed response length.
-- Dont do anything.
end case;
end if;
when WRITE_RESPONSE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (outboundAck_i = '1') then
case (packetIndex) is
when 1 =>
-- destination
outboundDat_o <= dstid_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- source
outboundDat_o <= srcid_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & status & targetTID & hop & reserved(7:0)
outboundDat_o <= "0011" & status_i & tid_i & hop_i & x"00";
packetIndex <= packetIndex + 1;
when others =>
-- reserved(15:0) & crc(15:0)
outboundDat_o <= x"00000000";
packetIndex <= packetIndex + 1;
state <= WAIT_COMPLETE;
end case;
end if;
 
when WAIT_COMPLETE =>
-------------------------------------------------------------------
--
-------------------------------------------------------------------
if (outboundAck_i = '1') then
outboundCyc_o <= '0';
outboundStb_o <= '0';
state <= RESPONSE_DONE;
end if;
when RESPONSE_DONE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (readResponseReady_i = '0') and (writeResponseReady_i = '0') then
state <= WAIT_PACKET;
done_o <= '0';
else
done_o <= '1';
end if;
when others =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
state <= WAIT_PACKET;
end case;
end if;
end if;
end process;
 
end architecture;
branches/2.0.0-development/rtl/vhdl/RioLogicalPackets.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: branches/2.0.0-development/rtl/vhdl/RioCommon.vhd =================================================================== --- branches/2.0.0-development/rtl/vhdl/RioCommon.vhd (revision 45) +++ branches/2.0.0-development/rtl/vhdl/RioCommon.vhd (revision 46) @@ -57,7 +57,216 @@ -- RioCommon package description. ------------------------------------------------------------------------------- package rio_common is + ----------------------------------------------------------------------------- + -- Primitive memory component declarations. + ----------------------------------------------------------------------------- + + component MemorySimpleDualPort + generic( + ADDRESS_WIDTH : natural := 1; + DATA_WIDTH : natural := 1); + port( + clkA_i : in std_logic; + enableA_i : in std_logic; + addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0); + + clkB_i : in std_logic; + enableB_i : in std_logic; + addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); + dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0)); + end component; + + 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; + + ----------------------------------------------------------------------------- + -- Logical layer component declarations. + ----------------------------------------------------------------------------- + + component RioLogicalCommon is + generic( + PORTS : natural); + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + readFrameEmpty_i : in std_logic; + readFrame_o : out std_logic; + readContent_o : out std_logic; + readContentEnd_i : in std_logic; + readContentData_i : in std_logic_vector(31 downto 0); + + writeFrameFull_i : in std_logic; + writeFrame_o : out std_logic; + writeFrameAbort_o : out std_logic; + writeContent_o : out std_logic; + writeContentData_o : out std_logic_vector(31 downto 0); + + inboundCyc_o : out std_logic; + inboundStb_o : out std_logic; + inboundAdr_o : out std_logic_vector(7 downto 0); + inboundDat_o : out std_logic_vector(31 downto 0); + inboundAck_i : in std_logic; + + outboundCyc_i : in std_logic_vector(PORTS-1 downto 0); + outboundStb_i : in std_logic_vector(PORTS-1 downto 0); + outboundDat_i : in std_logic_vector(32*PORTS-1 downto 0); + outboundAck_o : out std_logic_vector(PORTS-1 downto 0)); + end component; + + component RioLogicalMaintenance is + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + readRequestReady_i : in std_logic; + writeRequestReady_i : in std_logic; + offset_i : in std_logic_vector(20 downto 0); + wdptr_i : in std_logic; + payloadLength_i : in std_logic_vector(3 downto 0); + payloadIndex_o : out std_logic_vector(3 downto 0); + payload_i : in std_logic_vector(31 downto 0); + done_o : out std_logic; + + readResponseReady_o : out std_logic; + writeResponseReady_o : out std_logic; + wdptr_o : out std_logic; + payloadLength_o : out std_logic_vector(3 downto 0); + payloadIndex_i : in std_logic_vector(3 downto 0); + payload_o : out std_logic_vector(31 downto 0); + done_i : in std_logic; + + configStb_o : out std_logic; + configWe_o : out std_logic; + configAdr_o : out std_logic_vector(21 downto 0); + configDat_o : out std_logic_vector(31 downto 0); + configDat_i : in std_logic_vector(31 downto 0); + configAck_i : in std_logic); + end component; + + component MaintenanceInbound is + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + readRequestReady_o : out std_logic; + writeRequestReady_o : out std_logic; + readResponseReady_o : out std_logic; + writeResponseReady_o : out std_logic; + portWriteReady_o : out std_logic; + vc_o : out std_logic; + crf_o : out std_logic; + prio_o : out std_logic_vector(1 downto 0); + tt_o : out std_logic_vector(1 downto 0); + dstid_o : out std_logic_vector(31 downto 0); + srcid_o : out std_logic_vector(31 downto 0); + tid_o : out std_logic_vector(7 downto 0); + hop_o : out std_logic_vector(7 downto 0); + offset_o : out std_logic_vector(20 downto 0); + wdptr_o : out std_logic; + payloadLength_o : out std_logic_vector(3 downto 0); + payloadIndex_i : in std_logic_vector(3 downto 0); + payload_o : out std_logic_vector(31 downto 0); + done_i : in std_logic; + + inboundCyc_i : in std_logic; + inboundStb_i : in std_logic; + inboundAdr_i : in std_logic_vector(7 downto 0); + inboundDat_i : in std_logic_vector(31 downto 0); + inboundAck_o : out std_logic); + end component; + + component MaintenanceOutbound is + port( + clk : in std_logic; + areset_n : in std_logic; + enable : in std_logic; + + readRequestReady_i : in std_logic; + writeRequestReady_i : in std_logic; + readResponseReady_i : in std_logic; + writeResponseReady_i : in std_logic; + portWriteReady_i : in std_logic; + vc_i : in std_logic; + crf_i : in std_logic; + prio_i : in std_logic_vector(1 downto 0); + tt_i : in std_logic_vector(1 downto 0); + dstid_i : in std_logic_vector(31 downto 0); + srcid_i : in std_logic_vector(31 downto 0); + status_i : in std_logic_vector(3 downto 0); + tid_i : in std_logic_vector(7 downto 0); + hop_i : in std_logic_vector(7 downto 0); + offset_i : in std_logic_vector(20 downto 0); + wdptr_i : in std_logic; + payloadLength_i : in std_logic_vector(3 downto 0); + payloadIndex_o : out std_logic_vector(3 downto 0); + payload_i : in std_logic_vector(31 downto 0); + done_o : out std_logic; + + outboundCyc_o : out std_logic; + outboundStb_o : out std_logic; + outboundDat_o : out std_logic_vector(31 downto 0); + outboundAck_i : in std_logic); + end component; + + component RioPacketBuffer is + generic( + SIZE_ADDRESS_WIDTH : natural := 6; + CONTENT_ADDRESS_WIDTH : natural := 8); + port( + clk : in std_logic; + areset_n : in std_logic; + + inboundWriteFrameFull_o : out std_logic; + inboundWriteFrame_i : in std_logic; + inboundWriteFrameAbort_i : in std_logic; + inboundWriteContent_i : in std_logic; + inboundWriteContentData_i : in std_logic_vector(31 downto 0); + inboundReadFrameEmpty_o : out std_logic; + inboundReadFrame_i : in std_logic; + inboundReadFrameRestart_i : in std_logic; + inboundReadFrameAborted_o : out std_logic; + inboundReadContentEmpty_o : out std_logic; + inboundReadContent_i : in std_logic; + inboundReadContentEnd_o : out std_logic; + inboundReadContentData_o : out std_logic_vector(31 downto 0); + + outboundWriteFrameFull_o : out std_logic; + outboundWriteFrame_i : in std_logic; + outboundWriteFrameAbort_i : in std_logic; + outboundWriteContent_i : in std_logic; + outboundWriteContentData_i : in std_logic_vector(31 downto 0); + outboundReadFrameEmpty_o : out std_logic; + outboundReadFrame_i : in std_logic; + outboundReadFrameRestart_i : in std_logic; + outboundReadFrameAborted_o : out std_logic; + outboundReadContentEmpty_o : out std_logic; + outboundReadContent_i : in std_logic; + outboundReadContentEnd_o : out std_logic; + outboundReadContentData_o : out std_logic_vector(31 downto 0)); + end component; + + ----------------------------------------------------------------------------- -- Commonly used types. ----------------------------------------------------------------------------- type Array1 is array (natural range <>) of Index: branches/2.0.0-development/rtl/vhdl/RioLogicalMaintenance.vhd =================================================================== --- branches/2.0.0-development/rtl/vhdl/RioLogicalMaintenance.vhd (revision 45) +++ branches/2.0.0-development/rtl/vhdl/RioLogicalMaintenance.vhd (revision 46) @@ -9,9 +9,7 @@ -- Contains a platform to build endpoints on. -- -- To Do: --- REMARK: Dont set complete before the packet is ready in inbound packet --- handler. --- REMARK: Add error indication if erronous sizes are received. +-- - -- -- Author(s): -- - Magnus Rosenius, magro732@opencores.org @@ -46,9 +44,8 @@ ------------------------------------------------------------------------------- -- RioLogicalMaintenance -- This logical layer module handles ingress maintenance requests and converts --- them into accesses on a Wishbone compatible bus accessing the configuration +-- them into accesses on a Wishbone similar bus accessing the configuration -- space. --- Addresses: 0x80 (maint read request) and 0x81 (maint write request). ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; @@ -65,23 +62,29 @@ areset_n : in std_logic; enable : in std_logic; + readRequestReady_i : in std_logic; + writeRequestReady_i : in std_logic; + offset_i : in std_logic_vector(20 downto 0); + wdptr_i : in std_logic; + payloadLength_i : in std_logic_vector(3 downto 0); + payloadIndex_o : out std_logic_vector(3 downto 0); + payload_i : in std_logic_vector(31 downto 0); + done_o : out std_logic; + + readResponseReady_o : out std_logic; + writeResponseReady_o : out std_logic; + wdptr_o : out std_logic; + payloadLength_o : out std_logic_vector(3 downto 0); + payloadIndex_i : in std_logic_vector(3 downto 0); + payload_o : out std_logic_vector(31 downto 0); + done_i : in std_logic; + configStb_o : out std_logic; configWe_o : out std_logic; configAdr_o : out std_logic_vector(21 downto 0); configDat_o : out std_logic_vector(31 downto 0); configDat_i : in std_logic_vector(31 downto 0); - configAck_i : in std_logic; - - inboundCyc_i : in std_logic; - inboundStb_i : in std_logic; - inboundAdr_i : in std_logic_vector(7 downto 0); - inboundDat_i : in std_logic_vector(31 downto 0); - inboundAck_o : out std_logic; - - outboundCyc_o : out std_logic; - outboundStb_o : out std_logic; - outboundDat_o : out std_logic_vector(31 downto 0); - outboundAck_i : in std_logic); + configAck_i : in std_logic); end entity; @@ -90,98 +93,26 @@ ------------------------------------------------------------------------------- architecture RioLogicalMaintenance of RioLogicalMaintenance is - component MaintenanceRequestInbound is - port( - clk : in std_logic; - areset_n : in std_logic; - enable : in std_logic; - - requestReadReady_o : out std_logic; - requestWriteReady_o : out std_logic; - requestVc_o : out std_logic; - requestCrf_o : out std_logic; - requestPrio_o : out std_logic_vector(1 downto 0); - requestTt_o : out std_logic_vector(1 downto 0); - requestDstId_o : out std_logic_vector(31 downto 0); - requestSrcId_o : out std_logic_vector(31 downto 0); - requestTid_o : out std_logic_vector(7 downto 0); - requestOffset_o : out std_logic_vector(20 downto 0); - requestWdptr_o : out std_logic; - requestPayloadLength_o : out std_logic_vector(3 downto 0); - requestPayloadIndex_i : in std_logic_vector(3 downto 0); - requestPayload_o : out std_logic_vector(31 downto 0); - requestDone_i : in std_logic; - - inboundCyc_i : in std_logic; - inboundStb_i : in std_logic; - inboundAdr_i : in std_logic_vector(7 downto 0); - inboundDat_i : in std_logic_vector(31 downto 0); - inboundAck_o : out std_logic); - end component; - - component MaintenanceResponseOutbound is - port( - clk : in std_logic; - areset_n : in std_logic; - enable : in std_logic; - - responseReadReady_i : in std_logic; - responseWriteReady_i : in std_logic; - responseVc_i : in std_logic; - responseCrf_i : in std_logic; - responsePrio_i : in std_logic_vector(1 downto 0); - responseTt_i : in std_logic_vector(1 downto 0); - responseDstId_i : in std_logic_vector(31 downto 0); - responseSrcId_i : in std_logic_vector(31 downto 0); - responseTid_i : in std_logic_vector(7 downto 0); - responseWdptr_i : in std_logic; - responsePayloadLength_i : in std_logic_vector(3 downto 0); - responsePayloadWrite_i : in std_logic; - responsePayloadIndex_i : in std_logic_vector(3 downto 0); - responsePayload_i : in std_logic_vector(31 downto 0); - responseDone_o : out std_logic; - - outboundCyc_o : out std_logic; - outboundStb_o : out std_logic; - outboundDat_o : out std_logic_vector(31 downto 0); - outboundAck_i : in std_logic); - end component; - type StateType is (IDLE, CONFIG_READ, CONFIG_READ_RESPONSE, CONFIG_WRITE, CONFIG_WRITE_RESPONSE); signal state : StateType; - - signal vc : std_logic; - signal crf : std_logic; - signal prio : std_logic_vector(1 downto 0); - signal tt : std_logic_vector(1 downto 0); - signal dstId : std_logic_vector(31 downto 0); - signal srcId : std_logic_vector(31 downto 0); - signal tid : std_logic_vector(7 downto 0); - signal wdptr : std_logic; - + + signal payloadWrite : std_logic; + signal payloadIndex : std_logic_vector(3 downto 0); + signal configAdr : std_logic_vector(21 downto 0); signal configDat : std_logic_vector(31 downto 0); - - signal requestReadReady : std_logic; - signal requestWriteReady : std_logic; - signal requestOffset : std_logic_vector(20 downto 0); - signal requestPayloadLength : std_logic_vector(3 downto 0); - signal requestPayloadIndex : std_logic_vector(3 downto 0); - signal requestPayload : std_logic_vector(31 downto 0); - signal requestDone : std_logic; - - signal responseReadReady : std_logic; - signal responseWriteReady : std_logic; - signal responsePayloadWrite : std_logic; - signal responsePayloadIndex : std_logic_vector(3 downto 0); - signal responseDone : std_logic; - + begin + wdptr_o <= wdptr_i; + configAdr_o <= configAdr; configDat_o <= configDat; + + payloadLength_o <= payloadLength_i; + payloadIndex_o <= payloadIndex; ----------------------------------------------------------------------------- -- @@ -189,24 +120,25 @@ Maintenance: process(clk, areset_n) begin if (areset_n = '0') then + state <= IDLE; + configStb_o <= '0'; configWe_o <= '0'; configAdr <= (others=>'0'); configDat <= (others=>'0'); - responseReadReady <= '0'; - responseWriteReady <= '0'; - responsePayloadWrite <= '0'; + readResponseReady_o <= '0'; + writeResponseReady_o <= '0'; - requestDone <= '0'; + done_o <= '0'; - requestPayloadIndex <= (others=>'0'); + payloadWrite <= '0'; + payloadIndex <= (others=>'0'); elsif (clk'event and clk = '1') then - requestDone <= '0'; - responsePayloadWrite <= '0'; + payloadWrite <= '0'; - if (responsePayloadWrite = '1') then - responsePayloadIndex <= std_logic_vector(unsigned(responsePayloadIndex) + 1); + if (payloadWrite = '1') then + payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1); end if; case state is @@ -214,22 +146,18 @@ --------------------------------------------------------------------- -- --------------------------------------------------------------------- - responsePayloadIndex <= (others=>'0'); - if (requestReadReady = '1') then + payloadIndex <= (others=>'0'); + if (readRequestReady_i = '1') then configStb_o <= '1'; configWe_o <= '0'; - configAdr <= requestOffset & wdptr; + configAdr <= offset_i & wdptr_i; state <= CONFIG_READ; - elsif (requestWriteReady = '1') then + elsif (writeRequestReady_i = '1') then configStb_o <= '1'; configWe_o <= '1'; - configAdr <= requestOffset & wdptr; - configDat <= requestPayload; - requestPayloadIndex <= std_logic_vector(unsigned(requestPayloadIndex) + 1); + configAdr <= offset_i & wdptr_i; + configDat <= payload_i; state <= CONFIG_WRITE; - else - responsePayloadIndex <= (others=>'0'); - requestPayloadIndex <= (others=>'0'); end if; when CONFIG_READ => @@ -237,12 +165,12 @@ -- --------------------------------------------------------------------- if (configAck_i = '1') then - responsePayloadWrite <= '1'; + payloadWrite <= '1'; - if (responsePayloadIndex /= requestPayloadLength) then + if (payloadIndex /= payloadLength_i) then configAdr <= std_logic_vector(unsigned(configAdr) + 1); else - requestDone <= '1'; + done_o <= '1'; configStb_o <= '0'; state <= CONFIG_READ_RESPONSE; end if; @@ -252,11 +180,12 @@ --------------------------------------------------------------------- -- --------------------------------------------------------------------- - if (responseDone = '1') then - responseReadReady <= '0'; + if (done_i = '1') then + done_o <= '0'; + readResponseReady_o <= '0'; state <= IDLE; else - responseReadReady <= '1'; + readResponseReady_o <= '1'; end if; when CONFIG_WRITE => @@ -264,14 +193,14 @@ -- --------------------------------------------------------------------- if (configAck_i = '1') then - responsePayloadWrite <= '1'; + payloadWrite <= '1'; - if (responsePayloadIndex /= requestPayloadLength) then + if (payloadIndex /= payloadLength_i) then configAdr <= std_logic_vector(unsigned(configAdr) + 1); - configDat <= requestPayload; - requestPayloadIndex <= std_logic_vector(unsigned(requestPayloadIndex) + 1); + configDat <= payload_i; + payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1); else - requestDone <= '1'; + done_o <= '1'; configStb_o <= '0'; state <= CONFIG_WRITE_RESPONSE; end if; @@ -281,11 +210,12 @@ --------------------------------------------------------------------- -- --------------------------------------------------------------------- - if (responseDone = '1') then - responseWriteReady <= '0'; + if (done_i = '1') then + done_o <= '0'; + writeResponseReady_o <= '0'; state <= IDLE; else - responseWriteReady <= '1'; + writeResponseReady_o <= '1'; end if; when others => @@ -295,653 +225,18 @@ end process; ----------------------------------------------------------------------------- - -- Request packet handler. - ----------------------------------------------------------------------------- - RequestInbound: MaintenanceRequestInbound - port map( - clk=>clk, - areset_n=>areset_n, - enable=>enable, - requestReadReady_o=>requestReadReady, - requestWriteReady_o=>requestWriteReady, - requestVc_o=>vc, - requestCrf_o=>crf, - requestPrio_o=>prio, - requestTt_o=>tt, - requestDstId_o=>dstId, - requestSrcId_o=>srcId, - requestTid_o=>tid, - requestOffset_o=>requestOffset, - requestWdptr_o=>wdptr, - requestPayloadLength_o=>requestPayloadLength, - requestPayloadIndex_i=>requestPayloadIndex, - requestPayload_o=>requestPayload, - requestDone_i=>requestDone, - inboundCyc_i=>inboundCyc_i, - inboundStb_i=>inboundStb_i, - inboundAdr_i=>inboundAdr_i, - inboundDat_i=>inboundDat_i, - inboundAck_o=>inboundAck_o); - - ----------------------------------------------------------------------------- - -- Response packet handler. - ----------------------------------------------------------------------------- - -- Note that the dstId and srcId is flipped since the response should be - -- returned to the source. - ResponseOutbound: MaintenanceResponseOutbound - port map( - clk=>clk, areset_n=>areset_n, enable=>enable, - responseReadReady_i=>responseReadReady, - responseWriteReady_i=>responseWriteReady, - responseVc_i=>vc, - responseCrf_i=>crf, - responsePrio_i=>prio, - responseTt_i=>tt, - responseDstId_i=>srcId, - responseSrcId_i=>dstId, - responseTid_i=>tid, - responseWdptr_i=>wdptr, - responsePayloadLength_i=>requestPayloadLength, - responsePayloadWrite_i=>responsePayloadWrite, - responsePayloadIndex_i=>responsePayloadIndex, - responsePayload_i=>configDat_i, - responseDone_o=>responseDone, - outboundCyc_o=>outboundCyc_o, - outboundStb_o=>outboundStb_o, - outboundDat_o=>outboundDat_o, - outboundAck_i=>outboundAck_i); - -end architecture; - - -------------------------------------------------------------------------------- --- -------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use work.rio_common.all; - - -------------------------------------------------------------------------------- --- -------------------------------------------------------------------------------- -entity MaintenanceRequestInbound is - port( - clk : in std_logic; - areset_n : in std_logic; - enable : in std_logic; - - requestReadReady_o : out std_logic; - requestWriteReady_o : out std_logic; - requestVc_o : out std_logic; - requestCrf_o : out std_logic; - requestPrio_o : out std_logic_vector(1 downto 0); - requestTt_o : out std_logic_vector(1 downto 0); - requestDstId_o : out std_logic_vector(31 downto 0); - requestSrcId_o : out std_logic_vector(31 downto 0); - requestTid_o : out std_logic_vector(7 downto 0); - requestOffset_o : out std_logic_vector(20 downto 0); - requestWdptr_o : out std_logic; - requestPayloadLength_o : out std_logic_vector(3 downto 0); - requestPayloadIndex_i : in std_logic_vector(3 downto 0); - requestPayload_o : out std_logic_vector(31 downto 0); - requestDone_i : in std_logic; - - inboundCyc_i : in std_logic; - inboundStb_i : in std_logic; - inboundAdr_i : in std_logic_vector(7 downto 0); - inboundDat_i : in std_logic_vector(31 downto 0); - inboundAck_o : out std_logic); -end entity; - - -------------------------------------------------------------------------------- --- -------------------------------------------------------------------------------- -architecture MaintenanceRequestInbound of MaintenanceRequestInbound is - component MemorySimpleDualPort - generic( - ADDRESS_WIDTH : natural := 1; - DATA_WIDTH : natural := 1); - port( - clkA_i : in std_logic; - enableA_i : in std_logic; - addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); - dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0); - - clkB_i : in std_logic; - enableB_i : in std_logic; - addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); - dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0)); - end component; - - type StateType is (RECEIVE_PACKET, READY); - signal state : StateType; - - signal wdptr : std_logic; - signal size : std_logic_vector(3 downto 0); - signal words : natural range 0 to 32; - - signal inboundAck : std_logic; - signal maintReadComplete : std_logic; - signal maintWriteComplete : std_logic; - - signal packetIndex : natural range 0 to 33; - signal requestData : std_logic_vector(31 downto 0); - - signal memoryWrite : std_logic; - signal memoryAddress : std_logic_vector(3 downto 0); - signal memoryDataIn : std_logic_vector(31 downto 0); - -begin - - inboundAck_o <= inboundAck; - - requestReadReady_o <= maintReadComplete when (state = READY) else '0'; - requestWriteReady_o <= maintWriteComplete when (state = READY) else '0'; - - MaintenanceRequest: process(clk, areset_n) - begin - if (areset_n = '0') then - inboundAck <= '0'; - - maintReadComplete <= '0'; - maintWriteComplete <= '0'; - - requestVc_o <= '0'; - requestCrf_o <= '0'; - requestPrio_o <= "00"; - requestTt_o <= "00"; - requestOffset_o <= (others=>'0'); - - wdptr <= '0'; - size <= (others=>'0'); - - packetIndex <= 0; - memoryWrite <= '0'; - memoryAddress <= (others=>'0'); - memoryDataIn <= (others=>'0'); - elsif (clk'event and clk = '1') then - case state is - when RECEIVE_PACKET => - --------------------------------------------------------------------- - -- This state waits for a new maintenance request packet, receives it - -- and parses it. - --------------------------------------------------------------------- - if (inboundCyc_i = '1') then - if (inboundAck = '0') then - if (inboundStb_i = '1') then - if (inboundAdr_i = x"80") then - ------------------------------------------------------------- - -- Maintenance Read Request packet parser. - ------------------------------------------------------------- - case (packetIndex) is - when 0 => - -- x"0000" & ackid & vc & crf & prio & tt & ftype - requestVc_o <= inboundDat_i(9); - requestCrf_o <= inboundDat_i(8); - requestPrio_o <= inboundDat_i(7 downto 6); - requestTt_o <= inboundDat_i(5 downto 4); - packetIndex <= packetIndex + 1; - when 1 => - -- destid - requestDstId_o <= inboundDat_i; - packetIndex <= packetIndex + 1; - when 2 => - -- srcid - requestSrcId_o <= inboundDat_i; - packetIndex <= packetIndex + 1; - when 3 => - -- transaction & rdsize & srcTID & hop & config_offset(20:13) - size <= inboundDat_i(27 downto 24); - requestTid_o <= inboundDat_i(23 downto 16); - requestOffset_o(20 downto 13) <= inboundDat_i(7 downto 0); - packetIndex <= packetIndex + 1; - when 4 => - -- config_offset(12:0) & wdptr & rsrv & crc(15:0) - requestOffset_o(12 downto 0) <= inboundDat_i(31 downto 19); - wdptr <= inboundDat_i(18); - packetIndex <= packetIndex + 1; - maintReadComplete <= '1'; - when others => - -- There should be no more content in a maintenance read request. - -- Discard. - end case; - inboundAck <= '1'; - elsif (inboundAdr_i = x"81") then - ------------------------------------------------------------- - -- Maintenance Write Request packet parser. - ------------------------------------------------------------- - case (packetIndex) is - when 0 => - -- x"0000" & ackid & vc & crf & prio & tt & ftype - requestVc_o <= inboundDat_i(9); - requestCrf_o <= inboundDat_i(8); - requestPrio_o <= inboundDat_i(7 downto 6); - requestTt_o <= inboundDat_i(5 downto 4); - packetIndex <= packetIndex + 1; - when 1 => - -- destId - requestDstId_o <= inboundDat_i; - packetIndex <= packetIndex + 1; - when 2 => - -- srcId - requestSrcId_o <= inboundDat_i; - packetIndex <= packetIndex + 1; - when 3 => - -- transaction & wrsize & srcTID & hop & config_offset(20:13) - size <= inboundDat_i(27 downto 24); - requestTid_o <= inboundDat_i(23 downto 16); - requestOffset_o(20 downto 13) <= inboundDat_i(7 downto 0); - packetIndex <= packetIndex + 1; - when 4 => - -- config_offset(12:0) & wdptr & rsrv & double-word(63:48) - requestOffset_o(12 downto 0) <= inboundDat_i(31 downto 19); - wdptr <= inboundDat_i(18); - requestData(31 downto 16) <= inboundDat_i(15 downto 0); - packetIndex <= packetIndex + 1; - when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 => - -- double-word(47:16) - requestData(31 downto 16) <= inboundDat_i(15 downto 0); - packetIndex <= packetIndex + 1; - - if (not ((size = "1000") and (wdptr = '1'))) then - memoryWrite <= '1'; - memoryDataIn <= requestData(31 downto 16) & inboundDat_i(31 downto 16); - end if; - when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 => - -- double-word(15:0) & double-word(63:48) - requestData(31 downto 16) <= inboundDat_i(15 downto 0); - packetIndex <= packetIndex + 1; - - memoryWrite <= '1'; - memoryDataIn <= requestData(31 downto 16) & inboundDat_i(31 downto 16); - -- REMARK: Dont set complete before the packet is ready... - maintWriteComplete <= '1'; - when others => - -- There should be no more content in a maintenance write request. - -- Discard. - end case; - inboundAck <= '1'; - end if; - end if; - else - if (memoryWrite = '1') then - memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); - end if; - - memoryWrite <= '0'; - inboundAck <= '0'; - end if; - else - if (maintReadComplete = '1') or (maintWriteComplete = '1') then - state <= READY; - end if; - packetIndex <= 0; - memoryAddress <= (others=>'0'); - end if; - - when READY => - --------------------------------------------------------------------- - -- Wait for the handler of the packet to signal that it has been - -- processed. - --------------------------------------------------------------------- - if (requestDone_i = '1') then - maintReadComplete <= '0'; - maintWriteComplete <= '0'; - state <= RECEIVE_PACKET; - end if; - - when others => - --------------------------------------------------------------------- - -- - --------------------------------------------------------------------- - - end case; - end if; - end process; - - ----------------------------------------------------------------------------- - -- Transformation of rdsize/wrsize into length of access and byte lanes. - ----------------------------------------------------------------------------- - - process(clk, areset_n) - begin - if (areset_n = '0') then - requestPayloadLength_o <= (others=>'0'); - requestWdptr_o <= '0'; - elsif (clk'event and clk = '1') then - if (maintReadComplete = '1') or (maintWriteComplete = '1') then - if (wdptr = '0') then - case size is - when "1000" => - -- Read 1 word. - requestPayloadLength_o <= "0000"; - requestWdptr_o <= '0'; - when "1011" => - -- Read 2 words. - requestPayloadLength_o <= "0001"; - requestWdptr_o <= '0'; - when "1100" => - -- Read 8 words. - requestPayloadLength_o <= "0111"; - requestWdptr_o <= '0'; - when others => - -- REMARK: Not allowed for a maintenance packet. - requestPayloadLength_o <= "0000"; - requestWdptr_o <= '0'; - end case; - else - case size is - when "1000" => - -- Read 1 word. - requestPayloadLength_o <= "0000"; - requestWdptr_o <= '1'; - when "1011" => - -- Read 4 words. - requestPayloadLength_o <= "0011"; - requestWdptr_o <= '0'; - when "1100" => - -- Read 16 words. - requestPayloadLength_o <= "1111"; - requestWdptr_o <= '0'; - when others => - -- REMARK: Not allowed for a maintenance packet. - requestPayloadLength_o <= "0000"; - requestWdptr_o <= '0'; - end case; - end if; - end if; - end if; - end process; - - ----------------------------------------------------------------------------- -- Payload content memory. ----------------------------------------------------------------------------- - PayloadMemory: MemorySimpleDualPort - generic map(ADDRESS_WIDTH=>4, DATA_WIDTH=>32) - port map(clkA_i=>clk, - enableA_i=>memoryWrite, - addressA_i=>memoryAddress, - dataA_i=>memoryDataIn, - clkB_i=>clk, - enableB_i=>enable, - addressB_i=>requestPayloadIndex_i, - dataB_o=>requestPayload_o); -end architecture; - - -------------------------------------------------------------------------------- --- -------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use work.rio_common.all; - -------------------------------------------------------------------------------- --- -------------------------------------------------------------------------------- -entity MaintenanceResponseOutbound is - port( - clk : in std_logic; - areset_n : in std_logic; - enable : in std_logic; - - responseReadReady_i : in std_logic; - responseWriteReady_i : in std_logic; - responseVc_i : in std_logic; - responseCrf_i : in std_logic; - responsePrio_i : in std_logic_vector(1 downto 0); - responseTt_i : in std_logic_vector(1 downto 0); - responseDstId_i : in std_logic_vector(31 downto 0); - responseSrcId_i : in std_logic_vector(31 downto 0); - responseTid_i : in std_logic_vector(7 downto 0); - responseWdptr_i : in std_logic; - responsePayloadLength_i : in std_logic_vector(3 downto 0); - responsePayloadWrite_i : in std_logic; - responsePayloadIndex_i : in std_logic_vector(3 downto 0); - responsePayload_i : in std_logic_vector(31 downto 0); - responseDone_o : out std_logic; - - outboundCyc_o : out std_logic; - outboundStb_o : out std_logic; - outboundDat_o : out std_logic_vector(31 downto 0); - outboundAck_i : in std_logic); -end entity; - - -------------------------------------------------------------------------------- --- -------------------------------------------------------------------------------- -architecture MaintenanceResponseOutbound of MaintenanceResponseOutbound is - component MemorySimpleDualPort - generic( - ADDRESS_WIDTH : natural := 1; - DATA_WIDTH : natural := 1); - port( - clkA_i : in std_logic; - enableA_i : in std_logic; - addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); - dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0); - - clkB_i : in std_logic; - enableB_i : in std_logic; - addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); - dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0)); - end component; - - type StateType is (WAIT_PACKET, - READ_RESPONSE, WRITE_RESPONSE, - WAIT_COMPLETE, RESPONSE_DONE); - signal state : StateType; - - signal packetIndex : natural range 0 to 33; - signal responseHeader : std_logic_vector(31 downto 0); - signal responsePayload : std_logic_vector(31 downto 0); - signal responsePayloadIndex : std_logic_vector(2 downto 0); - - signal memoryEnable : std_logic; - signal memoryAddress : std_logic_vector(3 downto 0); - signal memoryDataRead : std_logic_vector(31 downto 0); - -begin - - responseHeader <= - x"0000" & "000000" & responseVc_i & responseCrf_i & - responsePrio_i & responseTt_i & x"8"; - - MaintenanceResponse: process(clk, areset_n) - begin - if (areset_n = '0') then - outboundCyc_o <= '0'; - outboundStb_o <= '0'; - - memoryEnable <= '0'; - memoryAddress <= (others=>'0'); - - responsePayloadIndex <= (others=>'0'); - responseDone_o <= '0'; - - state <= WAIT_PACKET; - elsif (clk'event and clk = '1') then - if (enable = '1') then - case state is - when WAIT_PACKET => - ------------------------------------------------------------------- - -- - ------------------------------------------------------------------- - if (responseReadReady_i = '1') then - outboundCyc_o <= '1'; - outboundStb_o <= '1'; - outboundDat_o <= responseHeader; - packetIndex <= 1; - memoryEnable <= '1'; - memoryAddress <= (others=>'0'); - responsePayloadIndex <= (others=>'0'); - state <= READ_RESPONSE; - elsif (responseWriteReady_i = '1') then - outboundCyc_o <= '1'; - outboundStb_o <= '1'; - outboundDat_o <= responseHeader; - packetIndex <= 1; - state <= WRITE_RESPONSE; - end if; - - when READ_RESPONSE => - --------------------------------------------------------------------- - -- - --------------------------------------------------------------------- - if (outboundAck_i = '1') then - case (packetIndex) is - when 1 => - -- destination - outboundDat_o <= responseDstId_i; - packetIndex <= packetIndex + 1; - when 2 => - -- source - outboundDat_o <= responseSrcId_i; - packetIndex <= packetIndex + 1; - when 3 => - -- transaction & status & targetTID & hop & reserved(7:0) - outboundDat_o <= "0010" & "0000" & responseTid_i & x"ff" & x"00"; - packetIndex <= packetIndex + 1; - when 4 => - -- reserved(15:0) & double-wordN(63:48) - if (responsePayloadLength_i = "0000") and (responseWdptr_i = '0') then - outboundDat_o <= x"0000" & memoryDataRead(31 downto 16); - responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); - memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); - elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then - outboundDat_o <= x"0000" & x"0000"; - else - outboundDat_o <= x"0000" & memoryDataRead(31 downto 16); - responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); - memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); - end if; - packetIndex <= packetIndex + 1; - when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 => - -- double-wordN(47:16) - if (responsePayloadLength_i = "0000") and (responseWdptr_i = '0') then - outboundDat_o <= responsePayload(31 downto 16) & x"0000"; - elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then - outboundDat_o <= x"0000" & memoryDataRead(31 downto 16); - responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); - memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); - else - outboundDat_o <= - responsePayload(31 downto 16) & memoryDataRead(31 downto 16); - responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); - memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); - end if; - packetIndex <= packetIndex + 1; - when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 => - -- double-wordN(15:0) & double-wordN(63:48) - if (responsePayloadLength_i = "0000") and (responseWdptr_i = '0') then - outboundDat_o <= x"0000" & x"0000"; - elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then - outboundDat_o <= responsePayload(31 downto 16) & x"0000"; - else - if (responsePayloadIndex /= responsePayloadLength_i(3 downto 1)) then - outboundDat_o <= - responsePayload(31 downto 16) & memoryDataRead(31 downto 16); - responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); - memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); - else - outboundDat_o <= - responsePayload(31 downto 16) & x"0000"; - responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); - memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); - end if; - end if; - - responsePayloadIndex <= - std_logic_vector(unsigned(responsePayloadIndex) + 1); - - if (responsePayloadIndex = responsePayloadLength_i(3 downto 1)) then - state <= WAIT_COMPLETE; - else - packetIndex <= packetIndex + 1; - end if; - when others => - -- Unallowed response length. - -- Dont do anything. - end case; - end if; - - when WRITE_RESPONSE => - --------------------------------------------------------------------- - -- - --------------------------------------------------------------------- - if (outboundAck_i = '1') then - case (packetIndex) is - when 1 => - -- destination - outboundDat_o <= responseDstId_i; - packetIndex <= packetIndex + 1; - when 2 => - -- source - outboundDat_o <= responseSrcId_i; - packetIndex <= packetIndex + 1; - when 3 => - -- transaction & status & targetTID & hop & reserved(7:0) - outboundDat_o <= "0011" & "0000" & responseTid_i & x"ff" & x"00"; - packetIndex <= packetIndex + 1; - when others => - -- reserved(15:0) & crc(15:0) - outboundDat_o <= x"00000000"; - packetIndex <= packetIndex + 1; - state <= WAIT_COMPLETE; - end case; - end if; - - when WAIT_COMPLETE => - ------------------------------------------------------------------- - -- - ------------------------------------------------------------------- - if (outboundAck_i = '1') then - outboundCyc_o <= '0'; - outboundStb_o <= '0'; - state <= RESPONSE_DONE; - end if; - - when RESPONSE_DONE => - --------------------------------------------------------------------- - -- - --------------------------------------------------------------------- - memoryEnable <= '0'; - if (responseReadReady_i = '0') and (responseWriteReady_i = '0') then - state <= WAIT_PACKET; - responseDone_o <= '0'; - else - responseDone_o <= '1'; - end if; - - when others => - --------------------------------------------------------------------- - -- - --------------------------------------------------------------------- - state <= WAIT_PACKET; - - end case; - end if; - end if; - end process; - - ----------------------------------------------------------------------------- - -- Payload content memory. - ----------------------------------------------------------------------------- PayloadMemory: MemorySimpleDualPort generic map(ADDRESS_WIDTH=>4, DATA_WIDTH=>32) port map(clkA_i=>clk, - enableA_i=>responsePayloadWrite_i, - addressA_i=>responsePayloadIndex_i, - dataA_i=>responsePayload_i, + enableA_i=>payloadWrite, + addressA_i=>payloadIndex, + dataA_i=>configDat_i, clkB_i=>clk, - enableB_i=>memoryEnable, - addressB_i=>memoryAddress, - dataB_o=>memoryDataRead); + enableB_i=>'1', + addressB_i=>payloadIndex_i, + dataB_o=>payload_o); end architecture;
/branches/2.0.0-development/rtl/vhdl/RioSwitch.vhd
10,7 → 10,22
-- entity RioSwitch.
--
-- To Do:
-- -
-- - Add configAck to external interface.
-- - Complete forwarding of maintenance packets.
-- - Remove all common component-declarations and move them to RioCommon.
-- - Add support for longer maintenance packets.
-- - Add support for portWrite maintenance packets.
-- - Add a real crossbar as interconnect.
-- - Change the internal addressing to one-hot.
-- - Remove acknowledge cycle when transfering packets between ports to double
-- the bandwidth.
-- - Add hot-swap.
-- - Connect linkInitialized to all ports and read it from the source port
-- using the interconnect. This will allow alternative routes since the
-- sending port can see if a receiving port is up or not.
-- - Add support for extended route.
-- - Add validity-bit to know if a route has been activly set for a particular
-- deviceId.
--
-- Author(s):
-- - Magnus Rosenius, magro732@opencores.org
215,6 → 230,7
component SwitchPort is
generic(
MAINTENANCE_LOOKUP : boolean;
PORT_INDEX : natural);
port(
clk : in std_logic;
249,6 → 265,7
readContent_o : out std_logic;
readContentEnd_i : in std_logic;
readContentData_i : in std_logic_vector(31 downto 0);
writeFramePort_o : out std_logic_vector(9 downto 0);
writeFrameFull_i : in std_logic;
writeFrame_o : out std_logic;
writeFrameAbort_o : out std_logic;
316,6 → 333,7
PortGeneration: for portIndex in 0 to SWITCH_PORTS-1 generate
PortInst: SwitchPort
generic map(
MAINTENANCE_LOOKUP=>false,
PORT_INDEX=>portIndex)
port map(
clk=>clk, areset_n=>areset_n,
335,6 → 353,7
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),
writeFramePort_o=>open,
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));
382,9 → 401,8
 
 
-------------------------------------------------------------------------------
-- SwitchPort
-- SwitchPort.
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
396,6 → 414,7
-------------------------------------------------------------------------------
entity SwitchPort is
generic(
MAINTENANCE_LOOKUP : boolean;
PORT_INDEX : natural);
port(
clk : in std_logic;
436,6 → 455,7
readContent_o : out std_logic;
readContentEnd_i : in std_logic;
readContentData_i : in std_logic_vector(31 downto 0);
writeFramePort_o : out std_logic_vector(7 downto 0);
writeFrameFull_i : in std_logic;
writeFrame_o : out std_logic;
writeFrameAbort_o : out std_logic;
457,13 → 477,12
STATE_WAIT_TARGET_WRITE,
STATE_WAIT_COMPLETE);
signal masterState : MasterStateType;
 
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);
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
 
-----------------------------------------------------------------------------
542,7 → 561,7
masterData_o <= readContentData_i;
 
-- Check if this is a maintenance frame.
if (ftype = FTYPE_MAINTENANCE_CLASS) then
if ((not MAINTENANCE_LOOKUP) and (ftype = FTYPE_MAINTENANCE_CLASS)) then
-- This is a maintenance frame.
 
-- Always route these frames to the maintenance module in the
714,13 → 733,12
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
729,6 → 747,7
 
slaveData_o <= '0';
 
writeFramePort_o <= (others=>'0');
writeFrame_o <= '0';
writeFrameAbort_o <= '0';
writeContent_o <= '0';
757,6 → 776,7
-- Writing the status address.
-- Update the buffering output signals according to the input
-- data.
writeFramePort_o <= slaveAddr_i(8 downto 1);
writeFrame_o <= slaveData_i(0);
writeFrameAbort_o <= slaveData_i(1);
else
804,6 → 824,8
 
 
 
 
 
-------------------------------------------------------------------------------
-- SwitchPortMaintenance
-------------------------------------------------------------------------------
892,113 → 914,157
-------------------------------------------------------------------------------
architecture SwitchPortMaintenanceImpl of SwitchPortMaintenance is
 
component MemoryDualPort is
component SwitchPort is
generic(
ADDRESS_WIDTH : natural := 1;
DATA_WIDTH : natural := 1);
MAINTENANCE_LOOKUP : boolean;
PORT_INDEX : natural);
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);
clk : in std_logic;
areset_n : in std_logic;
 
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));
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);
writeFramePort_o : out std_logic_vector(7 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;
 
-----------------------------------------------------------------------------
-- Signals between the port and the packet-queue.
-----------------------------------------------------------------------------
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;
signal outboundFramePort : std_logic_vector(7 downto 0);
signal outboundReadFrameEmpty : std_logic;
signal outboundReadFrame : std_logic;
signal outboundReadContent : std_logic;
signal outboundReadContentEnd : std_logic;
signal outboundReadContentData : std_logic_vector(31 downto 0);
signal inboundFramePort : std_logic_vector(7 downto 0);
signal inboundWriteFrameFull : std_logic;
signal inboundWriteFrame : std_logic;
signal inboundWriteFrameAbort : std_logic;
signal inboundWriteContent : std_logic;
signal inboundWriteContentData : std_logic_vector(31 downto 0);
 
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;
-----------------------------------------------------------------------------
-- Signals between the packet-queue and RioLogicalCommon.
-----------------------------------------------------------------------------
 
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 inboundReadFrameEmpty : std_logic;
signal inboundReadFrame : std_logic;
signal inboundReadContent : std_logic;
signal inboundReadContentEnd : std_logic;
signal inboundReadContentData : std_logic_vector(31 downto 0);
signal outboundWriteFrameFull : std_logic;
signal outboundWriteFrame : std_logic;
signal outboundWriteFrameAbort : std_logic;
signal outboundWriteContent : std_logic;
signal outboundWriteContentData : std_logic_vector(31 downto 0);
 
signal 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);
-----------------------------------------------------------------------------
-- Signals between RioLogicalCommon and PacketHandler.
-----------------------------------------------------------------------------
 
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 inboundCyc : std_logic;
signal inboundStb : std_logic;
signal inboundAdr : std_logic_vector(7 downto 0);
signal inboundDat : std_logic_vector(31 downto 0);
signal inboundAck : std_logic;
signal outboundCyc : std_logic_vector(0 downto 0);
signal outboundStb : std_logic_vector(0 downto 0);
signal outboundDat : std_logic_vector(31 downto 0);
signal outboundAck : std_logic_vector(0 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);
-----------------------------------------------------------------------------
-- Signals between PacketHandlers and maintenance controllers.
-----------------------------------------------------------------------------
 
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);
signal tid : std_logic_vector(7 downto 0);
 
signal readRequestInbound : std_logic;
signal writeRequestInbound : std_logic;
signal readResponseInbound : std_logic;
signal writeResponseInbound : std_logic;
signal portWriteInbound : std_logic;
signal dstIdInbound : std_logic_vector(31 downto 0);
signal srcIdInbound : std_logic_vector(31 downto 0);
signal hopInbound : std_logic_vector(7 downto 0);
signal offsetInbound : std_logic_vector(20 downto 0);
signal wdptrInbound: std_logic;
signal payloadLengthInbound : std_logic_vector(3 downto 0);
signal payloadIndexInbound : std_logic_vector(3 downto 0);
signal payloadInbound : std_logic_vector(31 downto 0);
signal doneInbound : std_logic;
 
signal readRequestOutbound : std_logic;
signal writeRequestOutbound : std_logic;
signal readResponseOutbound : std_logic;
signal writeResponseOutbound : std_logic;
signal portWriteOutbound : std_logic;
signal dstIdOutbound : std_logic_vector(31 downto 0);
signal srcIdOutbound : std_logic_vector(31 downto 0);
signal hopOutbound : std_logic_vector(7 downto 0);
signal wdptrOutbound: std_logic;
signal payloadLengthOutbound : std_logic_vector(3 downto 0);
signal payloadIndexOutbound : std_logic_vector(3 downto 0);
signal payloadOutbound : std_logic_vector(31 downto 0);
signal doneOutbound : std_logic;
 
signal readRequestMaint : std_logic;
signal writeRequestMaint : std_logic;
signal readResponseMaint : std_logic;
signal writeResponseMaint : std_logic;
signal wdptrMaint : std_logic;
signal payloadLengthMaint : std_logic_vector(3 downto 0);
signal payloadIndexMaint : std_logic_vector(3 downto 0);
signal payloadMaint : std_logic_vector(31 downto 0);
signal doneMaint : std_logic;
-----------------------------------------------------------------------------
--
-----------------------------------------------------------------------------
 
signal sendPacket : std_logic;
signal forwardPacket : std_logic;
-----------------------------------------------------------------------------
-- 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);
1015,15 → 1081,20
-----------------------------------------------------------------------------
-- Configuration space signals.
-----------------------------------------------------------------------------
 
signal configStb : std_logic;
signal configWe : std_logic;
signal configAdr : std_logic_vector(23 downto 0);
signal configDataWrite : std_logic_vector(31 downto 0);
signal configDataRead, configDataReadInternal : std_logic_vector(31 downto 0);
signal configAck : std_logic;
 
-- REMARK: Make these variables instead...
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);
1030,66 → 1101,216
begin
 
-----------------------------------------------------------------------------
-- Memory to contain the outbound frame.
-- Normal switch port instance interfacing the switch interconnect.
-----------------------------------------------------------------------------
OutboundFrameMemory: MemorySinglePort
-- REMARK: PORT_INDEX is not used in this instantiation.
-- REMARK: Add generic to disable the maintenance routing to this port...
PortInst: SwitchPort
generic map(
ADDRESS_WIDTH=>3, DATA_WIDTH=>32)
MAINTENANCE_LOOKUP=>true,
PORT_INDEX=>0)
port map(
clk_i=>clk,
enable_i=>outboundFrameEnable, writeEnable_i=>outboundFrameWrite,
address_i=>outboundFrameAddress,
data_i=>outboundFrameDataWrite, data_o=>outboundFrameDataRead);
clk=>clk, areset_n=>areset_n,
masterCyc_o=>masterCyc_o,
masterStb_o=>masterStb_o,
masterWe_o=>masterWe_o,
masterAddr_o=>masterAddr_o,
masterData_o=>masterData_o,
masterData_i=>masterData_i,
masterAck_i=>masterAck_i,
slaveCyc_i=>slaveCyc_i,
slaveStb_i=>slaveStb_i,
slaveWe_i=>slaveWe_i,
slaveAddr_i=>slaveAddr_i,
slaveData_i=>slaveData_i,
slaveData_o=>slaveData_o,
slaveAck_o=>slaveAck_o,
lookupStb_o=>open,
lookupAddr_o=>open,
lookupData_i=>outboundFramePort,
lookupAck_i=>'1',
readFrameEmpty_i=>outboundReadFrameEmpty,
readFrame_o=>outboundReadFrame,
readFrameRestart_o=>open,
readFrameAborted_i=>'0',
readContentEmpty_i=>'0',
readContent_o=>outboundReadContent,
readContentEnd_i=>outboundReadContentEnd,
readContentData_i=>outboundReadContentData,
writeFramePort_o=>inboundFramePort,
writeFrameFull_i=>inboundWriteFrameFull,
writeFrame_o=>inboundWriteFrame,
writeFrameAbort_o=>inboundWriteFrameAbort,
writeContent_o=>inboundWriteContent,
writeContentData_o=>inboundWriteContentData);
 
-----------------------------------------------------------------------------
-- Packet queue.
-- This queue should only contain one packet.
-----------------------------------------------------------------------------
-- REMARK: Use a packet-buffer with a configurable maximum sized packet...
PacketQueue: RioPacketBuffer
generic map(SIZE_ADDRESS_WIDTH=>1, CONTENT_ADDRESS_WIDTH=>7)
port map(
clk=>clk, areset_n=>areset_n,
inboundWriteFrameFull_o=>inboundWriteFrameFull,
inboundWriteFrame_i=>inboundWriteFrame,
inboundWriteFrameAbort_i=>inboundWriteFrameAbort,
inboundWriteContent_i=>inboundWriteContent,
inboundWriteContentData_i=>inboundWriteContentData,
inboundReadFrameEmpty_o=>inboundReadFrameEmpty,
inboundReadFrame_i=>inboundReadFrame,
inboundReadFrameRestart_i=>'0',
inboundReadFrameAborted_o=>open,
inboundReadContentEmpty_o=>open,
inboundReadContent_i=>inboundReadContent,
inboundReadContentEnd_o=>inboundReadContentEnd,
inboundReadContentData_o=>inboundReadContentData,
outboundWriteFrameFull_o=>outboundWriteFrameFull,
outboundWriteFrame_i=>outboundWriteFrame,
outboundWriteFrameAbort_i=>outboundWriteFrameAbort,
outboundWriteContent_i=>outboundWriteContent,
outboundWriteContentData_i=>outboundWriteContentData,
outboundReadFrameEmpty_o=>outboundReadFrameEmpty,
outboundReadFrame_i=>outboundReadFrame,
outboundReadFrameRestart_i=>'0',
outboundReadFrameAborted_o=>open,
outboundReadContentEmpty_o=>open,
outboundReadContent_i=>outboundReadContent,
outboundReadContentEnd_o=>outboundReadContentEnd,
outboundReadContentData_o=>outboundReadContentData);
-----------------------------------------------------------------------------
-- CRC generation for outbound frames.
-- Logical common packet parser.
-- This module removes CRC and unpack addresses in the inbound direction and
-- adds CRC and packs addresses in the outbound direction.
-----------------------------------------------------------------------------
LogicalCommon: RioLogicalCommon
generic map(PORTS=>1)
port map(
clk=>clk, areset_n=>areset_n, enable=>'1',
readFrameEmpty_i=>inboundReadFrameEmpty,
readFrame_o=>inboundReadFrame,
readContent_o=>inboundReadContent,
readContentEnd_i=>inboundReadContentEnd,
readContentData_i=>inboundReadContentData,
writeFrameFull_i=>outboundWriteFrameFull,
writeFrame_o=>outboundWriteFrame,
writeFrameAbort_o=>outboundWriteFrameAbort,
writeContent_o=>outboundWriteContent,
writeContentData_o=>outboundWriteContentData,
inboundCyc_o=>inboundCyc,
inboundStb_o=>inboundStb,
inboundAdr_o=>inboundAdr,
inboundDat_o=>inboundDat,
inboundAck_i=>inboundAck,
outboundCyc_i=>outboundCyc,
outboundStb_i=>outboundStb,
outboundDat_i=>outboundDat,
outboundAck_o=>outboundAck);
 
crc16Data <= outboundFrameDataWrite;
-- REMARK: Insert FFs here to make the critical path shorter...
Crc16High: Crc16CITT
-----------------------------------------------------------------------------
-- Inbound maintenance packet parser.
-- 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;
doneInbound <= doneOutbound when (forwardPacket = '1') else doneMaint;
InboundPacket: MaintenanceInbound
port map(
d_i=>crc16Data(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp);
Crc16Low: Crc16CITT
clk=>clk, areset_n=>areset_n, enable=>'1',
readRequestReady_o=>readRequestInbound,
writeRequestReady_o=>writeRequestInbound,
readResponseReady_o=>readResponseInbound,
writeResponseReady_o=>writeResponseInbound,
portWriteReady_o=>portWriteInbound,
vc_o=>vc,
crf_o=>crf,
prio_o=>prio,
tt_o=>tt,
dstid_o=>dstIdInbound,
srcid_o=>srcIdInbound,
tid_o=>tid,
hop_o=>hopInbound,
offset_o=>offsetInbound,
wdptr_o=>wdptrInbound,
payloadLength_o=>payloadLengthInbound,
payloadIndex_i=>payloadIndexInbound,
payload_o=>payloadInbound,
done_i=>doneInbound,
inboundCyc_i=>inboundCyc,
inboundStb_i=>inboundStb,
inboundAdr_i=>inboundAdr,
inboundDat_i=>inboundDat,
inboundAck_o=>inboundAck);
 
-----------------------------------------------------------------------------
-- Outbound maintenance packet generator.
-----------------------------------------------------------------------------
readRequestOutbound <= (readRequestInbound and sendPacket) when (forwardPacket = '1') else '0';
writeRequestOutbound <= (writeRequestInbound and sendPacket) when (forwardPacket = '1') else '0';
readResponseOutbound <= (readResponseInbound and sendPacket) when (forwardPacket = '1') else readResponseMaint;
writeResponseOutbound <= (writeResponseInbound and sendPacket) when (forwardPacket = '1') else writeResponseMaint;
portWriteOutbound <= (portWriteInbound and sendPacket) when (forwardPacket = '1') else '0';
srcIdOutbound <= srcIdInbound when (forwardPacket = '1') else dstIdInbound;
dstIdOutbound <= dstIdInbound when (forwardPacket = '1') else srcIdInbound;
hopOutbound <= std_logic_vector(unsigned(hopInbound)-1) when (forwardPacket = '1') else x"ff";
wdptrOutbound <= wdptrInbound when (forwardPacket = '1') else wdptrMaint;
payloadLengthOutbound <= payloadLengthInbound when (forwardPacket = '1') else payloadLengthMaint;
payloadOutbound <= payloadInbound when (forwardPacket = '1') else payloadMaint;
-- REMARK: Connect enable to something...
OutboundPacket: MaintenanceOutbound
port map(
d_i=>crc16Data(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next);
clk=>clk, areset_n=>areset_n, enable=>'1',
readRequestReady_i=>readRequestOutbound,
writeRequestReady_i=>writeRequestOutbound,
readResponseReady_i=>readResponseOutbound,
writeResponseReady_i=>writeResponseOutbound,
portWriteReady_i=>portWriteOutbound,
vc_i=>vc,
crf_i=>crf,
prio_i=>prio,
tt_i=>tt,
dstid_i=>dstIdOutbound,
srcid_i=>srcIdOutbound,
status_i=>"0000",
tid_i=>tid,
hop_i=>hopOutbound,
offset_i=>offsetInbound,
wdptr_i=>wdptrOutbound,
payloadLength_i=>payloadLengthOutbound,
payloadIndex_o=>payloadIndexOutbound,
payload_i=>payloadOutbound,
done_o=>doneOutbound,
outboundCyc_o=>outboundCyc(0),
outboundStb_o=>outboundStb(0),
outboundDat_o=>outboundDat,
outboundAck_i=>outboundAck(0));
 
-----------------------------------------------------------------------------
-- Master interface process.
-- Main switch maintenance controller.
-- This controller decides when to forward packets and when to consume and
-- produce responses instead.
-- It also determines when portWrite-packets are allowed to be sent.
-----------------------------------------------------------------------------
Master: process(clk, areset_n)
RioSwitchMaintenance: process(clk, areset_n)
type MasterStateType is (STATE_IDLE,
STATE_START_PORT_LOOKUP,
STATE_READ_PORT_LOOKUP,
STATE_WAIT_COMPLETE);
variable masterState : MasterStateType;
begin
if (areset_n = '0') then
masterState <= STATE_IDLE;
masterState := STATE_IDLE;
 
sendPacket <= '0';
forwardPacket <= '0';
outboundFramePort <= (others=>'0');
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 =>
1096,392 → 1317,20
---------------------------------------------------------------------
--
---------------------------------------------------------------------
-- 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;
-- Wait for frame to be available.
-- REMARK: Discard erronous frames.
sendPacket <= '0';
if (((readRequestInbound = '1') or (writeRequestInbound = '1')) and (hopInbound = x"00")) then
masterState := STATE_WAIT_COMPLETE;
forwardPacket <= '0';
outboundFramePort <= inboundFramePort;
elsif (((readResponseInbound = '1') or ((readRequestInbound = '1') and (hopInbound /= x"00"))) or
((writeResponseInbound = '1') or ((writeRequestInbound = '1') and (hopInbound /= x"00"))) or
(portWriteInbound = '1')) then
masterState := STATE_START_PORT_LOOKUP;
forwardPacket <= '1';
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 =>
---------------------------------------------------------------------
--
1489,8 → 1338,8
 
-- Initiate a port-lookup of the destination address.
lookupStb_o <= '1';
lookupAddr_o <= destinationId;
masterState <= STATE_READ_PORT_LOOKUP;
lookupAddr_o <= dstIdInbound(15 downto 0);
masterState := STATE_READ_PORT_LOOKUP;
 
when STATE_READ_PORT_LOOKUP =>
---------------------------------------------------------------------
1505,118 → 1354,23
lookupStb_o <= '0';
 
-- Wait for the target port to reply.
masterAddr_o <= '0' & lookupData_i & '0';
masterState <= STATE_READ_TARGET_PORT;
outboundFramePort <= lookupData_i;
masterState := STATE_WAIT_COMPLETE;
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???
-- 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';
if (doneOutbound = '1') then
masterState := STATE_IDLE;
end if;
 
when STATE_WAIT_SLAVE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
masterState <= STATE_IDLE;
when others =>
---------------------------------------------------------------------
1626,229 → 1380,52
end if;
end process;
 
-----------------------------------------------------------------------------
-- Slave interface process.
-- Bridge between the inbound RapidIO maintenance packets to the internal
-- config-space bus.
-----------------------------------------------------------------------------
-- 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)
-- REMARK: Connect enable...
readRequestMaint <= (readRequestInbound and sendPacket) when (forwardPacket = '0') else '0';
writeRequestMaint <= (writeRequestInbound and sendPacket) when (forwardPacket = '0') else '0';
MaintenanceBridge: RioLogicalMaintenance
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);
clk=>clk, areset_n=>areset_n, enable=>'1',
readRequestReady_i=>readRequestMaint,
writeRequestReady_i=>writeRequestMaint,
offset_i=>offsetInbound,
wdptr_i=>wdptrInbound,
payloadLength_i=>payloadLengthInbound,
payloadIndex_o=>payloadIndexMaint,
payload_i=>payloadInbound,
done_o=>doneMaint,
readResponseReady_o=>readResponseMaint,
writeResponseReady_o=>writeResponseMaint,
wdptr_o=>wdptrMaint,
payloadLength_o=>payloadLengthMaint,
payloadIndex_i=>payloadIndexOutbound,
payload_o=>payloadMaint,
done_i=>doneOutbound,
configStb_o=>configStb,
configWe_o=>configWe,
configAdr_o=>configAdr(23 downto 2),
configDat_o=>configDataWrite,
configDat_i=>configDataRead,
configAck_i=>configAck);
configAdr(1 downto 0) <= "00";
-----------------------------------------------------------------------------
-- Configuration memory.
-- Switch 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;
 
-- REMARK: Connect configAck...
configStb_o <= '1' when ((configStb = '1') and (configAdr(23 downto 16) /= x"00")) else '0';
configWe_o <= configWe;
configAddr_o <= configAdr;
configData_o <= configDataWrite;
configDataRead <= configData_i when (configAddress(23 downto 16) /= x"00") else
configDataRead <= configData_i when (configAdr(23 downto 16) /= x"00") else
configDataReadInternal;
ConfigMemory: process(areset_n, clk)
1855,6 → 1432,7
begin
if (areset_n = '0') then
configDataReadInternal <= (others => '0');
configAck <= '0';
 
routeTableEnable <= '1';
routeTableWrite <= '0';
1879,397 → 1457,436
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.
if (configAck = '0') then
if (configStb = '1') then
configAck <= '1';
case (configAddress) is
when x"000000" =>
-----------------------------------------------------------------
-- Device Identity CAR. Read-only.
-----------------------------------------------------------------
-- Check if the access is into implementation defined space or if the
-- access should be handled here.
if (configAdr(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 (configAdr) 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 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 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_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.
-----------------------------------------------------------------
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');
-- Reserved.
configDataReadInternal(31 downto 16) <= (others => '0');
 
-- PortTotal.
configDataReadInternal(15 downto 8) <=
std_logic_vector(to_unsigned(SWITCH_PORTS, 8));
-- 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.
-----------------------------------------------------------------
-- 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.
-----------------------------------------------------------------
-- 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');
if (configWe = '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
-- Not writing the same as the stored value.
-- Ignore the write.
-- 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;
end if;
configDataReadInternal(31 downto 16) <= (others => '0');
configDataReadInternal(15 downto 0) <= hostBaseDeviceId;
when x"00006c" =>
-----------------------------------------------------------------
-- Component TAG CSR.
-----------------------------------------------------------------
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 (configWe = '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 (configWe = '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;
if (configWe = '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.
-----------------------------------------------------------------
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.
-----------------------------------------------------------------
if (configWe = '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.
-----------------------------------------------------------------
-- 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 (configWe = '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');
if (configWe = '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');
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);
-- Iterate through all active ports.
for portIndex in 0 to SWITCH_PORTS-1 loop
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';
if(unsigned(configAdr) = (x"000148" + (x"000020"*portIndex))) then
-----------------------------------------------------------------
-- Port N Local ackID CSR.
-----------------------------------------------------------------
if (configWe = '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(configAdr) = (x"000154" + (x"000020"*portIndex))) then
-----------------------------------------------------------------
-- Port N Control 2 CSR.
-----------------------------------------------------------------
configDataReadInternal <= (others => '0');
elsif(unsigned(configAdr) = (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');
-- 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');
-- 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(configAdr) = (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');
-- Initialized Port Width.
configDataReadInternal(29 downto 27) <= (others=>'0');
 
-- Port Width Override.
configDataReadInternal(26 downto 24) <= (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);
-- Port disable.
configDataReadInternal(23) <= '0';
-- Output Port Enable.
if (configWe = '1') then
outputPortEnable(portIndex) <= configDataWrite(22);
end if;
configDataReadInternal(22) <= outputPortEnable(portIndex);
-- Input Port Enable.
if (configWe = '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';
-- 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';
-- Reserved.
configDataReadInternal(16) <= '0';
 
-- Extended Port Width Override.
configDataReadInternal(15 downto 14) <= (others=>'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');
-- 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');
-- Reserved.
configDataReadInternal(3 downto 1) <= (others=>'0');
 
-- Port Type.
configDataReadInternal(0) <= '1';
end if;
end loop;
-- Port Type.
configDataReadInternal(0) <= '1';
end if;
end loop;
 
end case;
end case;
end if;
else
-- Config memory not enabled.
end if;
else
-- Config memory not enabled.
configAck <= '0';
end if;
end if;
end process;
-----------------------------------------------------------------------------
-- 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);
end architecture;
 
 
/branches/2.0.0-development/rtl/vhdl/RioLogicalCommon.vhd
9,10 → 9,10
-- Contains a platform to build endpoints on.
--
-- To Do:
-- REMARK: Clean up and increase the speed of the interface to packet handlers.
-- REMARK: 8-bit deviceId has not been verified, fix.
-- REMARK: Egress; Places packets in different queues depending on the packet priority?
-- REMARK: Add verification of all sizes of packets.
-- - Clean up and increase the speed of the interface to packet handlers.
-- - 8-bit deviceId has not been verified, fix.
-- - Egress; Place packets in different queues depending on the packet priority?
-- - Add verification of all sizes of packets.
--
-- Author(s):
-- - Magnus Rosenius, magro732@opencores.org

powered by: WebSVN 2.1.0

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