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 |