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

Subversion Repositories rio

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /rio
    from Rev 38 to Rev 39
    Reverse comparison

Rev 38 → Rev 39

/branches/singleSymbol/rtl/vhdl/RioWbBridge.vhd
7,13 → 7,13
--
-- Description
-- Containing a bridge between a RapidIO network and a Wishbone bus. Packets
-- NWRITE and NREAD are currently supported.
-- NWRITE, NWRITER and NREAD are currently supported.
--
-- To Do:
-- -
--
-- Author(s):
-- - Nader Kardouni, nader.kardouni@se.transport.bombardier.com
-- - Magnus Rosenius, magro732@opencores.org
--
-------------------------------------------------------------------------------
--
42,6 → 42,10
--
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
-- RioWbBridge.
-------------------------------------------------------------------------------
-- REMARK: Add support for EXTENDED_ADDRESS...
library ieee;
use ieee.numeric_std.ALL;
use ieee.std_logic_1164.all;
49,20 → 53,20
use work.rio_common.all;
 
-------------------------------------------------------------------------------
-- entity for RioWbBridge.
-- Entity for RioWbBridge.
-------------------------------------------------------------------------------
Entity RioWbBridge is
entity RioWbBridge is
generic(
EXTENDED_ADDRESS : natural range 0 to 2 := 0;
DEVICE_IDENTITY : std_logic_vector(15 downto 0);
DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
DEVICE_REV : std_logic_vector(31 downto 0);
ASSY_IDENTITY : std_logic_vector(15 downto 0);
ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
ASSY_REV : std_logic_vector(15 downto 0);
DEFAULT_BASE_DEVICE_ID : std_logic_vector(15 downto 0) := x"ffff");
ASSY_REV : std_logic_vector(15 downto 0));
port(
clk : in std_logic; -- Main clock 25MHz
areset_n : in std_logic; -- Asynchronous reset, active low
clk : in std_logic;
areset_n : in std_logic;
 
readFrameEmpty_i : in std_logic;
readFrame_o : out std_logic;
69,7 → 73,6
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;
76,860 → 79,1316
writeContent_o : out std_logic;
writeContentData_o : out std_logic_vector(31 downto 0);
 
-- interface to the peripherals module
wbStb_o : out std_logic; -- strob signal, active high
wbWe_o : out std_logic; -- write signal, active high
wbData_o : out std_logic_vector(7 downto 0); -- master data bus
wbAdr_o : out std_logic_vector(25 downto 0); -- master address bus
wbErr_i : in std_logic; -- error signal, high active
wbAck_i : in std_logic; -- slave acknowledge
wbData_i : in std_logic_vector(7 downto 0) -- slave data bus
);
end;
cyc_o : out std_logic;
stb_o : out std_logic;
we_o : out std_logic;
adr_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
sel_o : out std_logic_vector(7 downto 0);
dat_o : out std_logic_vector(63 downto 0);
dat_i : in std_logic_vector(63 downto 0);
err_i : in std_logic;
ack_i : in std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
-- Architecture for RioWbBridge.
-------------------------------------------------------------------------------
architecture rtl of RioWbBridge is
architecture RioWbBridgeImpl of RioWbBridge is
 
component Crc16CITT is
component RequestClassInbound is
generic(
EXTENDED_ADDRESS : natural range 0 to 2 := 0);
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));
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
ready_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);
address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
length_o : out std_logic_vector(3 downto 0);
select_o : out std_logic_vector(7 downto 0);
done_i : in std_logic;
slaveCyc_i : in std_logic;
slaveStb_i : in std_logic;
slaveAdr_i : in std_logic_vector(7 downto 0);
slaveDat_i : in std_logic_vector(31 downto 0);
slaveAck_o : out std_logic);
end component;
 
constant RST_LVL : std_logic := '0';
constant BERR_UNKNOWN_DATA : std_logic_vector(7 downto 0) := X"08"; -- not valid data
constant BERR_FRAME_SIZE : std_logic_vector(7 downto 0) := X"81"; -- Frame code size error
constant BERR_FRAME_CODE : std_logic_vector(7 downto 0) := X"80"; -- Frame code type error
constant BERR_NOT_RESPONSE : std_logic_vector(7 downto 0) := X"86"; -- Not response from the device
type state_type_RioBrige is (IDLE, WAIT_HEADER_0, HEADER_0, HEADER_1, CHECK_OPERATION,
READ_ADDRESS, READ_FROM_FIFO, CHECK_ERROR, WRITE_DATA,
WRITE_TO_WB, WAIT_IDLE, SEND_DONE_0, SEND_DONE_1,
SEND_DONE_2, READ_FROM_WB, APPEND_CRC,
SEND_TO_FIFO, SEND_ERROR, SEND_FRAME, APPEND_CRC_AND_SEND,
SEND_MAINTENANCE_READ_RESPONSE_0, SEND_MAINTENANCE_READ_RESPONSE_1,
SEND_MAINTENANCE_WRITE_RESPONSE_0, SEND_MAINTENANCE_WRITE_RESPONSE_1);
signal stateRB, nextStateRB : state_type_RioBrige;
type byteArray8 is array (0 to 7) of std_logic_vector(7 downto 0);
signal dataLane : byteArray8;
-- type byteArray4 is array (0 to 3) of std_logic_vector(7 downto 0);
-- signal dataLaneS : byteArray4;
signal pos, byteOffset : integer range 0 to 7;
signal numberOfByte, byteCnt, headLen : integer range 0 to 256;
signal endianMsb, reserved, ready : std_logic;
signal start : std_logic;
signal wdptr : std_logic;
signal wbStb : std_logic;
signal xamsbs : std_logic_vector(1 downto 0);
signal ftype : std_logic_vector(3 downto 0);
signal ttype : std_logic_vector(3 downto 0);
signal size : std_logic_vector(3 downto 0);
signal tid : std_logic_vector(7 downto 0);
signal tt : std_logic_vector(1 downto 0);
signal errorCode : std_logic_vector(7 downto 0);
signal sourceId : std_logic_vector(15 downto 0);
signal destinationId : std_logic_vector(15 downto 0);
signal writeContentData : std_logic_vector(31 downto 0);
signal crc16Current, crc16Temp, crc16Next: std_logic_vector(15 downto 0);
signal tempAddr : std_logic_vector(25 downto 0);
signal timeOutCnt : std_logic_vector(14 downto 0);
component WriteClassInbound is
generic(
EXTENDED_ADDRESS : natural range 0 to 2 := 0);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
-- Configuration memory signal declaration.
signal configEnable : std_logic;
signal configWrite : std_logic;
signal configAddress : std_logic_vector(23 downto 0);
signal configDataWrite : std_logic_vector(31 downto 0);
signal configDataRead : std_logic_vector(31 downto 0);
signal componentTag : std_logic_vector(31 downto 0);
signal baseDeviceId : std_logic_vector(15 downto 0) := DEFAULT_BASE_DEVICE_ID;
signal hostBaseDeviceIdLocked : std_logic;
signal hostBaseDeviceId : std_logic_vector(15 downto 0) := (others => '1');
ready_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);
address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
length_o : out std_logic_vector(3 downto 0);
select_o : out std_logic_vector(7 downto 0);
payloadSetFirst_i : in std_logic;
payloadSetNext_i : in std_logic;
payload_o : out std_logic_vector(31 downto 0);
done_i : in std_logic;
slaveCyc_i : in std_logic;
slaveStb_i : in std_logic;
slaveAdr_i : in std_logic_vector(7 downto 0);
slaveDat_i : in std_logic_vector(31 downto 0);
slaveAck_o : out std_logic);
end component;
 
begin
wbStb_o <= wbStb;
writeContentData_o <= writeContentData;
component ResponseClassOutbound is
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
Crc16High: Crc16CITT
port map(
d_i=>writeContentData(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp);
Crc16Low: Crc16CITT
port map(
d_i=>writeContentData(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next);
ready_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);
tid_i : in std_logic_vector(7 downto 0);
error_i : in std_logic;
payloadPresent_i : in std_logic;
payloadLength_i : in std_logic_vector(3 downto 0);
payloadWrite_i : in std_logic;
payloadIndex_i : in std_logic_vector(3 downto 0);
payload_i : in std_logic_vector(31 downto 0);
done_o : out std_logic;
masterCyc_o : out std_logic;
masterStb_o : out std_logic;
masterDat_o : out std_logic_vector(31 downto 0);
masterAck_i : in std_logic);
end component;
 
component RioLogicalCommon is
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);
 
masterCyc_o : out std_logic;
masterStb_o : out std_logic;
masterAdr_o : out std_logic_vector(7 downto 0);
masterDat_o : out std_logic_vector(31 downto 0);
masterAck_i : in std_logic;
slaveCyc_i : in std_logic;
slaveStb_i : in std_logic;
slaveDat_i : in std_logic_vector(31 downto 0);
slaveAck_o : out std_logic);
end component;
 
-- signal configStb : std_logic;
-- signal configWe : std_logic;
-- signal configAdr : std_logic_vector(23 downto 0);
-- signal configDatWrite : std_logic_vector(31 downto 0);
-- signal configDatRead : std_logic_vector(31 downto 0);
-- signal configAck : std_logic;
-- signal componentTag : std_logic_vector(31 downto 0);
-- signal baseDeviceId : std_logic_vector(15 downto 0) := DEFAULT_BASE_DEVICE_ID;
-- signal hostBaseDeviceIdLocked : std_logic;
-- signal hostBaseDeviceId : std_logic_vector(15 downto 0) := (others => '1');
 
begin
 
-----------------------------------------------------------------------------
-- wbInterfaceCtrl
-- This process handle the Wishbone interface to the RioWbBridge module.
--
-----------------------------------------------------------------------------
wbInterfaceCtrl: process(clk, areset_n)
variable Temp : std_logic_vector(2 downto 0);
adr_o <= adr;
dat_o <= datOut;
Bridge: process(clk, areset_n)
begin
if areset_n = RST_LVL then
start <= '0';
wdptr <= '0';
wbStb <= '0';
wbWe_o <= '0';
byteCnt <= 0;
headLen <= 0;
byteOffset <= 0;
readFrame_o <= '0';
readContent_o <= '0';
writeFrame_o <= '0';
writeContent_o <= '0';
writeFrameAbort_o <= '0';
configWrite <= '0';
configEnable <= '0';
ready <= '0';
endianMsb <= '0';
stateRB <= IDLE;
nextStateRB <= IDLE;
tt <= (others => '0');
tid <= (others => '0');
size <= (others => '0');
ttype <= (others => '0');
ftype <= (others => '0');
xamsbs <= (others => '0');
sourceId <= (others => '0');
configDataWrite <= (others => '0');
destinationId <= (others => '0');
errorCode <= (others => '0');
tempAddr <= (others => '0');
wbAdr_o <= (others => '0');
wbData_o <= (others => '0');
writeContentData <= (others => '0');
dataLane <= (others =>(others => '0'));
-- dataLaneS <= (others =>(others => '0'));
crc16Current <= (others => '0');
timeOutCnt <= (others => '0');
Temp := (others => '0');
elsif clk'event and clk ='1' then
if (areset_n = '0') then
cyc_o <= '0';
stb_o <= '0';
we_o <= '0';
adr <= (others=>'0');
datOut <= (others=>'0');
 
case stateRB is
responseReadReady <= '0';
responseWriteReady <= '0';
responsePayloadWrite <= '0';
 
requestDone <= '0';
requestPayloadIndex <= (others=>'0');
elsif (clk'event and clk = '1') then
requestDone <= '0';
responsePayloadWrite <= '0';
 
if (responsePayloadWrite = '1') then
responsePayloadIndex <= std_logic_vector(unsigned(responsePayloadIndex) + 1);
end if;
case state is
when IDLE =>
if (readFrameEmpty_i = '0') and (writeFrameFull_i = '0') then
readContent_o <= '1';
byteCnt <= 0;
ready <= '0';
endianMsb <= '1';
timeOutCnt <= (others => '0');
crc16Current <= (others => '1');
stateRB <= WAIT_HEADER_0;
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (requestReady = '1') then
cyc_o <= '1';
stb_o <= '1';
we_o <= '0';
adr <= requestAddress;
responsePayloadPresent <= '1';
state <= REQUEST_CLASS;
elsif (writeReady = '1') then
cyc_o <= '1';
stb_o <= '1';
we_o <= '1';
adr <= writeAddress;
datOut <= writePayload;
writePayloadNext <= '1';
responsePayloadPresent <= '0';
state <= WRITE_CLASS;
end if;
 
when REQUEST_CLASS =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (ack_i = '1') then
responsePayloadWrite <= '1';
if (responsePayloadIndex /= requestPayloadLength) then
adr <= std_logic_vector(unsigned(adr) + 1);
else
requestDone <= '1';
cyc_o <= '0';
stb_o <= '0';
state <= NREAD_RESPONSE;
end if;
-- elsif(err_i = '1') then
-- REMARK: Implement error indication from wb-bus...
end if;
 
when REQUEST_CLASS_RESPONSE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (responseDone = '1') then
responseReadReady <= '0';
state <= IDLE;
else
start <= '0';
readFrame_o <= '0';
readContent_o <= '0';
writeFrame_o <= '0';
writeContent_o <= '0';
writeFrameAbort_o <= '0';
errorCode <= (others => '0');
writeContentData <= (others => '0');
dataLane <= (others =>(others => '0'));
-- dataLaneS <= (others =>(others => '0'));
Temp := (others => '0');
responseReadReady <= '1';
end if;
 
when WAIT_HEADER_0 =>
stateRB <= HEADER_0;
when WRITE_CLASS =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (ack_i = '1') then
responsePayloadWrite <= '1';
 
when HEADER_0 =>
readContent_o <= '1'; -- read the header (frame 0)
tt <= readContentData_i(21 downto 20);
ftype <= readContentData_i(19 downto 16);
destinationId <= readContentData_i(15 downto 0);
stateRB <= HEADER_1;
when HEADER_1 => -- read the header (frame 1)
readContent_o <= '1';
ttype <= readContentData_i(15 downto 12);
size <= readContentData_i(11 downto 8);
tid <= readContentData_i(7 downto 0);
sourceId <= readContentData_i(31 downto 16);
stateRB <= READ_ADDRESS;
if (responsePayloadIndex /= requestPayloadLength) then
adr <= std_logic_vector(unsigned(configAdr) + 1);
datOut <= writePayload;
requestPayloadIndex <= std_logic_vector(unsigned(requestPayloadIndex) + 1);
else
writeDone <= '1';
cyc_o <= '0';
stb_o <= '0';
state <= WRITE_CLASS_RESPONSE;
end if;
end if;
 
when READ_ADDRESS =>
readContent_o <= '0';
wdptr <= readContentData_i(2);
xamsbs <= readContentData_i(1 downto 0);
tempAddr <= readContentData_i(25 downto 3) & "000"; -- Wishbone address bus is 26 bits width
configAddress <= readContentData_i(23 downto 0); -- this line is in case of maintenance pakage (config-offset(21-bits)+wdptr(1-bit)+rsv(2-bits))
stateRB <= CHECK_ERROR;
when WRITE_CLASS_RESPONSE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (responseDone = '1') then
responseWriteReady <= '0';
state <= IDLE;
else
responseWriteReady <= '1';
end if;
 
when CHECK_ERROR =>
byteOffset <= pos; -- first byte position in the first payload
tempAddr <= tempAddr + pos; -- first address
if readContentEnd_i = '1' then -- check if data not valid i the switch buffer
wbStb <= '0';
wbWe_o <= '0';
byteOffset <= 0;
writeFrameAbort_o <= '1'; -- over write the frame with an error frame
errorCode <= BERR_UNKNOWN_DATA; -- not valid data
stateRB <= SEND_ERROR;
when others =>
 
-- check if error in the frame size for write pakage
elsif (reserved = '1') and (ftype = FTYPE_WRITE_CLASS) then
wbStb <= '0';
wbWe_o <= '0';
byteOffset <= 0;
writeFrameAbort_o <= '1'; -- over write the frame with an error frame
errorCode <= BERR_FRAME_SIZE; -- Frame code size error
stateRB <= SEND_ERROR;
end case;
end if;
end process;
-----------------------------------------------------------------------------
--
-----------------------------------------------------------------------------
 
-- type 5 pakage formate, NWRITE transaction (write to peripherals) read payload from the buffer
elsif (ftype = FTYPE_WRITE_CLASS) and (ttype = "0100") and (tt = "01") then
readContent_o <= '1';
stateRB <= READ_FROM_FIFO; -- read the payload
nextStateRB <= SEND_ERROR; -- this is in case not valid data in switch buffer
headLen <= 12;
RequestClassInboundInst: RequestClassInbound
generic map(
EXTENDED_ADDRESS=>EXTENDED_ADDRESS)
port map(
clk=>clk,
areset_n=>areset_n,
enable=>enable,
ready_o=>requestReady,
vc_o=>requestVc,
crf_o=>requestCrf,
prio_o=>requestPrio,
tt_o=>requestTt,
dstId_o=>requestDstId,
srcId_o=>requestSrcId,
tid_o=>requestTid,
address_o=>requestAddress,
length_o=>requestPayloadLength,
select_o=>requestSelect,
done_i=>requestDone,
slaveCyc_i=>inboundCyc,
slaveStb_i=>inboundStb,
slaveAdr_i=>inboundAdr,
slaveDat_i=>inboundDat,
slaveAck_o=>inboundAck);
 
-- Type 2 pakage formate, NREAD transaction, (read from peripherals) write payload to the buffer
elsif (ftype = FTYPE_REQUEST_CLASS) and (ttype = "0100") and (tt = "01") then
writeContent_o <= '1'; -- write the header-0 of the Read Response pakage
writeContentData(15 downto 0) <= sourceId; -- write to the source address
writeContentData(19 downto 16) <= "1101"; -- Response pakage type 13, ftype Response
writeContentData(21 downto 20) <= "01"; -- tt
writeContentData(31 downto 22) <= "0000000000"; -- acckId, vc, cfr, prio
stateRB <= SEND_DONE_0; --
headLen <= 8;
WriteClassInboundInst: WriteClassInbound
generic map(
EXTENDED_ADDRESS=>EXTENDED_ADDRESS)
port map(
clk=>clk,
areset_n=>areset_n,
enable=>enable,
ready_o=>writeReady,
vc_o=>writeVc,
crf_o=>writeCrf,
prio_o=>writePrio,
tt_o=>writeTt,
dstId_o=>writeDstId,
srcId_o=>writeSrcId,
tid_o=>writeTid,
address_o=>writeAddress,
length_o=>writeLength,
select_o=>writeSelect,
payloadSetFirst_i=>writePayloadFirst,
payloadSetNext_i=>writePayloadNext,
payload_o=>writePayload,
done_i=>writeDone,
slaveCyc_i=>inboundCyc_i,
slaveStb_i=>inboundStb_i,
slaveAdr_i=>inboundAdr_i,
slaveDat_i=>inboundDat_i,
slaveAck_o=>inboundAck_o);
 
-- Type 8 pakage formate, maintenance Read request
elsif (ftype = FTYPE_MAINTENANCE_CLASS) and (ttype = TTYPE_MAINTENANCE_READ_REQUEST) and (tt = "01") then
configWrite <= '0'; -- read config operation
configEnable <= '1'; -- enable signal to the memoryConfig process
writeContent_o <= '1';
-- write the header-0 of the Read Response pakage
writeContentData(15 downto 0) <= sourceId; -- write to the source address, this is a response pakage
writeContentData(19 downto 16) <= FTYPE_MAINTENANCE_CLASS; -- ftype, maintenance
writeContentData(21 downto 20) <= "01"; -- tt
writeContentData(31 downto 22) <= "0000000000"; -- acckId, vc, cfr, prio
stateRB <= SEND_MAINTENANCE_READ_RESPONSE_0;
ResponseClassOutboundInst: ResponseClassOutbound
port map(
clk=>clk,
areset_n=>areset_n,
enable=>enable,
ready_i=>responseReady,
vc_i=>vc,
crf_i=>crf,
prio_i=>prio,
tt_i=>tt,
dstid_i=>srcid,
srcid_i=>dstid,
tid_i=>tid,
error_i=>responseError,
payloadPresent_i=>responsePayloadPresent,
payloadLength_i=>responsePayloadLength,
payloadWrite_i=>responsePayloadWrite,
payloadIndex_i=>responsePayloadIndex,
payload_i=>responsePayload,
done_o=>responseDone,
masterCyc_o=>outboundCyc,
masterStb_o=>outboundStb,
masterDat_o=>outboundDat,
masterAck_i=>outboundAck);
RioLogicalCommonInst: RioLogicalCommon
port map(
clk=>clk,
areset_n=>areset_n,
enable=>enable,
readFrameEmpty_i=>readFrameEmpty_i,
readFrame_o=>readFrame_o,
readContent_o=>readContent_o,
readContentEnd_i=>readContentEnd_i,
readContentData_i=>readContentData_i,
writeFrameFull_i=>writeFrameFull_i,
writeFrame_o=>writeFrame_o,
writeFrameAbort_o=>writeFrameAbort_o,
writeContent_o=>writeContent_o,
writeContentData_o=>writeContentData_o,
masterCyc_o=>inboundCyc,
masterStb_o=>inboundStb,
masterAdr_o=>inboundAdr,
masterDat_o=>inboundDat,
masterAck_i=>inboundAck,
slaveCyc_i=>outboundCyc,
slaveStb_i=>outboundStb,
slaveDat_i=>outboundDat,
slaveAck_o=>outboundAck);
 
-- Type 8 pakage formate, maintenance Write request
elsif (ftype = FTYPE_MAINTENANCE_CLASS) and (ttype = TTYPE_MAINTENANCE_WRITE_REQUEST) and (tt = "01") then
configWrite <= '1'; -- write config operation
writeContent_o <= '1'; -- write the header-0
writeContentData(15 downto 0) <= sourceId; -- write to the source address, this is a response pakage
writeContentData(19 downto 16) <= FTYPE_MAINTENANCE_CLASS; -- ftype, maintenance
writeContentData(21 downto 20) <= "01"; -- tt
writeContentData(31 downto 22) <= "0000000000"; -- acckId, vc, cfr, prio
stateRB <= SEND_MAINTENANCE_WRITE_RESPONSE_0;
-----------------------------------------------------------------------------
-- Configuration memory.
-----------------------------------------------------------------------------
-- memoryConfig : process(clk, areset_n)
-- begin
-- if (areset_n = '0') then
-- configDataRead <= (others => '0');
-- baseDeviceId <= DEFAULT_BASE_DEVICE_ID;
-- componentTag <= (others => '0');
-- hostBaseDeviceIdLocked <= '0';
-- hostBaseDeviceId <= (others => '1');
-- elsif (clk'event and clk = '1') then
 
-- Error: unexpected ftype or ttype
else
wbStb <= '0';
wbWe_o <= '0';
byteOffset <= 0;
writeFrameAbort_o <= '1'; -- over write the frame with an error frame
errorCode <= BERR_FRAME_CODE;
stateRB <= SEND_ERROR; -- next state after the dataLane is stored in the switch buffer
end if;
-- if (configEnable = '1') then
-- case (configAddress) is
-- when x"000000" =>
-- -- Device Identity CAR. Read-only.
-- configDataRead(31 downto 16) <= DEVICE_IDENTITY;
-- configDataRead(15 downto 0) <= DEVICE_VENDOR_IDENTITY;
-- when x"000004" =>
-- -- Device Information CAR. Read-only.
-- configDataRead(31 downto 0) <= DEVICE_REV;
-- when x"000008" =>
-- -- Assembly Identity CAR. Read-only.
-- configDataRead(31 downto 16) <= ASSY_IDENTITY;
-- configDataRead(15 downto 0) <= ASSY_VENDOR_IDENTITY;
-- when x"00000c" =>
-- -- Assembly Informaiton CAR. Read-only.
-- -- Extended features pointer to "0000".
-- configDataRead(31 downto 16) <= ASSY_REV;
-- configDataRead(15 downto 0) <= x"0000";
-- when x"000010" =>
-- -- Processing Element Features CAR. Read-only.
-- -- Bridge(31), Memory(30), Processor(29), Switch(28).
-- configDataRead(31) <= '1';
-- configDataRead(30 downto 4) <= (others => '0');
-- configDataRead(3) <= '1'; -- support 16 bits common transport large system
-- configDataRead(2 downto 0) <= "001"; -- support 34 bits address
-- when x"000018" =>
-- -- Source Operations CAR. Read-only.
-- configDataRead(31 downto 0) <= (others => '0');
-- when x"00001C" =>
-- -- Destination Operations CAR. Read-only.
-- configDataRead(31 downto 16) <= (others => '0');
-- configDataRead(15) <= '1';
-- configDataRead(14) <= '1';
-- configDataRead(13 downto 0) <= (others => '0');
-- when x"00004C" =>
-- -- Processing Element Logical Layer Control CSR.
-- configDataRead(31 downto 3) <= (others => '0');
-- configDataRead(2 downto 0) <= "001"; -- support 34 bits address
-- when x"000060" =>
-- -- Base Device ID CSR.
-- -- Only valid for end point devices.
-- if (configWrite = '1') then
-- baseDeviceId <= configDataWrite(15 downto 0);
-- else
-- configDataRead(15 downto 0) <= baseDeviceId;
-- end if;
-- when x"000068" =>
-- -- Host Base Device ID Lock CSR.
-- if (configWrite = '1') then
-- -- Check if this field has been written before.
-- if (hostBaseDeviceIdLocked = '0') then
-- -- The field has not been written.
-- -- Lock the field and set the host base device id.
-- hostBaseDeviceIdLocked <= '1';
-- hostBaseDeviceId <= configDataWrite(15 downto 0);
-- else
-- -- The field has been written.
-- -- Check if the written data is the same as the stored.
-- if (hostBaseDeviceId = configDataWrite(15 downto 0)) then
-- -- Same as stored, reset the value to its initial value.
-- hostBaseDeviceIdLocked <= '0';
-- hostBaseDeviceId <= (others => '1');
-- else
-- -- Not writing the same as the stored value.
-- -- Ignore the write.
-- end if;
-- end if;
-- else
-- configDataRead(31 downto 16) <= (others => '0');
-- configDataRead(15 downto 0) <= hostBaseDeviceId;
-- end if;
-- when x"00006C" =>
-- -- Component TAG CSR.
-- if (configWrite = '1') then
-- componentTag <= configDataWrite;
-- else
-- configDataRead <= componentTag;
-- end if;
 
when SEND_MAINTENANCE_READ_RESPONSE_0 =>
byteCnt <= 0;
configEnable <= '0'; -- disable signal to the memoryConfig process
-- write the header-1 of the Read Response pakage
writeContentData(7 downto 0) <= tid;
writeContentData(11 downto 8) <= "0000"; -- size/status
writeContentData(15 downto 12) <= TTYPE_MAINTENANCE_READ_RESPONSE; -- transaction type, Maintenance Read Response
writeContentData(31 downto 16) <= baseDeviceId; -- destination address, because this is a response pakage
crc16Current <= crc16Next; -- first frame's CRC
stateRB <= SEND_MAINTENANCE_READ_RESPONSE_1;
-- when others =>
-- configDataRead <= (others => '0');
-- end case;
-- else
-- -- Config memory not enabled.
-- end if;
-- end if;
-- end process;
 
when SEND_MAINTENANCE_READ_RESPONSE_1 =>
byteCnt <= byteCnt + 1; -- using byteCnt as a counter
if byteCnt = 0 then
writeContentData <= X"FF" & X"000000"; -- write the filed with HOP + reserved
crc16Current <= crc16Next; -- second frame's CRC
elsif byteCnt = 1 then
if configAddress(2) = '0' then -- check the wdptr bit in the config offset field
writeContentData <= configDataRead; -- write payload-0 with data if wdptr='0'
else
writeContentData <= (others => '0'); -- write zeros
end if;
crc16Current <= crc16Next; -- third frame's CRC
elsif byteCnt = 2 then
if configAddress(2) = '0' then -- check the wdptr bit in the config offset field
writeContentData <= (others => '0'); -- write zeros
else
writeContentData <= configDataRead; -- write payload-1 with data if wdptr='1'
end if;
crc16Current <= crc16Next; -- forth frame's CRC
elsif byteCnt = 3 then
writeContentData <= crc16Next & X"0000"; -- write the CRC field
else
writeContent_o <= '0';
stateRB <= SEND_FRAME;
end if;
end architecture;
 
when SEND_MAINTENANCE_WRITE_RESPONSE_0 =>
byteCnt <= 0;
readContent_o <= '1'; -- read the config offset
if configAddress(2) = '0' then -- check the wdptr bit in the config offset field
configDataWrite <= readContentData_i; -- copy payload-0 if wdptr='0'
else
configDataWrite <= configDataWrite; -- do nothing
end if;
writeContentData(7 downto 0) <= tid;
writeContentData(11 downto 8) <= "0000"; -- size/status
writeContentData(15 downto 12) <= TTYPE_MAINTENANCE_WRITE_RESPONSE; -- transaction type, Maintenance Write Response
writeContentData(31 downto 16) <= baseDeviceId; -- destination address, because this is a response pakage
crc16Current <= crc16Next; -- first frame's CRC
stateRB <= SEND_MAINTENANCE_WRITE_RESPONSE_1;
 
when SEND_MAINTENANCE_WRITE_RESPONSE_1 =>
byteCnt <= byteCnt + 1; -- using byteCnt as a counter
if byteCnt = 0 then
writeContentData <= X"FF" & X"000000"; -- write the filed with HOP + reserved
crc16Current <= crc16Next; -- second frame's CRC
elsif byteCnt = 1 then
configEnable <= '1'; -- enable signal to the memoryConfig process
writeContentData <= crc16Next & X"0000"; -- write the CRC field
if configAddress(2) = '0' then -- check the wdptr bit in the config offset field
configDataWrite <= configDataWrite; -- do nothing
else
configDataWrite <= readContentData_i; -- copy payload-1 if wdptr='1'
end if;
else
configEnable <= '0'; -- disable signal to the memoryConfig process
readContent_o <= '0'; -- at this point even the frame's CRC is read from the buffer
writeContent_o <= '0';
stateRB <= SEND_FRAME;
end if;
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
-- REMARK: Extended addresses are not supported yet...
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
when SEND_DONE_0 =>
writeContent_o <= '1';
writeContentData(7 downto 0) <= tid;
writeContentData(11 downto 8) <= "0000"; -- size/status
writeContentData(15 downto 12) <= "1000"; -- ttype
writeContentData(31 downto 16) <= baseDeviceId;
crc16Current <= crc16Next; -- first frame's CRC
stateRB <= SEND_DONE_1;
 
when SEND_DONE_1 =>
byteCnt <= 0;
dataLane <= (others =>(others => '0'));
writeContent_o <= '0'; -- this line is to make sure that the CRC is complete read
crc16Current <= crc16Next; -- second frame's CRC
wbAdr_o <= tempAddr;
tempAddr <= tempAddr + 1;
wbStb <= '1';
wbWe_o <= '0';
byteOffset <= pos;
stateRB <= READ_FROM_WB;
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
entity RequestClassInbound is
generic(
EXTENDED_ADDRESS : natural range 0 to 2 := 0);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
when READ_FROM_WB =>
if wbAck_i = '1' then
timeOutCnt <= (others => '0'); -- reset the time out conter
if wbErr_i = '0' then -- check if no error occur
if (byteCnt < numberOfByte - 1) then -- check if reach the last data byte
byteCnt <= byteCnt + 1;
if (byteCnt + headLen = 80) then -- when current position in payload is a CRC position
dataLane(0) <= crc16Current(15 downto 8);
dataLane(1) <= crc16Current(7 downto 0);
dataLane(2) <= wbData_i;
byteOffset <= 3;
elsif byteOffset < 7 then
dataLane(byteOffset) <= wbData_i;
byteOffset <= byteOffset + 1;
else -- dataLane vector is ready to send to fifo
dataLane(7) <= wbData_i;
byteOffset <= 0; -- Here, sets byteOffset for other response
stateRB <= SEND_TO_FIFO;
nextStateRB <= READ_FROM_WB; --
ready_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);
address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
length_o : out std_logic_vector(3 downto 0);
select_o : out std_logic_vector(7 downto 0);
done_i : in std_logic;
slaveCyc_i : in std_logic;
slaveStb_i : in std_logic;
slaveAdr_i : in std_logic_vector(7 downto 0);
slaveDat_i : in std_logic_vector(31 downto 0);
slaveAck_o : out std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture RequestClassInbound of RequestClassInbound is
type StateType is (RECEIVE_PACKET, READY);
signal state : StateType;
 
signal rdsize : std_logic_vector(3 downto 0);
signal wdptr : std_logic;
 
signal slaveAck : std_logic;
signal complete : std_logic;
 
signal packetIndex : natural range 0 to 68;
 
begin
 
slaveAck_o <= slaveAck;
 
ready_o <= complete when (state = READY) else '0';
 
RequestClass: process(clk, areset_n)
begin
if (areset_n = '0') then
slaveAck <= '0';
 
complete <= '0';
vc_o <= '0';
crf_o <= '0';
prio_o <= "00";
tt_o <= "00";
address_o <= (others=>'0');
 
rdsize <= (others=>'0');
wdptr <= '0';
packetIndex <= 0;
elsif (clk'event and clk = '1') then
case state is
when RECEIVE_PACKET =>
---------------------------------------------------------------------
-- This state waits for a new REQUEST class packet, receives it
-- and parses it.
---------------------------------------------------------------------
if (slaveCyc_i = '1') then
if (slaveAck = '0') then
if (slaveStb_i = '1') then
if (slaveAdr_i = x"24") then
-------------------------------------------------------------
-- NREAD packet parser.
-------------------------------------------------------------
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
vc_o <= slaveDat_i(9);
crf_o <= slaveDat_i(8);
prio_o <= slaveDat_i(7 downto 6);
tt_o <= slaveDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- dstid
dstId_o <= slaveDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcid
srcId_o <= slaveDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction(3:0) & rdsize(3:0) & srcTID(7:0) & address(28:13)
-- REMARK: Add support for extended addresses here...
rdsize <= slaveDat_i(27 downto 24);
tid_o <= slaveDat_i(23 downto 16);
address_o(28 downto 13) <= slaveDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
when 4 =>
-- address(12:0) & wdptr & xamsbs(1:0) & crc(15:0)
address_o(12 downto 0) <= slaveDat_i(31 downto 19);
wdptr <= slaveDat_i(18);
address_o(30 downto 29) <= slaveDat_i(17 downto 16);
packetIndex <= packetIndex + 1;
complete <= '1';
when others =>
-- There should be no more content in an NREAD.
-- Discard.
end case;
end if;
else -- get last data from Wishbone
wbStb <= '0';
byteCnt <= 0; -- Here, using byteCnt and reset it for other response
dataLane(byteOffset) <= wbData_i;
stateRB <= APPEND_CRC_AND_SEND;
if byteOffset < 7 then -- checking for CRC appending position
byteOffset <= byteOffset + 1;
else
byteOffset <= 0;
end if;
slaveAck <= '1';
end if;
 
-- when Wishbone error occur
else
wbStb <= '0';
wbWe_o <= '0';
byteOffset <= 0;
writeFrameAbort_o <= '1'; -- over write the frame with an error frame
errorCode <= wbData_i;
stateRB <= SEND_ERROR;
slaveAck <= '0';
end if;
else -- when no acknowledge received
if timeOutCnt(13) = '1' then -- when waiting more than 1 ms for response from the device
wbStb <= '0';
wbWe_o <= '0';
byteOffset <= 0;
writeFrameAbort_o <= '1'; -- over write the frame with an error frame
errorCode <= BERR_NOT_RESPONSE;
stateRB <= SEND_ERROR;
else
timeOutCnt <= timeOutCnt + 1;
end if;
end if;
 
-- appending CRC and write to the fifo when frame is shorter then 80 bytes
when APPEND_CRC_AND_SEND =>
writeContent_o <= '0';
byteCnt <= byteCnt + 1;
-- check if frame is shorter than 80 bytes
if (numberOfByte < 65) then
-- Yes, frame is shorter then 80 bytes
if byteCnt = 0 then
-- first write the current double word to the fifo
-- then put the CRC in the next double word
byteOffset <= 0;
stateRB <= SEND_TO_FIFO;
nextStateRB <= APPEND_CRC_AND_SEND;
elsif byteCnt = 1 then
-- append the CRC
writeContent_o <= '1';
writeContentData <= crc16Current & X"0000";
else
stateRB <= SEND_FRAME; -- store in the switch buffer
end if;
else
--No, appending CRC and write to the fifo when frame is longer then 80 bytes
if byteCnt = 0 then
-- check if the last byte was placed in the second half of the double word,
-- in that case write the first word to the fifo.
writeContentData <= dataLane(0) & dataLane(1) & dataLane(2) & dataLane(3);
elsif byteCnt = 1 then
crc16Current <= crc16Temp; -- calcylate the crc for the 16 most significant bits
elsif byteCnt = 2 then
writeContent_o <= '1';
writeContentData <= dataLane(0) & dataLane(1) & crc16Current;
else
stateRB <= SEND_FRAME; -- store in the switch buffer
if (complete = '1') then
state <= READY;
end if;
packetIndex <= 0;
end if;
 
 
when SEND_TO_FIFO =>
if byteOffset = 0 then -- using byteOffset as a counter
byteOffset <= 1;
writeContent_o <= '1';
writeContentData <= dataLane(0) & dataLane(1) & dataLane(2) & dataLane(3);
elsif byteOffset = 1 then -- using byteOffset as a counter
byteOffset <= 2;
writeContent_o <= '0';
crc16Current <= crc16Next; -- calcylate the crc
elsif byteOffset = 2 then
byteOffset <= 3;
writeContent_o <= '1';
writeContentData <= dataLane(4) & dataLane(5) & dataLane(6) & dataLane(7);
elsif byteOffset = 3 then
crc16Current <= crc16Next; -- calcylate the crc
writeContent_o <= '0';
byteOffset <= 0;
stateRB <= nextStateRB;
dataLane <= (others =>(others => '0'));
when READY =>
---------------------------------------------------------------------
-- Wait for the handler of the packet to signal that it has been
-- processed.
---------------------------------------------------------------------
if (done_i = '1') then
complete <= '0';
state <= RECEIVE_PACKET;
end if;
when READ_FROM_FIFO =>
if (endianMsb = '1') then
if (readContentEnd_i = '0') then
endianMsb <= '0';
dataLane(0 to 3) <= (readContentData_i(31 downto 24), readContentData_i(23 downto 16),
readContentData_i(15 downto 8), readContentData_i(7 downto 0));
else
wbStb <= '0';
wbWe_o <= '0';
byteOffset <= 0;
readContent_o <= '0';
writeFrameAbort_o <= '1'; -- over write the frame with an error frame
errorCode <= BERR_FRAME_SIZE;
stateRB <= SEND_ERROR;
-- stateRB <= IDLE;
end if;
else
endianMsb <= '1';
readContent_o <= '0';
dataLane(4 to 7) <= (readContentData_i(31 downto 24), readContentData_i(23 downto 16),
readContentData_i(15 downto 8), readContentData_i(7 downto 0));
if ready = '1' then
stateRB <= nextStateRB;
else
stateRB <= WRITE_TO_WB;
end if;
end if;
when others =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
 
when WRITE_TO_WB =>
if wbStb = '0' then
wbStb <= '1';
wbWe_o <= '1';
byteCnt <= 1;
byteOffset <= byteOffset + 1; -- increase number of counted byte
tempAddr <= tempAddr + 1; -- increase the memory sddress address
wbAdr_o <= tempAddr;
wbData_o <= dataLane(byteOffset);
else
if wbAck_i = '1' then
timeOutCnt <= (others => '0'); -- reset the time out conter
if wbErr_i = '0' then -- check the peripherals error signal
if byteCnt < numberOfByte then
tempAddr <= tempAddr + 1; -- increase the memory sddress address
wbAdr_o <= tempAddr;
wbData_o <= dataLane(byteOffset);
byteCnt <= byteCnt + 1; -- increase number of counted byte
if byteOffset < 7 then
if (byteCnt + headLen = 79) then -- check for the CRC-byte position 80 in the frame
byteOffset <= byteOffset + 3;
else
byteOffset <= byteOffset + 1;
end if;
else
if (byteCnt + headLen = 79) then -- check for the CRC-byte position 80 in the frame
byteOffset <= 2;
else
byteOffset <= 0;
end if;
if byteCnt < numberOfByte - 1 then
readContent_o <= '1';
stateRB <= READ_FROM_FIFO;
end if;
end if;
else -- no more data to send to the peripherals
wbStb <= '0';
wbWe_o <= '0';
ready <= '1';
stateRB <= SEND_FRAME;
end case;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Transformation of rdsize and wdptr into length of access and byte lanes.
-----------------------------------------------------------------------------
process(clk, areset_n)
begin
if (areset_n = '0') then
length_o <= 0;
select_o <= (others=>'0');
elsif (clk'event and clk = '1') then
if (complete = '1') then
if (wdptr = '0') then
case rdsize is
when "0000" =>
length_o <= 0;
select_o <= "10000000";
when "0001" =>
length_o <= 0;
select_o <= "01000000";
when "0010" =>
length_o <= 0;
select_o <= "00100000";
when "0011" =>
length_o <= 0;
select_o <= "00010000";
when "0100" =>
length_o <= 0;
select_o <= "11000000";
when "0101" =>
length_o <= 0;
select_o <= "11100000";
when "0110" =>
length_o <= 0;
select_o <= "00110000";
when "0111" =>
length_o <= 0;
select_o <= "11111000";
when "1000" =>
length_o <= 0;
select_o <= "11110000";
when "1001" =>
length_o <= 0;
select_o <= "11111100";
when "1010" =>
length_o <= 0;
select_o <= "11111110";
when "1011" =>
length_o <= 0;
select_o <= "11111111";
when "1100" =>
length_o <= 3;
select_o <= "11111111";
when "1101" =>
length_o <= 11;
select_o <= "11111111";
when "1110" =>
length_o <= 19;
select_o <= "11111111";
when others =>
length_o <= 27;
select_o <= "11111111";
end case;
else
case rdsize is
when "0000" =>
length_o <= 0;
select_o <= "00001000";
when "0001" =>
length_o <= 0;
select_o <= "00000100";
when "0010" =>
length_o <= 0;
select_o <= "00000010";
when "0011" =>
length_o <= 0;
select_o <= "00000001";
when "0100" =>
length_o <= 0;
select_o <= "00001100";
when "0101" =>
length_o <= 0;
select_o <= "00000111";
when "0110" =>
length_o <= 0;
select_o <= "00000011";
when "0111" =>
length_o <= 0;
select_o <= "00011111";
when "1000" =>
length_o <= 0;
select_o <= "00001111";
when "1001" =>
length_o <= 0;
select_o <= "00111111";
when "1010" =>
length_o <= 0;
select_o <= "01111111";
when "1011" =>
length_o <= 1;
select_o <= "11111111";
when "1100" =>
length_o <= 7;
select_o <= "11111111";
when "1101" =>
length_o <= 15;
select_o <= "11111111";
when "1110" =>
length_o <= 23;
select_o <= "11111111";
when others =>
length_o <= 31;
select_o <= "11111111";
end case;
end if;
end if;
end if;
end process;
 
end architecture;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
-- REMARK: Support inbound data with full bandwidth, not just half...
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
entity WriteClassInbound is
generic(
EXTENDED_ADDRESS : natural range 0 to 2 := 0);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
ready_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);
address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
length_o : out std_logic_vector(3 downto 0);
select_o : out std_logic_vector(7 downto 0);
payloadSetFirst_i : in std_logic;
payloadSetNext_i : in std_logic;
payload_o : out std_logic_vector(31 downto 0);
done_i : in std_logic;
slaveCyc_i : in std_logic;
slaveStb_i : in std_logic;
slaveAdr_i : in std_logic_vector(7 downto 0);
slaveDat_i : in std_logic_vector(31 downto 0);
slaveAck_o : out std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture WriteClassInbound of WriteClassInbound 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 wrsize : std_logic_vector(3 downto 0);
 
signal slaveAck : std_logic;
signal complete : std_logic;
 
signal packetIndex : natural range 0 to 68;
signal requestData : std_logic_vector(31 downto 0);
 
signal payloadIndex : std_logic_vector(4 downto 0);
signal memoryWrite : std_logic;
signal memoryAddress : std_logic_vector(4 downto 0);
signal memoryDataIn : std_logic_vector(63 downto 0);
 
begin
 
slaveAck_o <= slaveAck;
 
ready_o <= complete when (state = READY) else '0';
 
WriteClass: process(clk, areset_n)
begin
if (areset_n = '0') then
slaveAck <= '0';
 
complete <= '0';
vc_o <= '0';
crf_o <= '0';
prio_o <= "00";
tt_o <= "00";
tid_o <= (others=>'0');
address_o <= (others=>'0');
wdptr <= '0';
wrsize <= (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 WRITE class packet, receives it
-- and parses it.
---------------------------------------------------------------------
if (slaveCyc_i = '1') then
if (slaveAck = '0') then
if (slaveStb_i = '1') then
if (slaveAdr_i = x"55") then
-------------------------------------------------------------
-- NWRITER packet parser.
-------------------------------------------------------------
-- REMARK: Add support for NWRITE without response...
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
vc_o <= slaveDat_i(9);
crf_o <= slaveDat_i(8);
prio_o <= slaveDat_i(7 downto 6);
tt_o <= slaveDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- destId
dstId_o <= slaveDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcId
srcId_o <= slaveDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & wrsize & srcTID & address(28:13)
-- REMARK: Add support for extended addresses here...
wrsize <= slaveDat_i(27 downto 24);
tid_o <= slaveDat_i(23 downto 16);
address_o(28 downto 13) <= slaveDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
when 4 =>
-- address(12:0) & wdptr & xamsbs(1:0) & double-word(63:48)
address_o(12 downto 0) <= slaveDat_i(31 downto 19);
wdptr <= slaveDat_i(18);
doubleWord(63 downto 48) <= slaveDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 33 | 35 |
37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 59 | 61 | 63 | 65 | 67 =>
-- double-word(47:16)
doubleWord(31 downto 16) <= slaveDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 |
36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 =>
-- double-word(15:0) & double-word(63:48)
doubleWord(63 downto 48) <= slaveDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
 
memoryWrite <= '1';
memoryDataIn <= doubleWord(63 downto 16) & slaveDat_i(31 downto 16);
complete <= '1';
when others =>
-- There should be no more content in an NWRITE request.
-- Discard.
end case;
end if;
else -- if the peripheral generates an error, send an error Response
wbStb <= '0';
wbWe_o <= '0';
byteOffset <= 0;
writeFrameAbort_o <= '1'; -- over write the frame with an error frame
errorCode <= wbData_i;
stateRB <= SEND_ERROR;
slaveAck <= '1';
end if;
else
-- if readContentEnd_i = '1' then -- when unvalid data in the switch buffer
-- wbStb <= '0';
-- wbWe_o <= '0';
-- readFrame_o <= '1';
-- byteOffset <= 0;
-- writeFrameAbort_o <= '1'; -- over write the frame with an error frame
-- errorCode <= BERR_FRAME_SIZE; -- more data content is expected, Frame size error
-- stateRB <= SEND_ERROR;
-- else
if timeOutCnt(13) = '1' then -- when waiting more than 1 ms for response from the device
wbStb <= '0';
wbWe_o <= '0';
readFrame_o <= '1';
byteOffset <= 0;
writeFrameAbort_o <= '1'; -- over write the frame with an error frame
errorCode <= BERR_NOT_RESPONSE;
stateRB <= SEND_ERROR;
else
timeOutCnt <= timeOutCnt + 1;
end if;
-- end if;
if (memoryWrite = '1') then
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
end if;
memoryWrite <= '0';
slaveAck <= '0';
end if;
end if;
 
when SEND_ERROR => -- Generate a Response Class, an error pakage ftype=13, ttype=8, status="1111"
readFrame_o <= '0';
writeFrameAbort_o <= '0';
byteOffset <= byteOffset + 1;
if byteOffset = 0 then
writeContent_o <= '1'; -- start write to the buffer
crc16Current <= (others => '1');
writeContentData <= "00000000" & "00" & "01" & "1101" & sourceId;
elsif byteOffset = 1 then
writeContentData <= baseDeviceId & "1000" & "1111" & tid;
crc16Current <= crc16Next; -- first frame's CRC
elsif byteOffset = 2 then
writeContentData <= errorCode & x"000000";
crc16Current <= crc16Next; -- second frame's CRC
elsif byteOffset = 3 then
writeContentData <= x"00000000";
crc16Current <= crc16Next; -- third frame's CRC
elsif byteOffset = 4 then
writeContentData <= crc16Next & X"0000"; -- write the CRC field
else
writeContent_o <= '0';
writeFrame_o <= '1';
readFrame_o <= '1';
stateRB <= WAIT_IDLE;
if (complete = '1') then
state <= READY;
end if;
packetIndex <= 0;
memoryAddress <= (others=>'0');
end if;
 
when SEND_FRAME =>
if (ftype = FTYPE_WRITE_CLASS) and (ttype = TTYPE_NWRITE_TRANSACTION) and (tt = "01") then -- check what type of pakage we got
readFrame_o <= '1';
elsif (ftype = FTYPE_REQUEST_CLASS) and (ttype = TTYPE_NREAD_TRANSACTION) and (tt = "01") then -- write payload to the buffer is done
readFrame_o <= '1';
writeFrame_o <= '1';
else -- the operation was not valid
readFrame_o <= '1';
writeFrame_o <= '1';
when READY =>
---------------------------------------------------------------------
-- Wait for the handler of the packet to signal that it has been
-- processed.
---------------------------------------------------------------------
if (done_i = '1') then
complete <= '0';
state <= RECEIVE_PACKET;
end if;
stateRB <= WAIT_IDLE;
when WAIT_IDLE =>
readFrame_o <= '0';
writeFrame_o <= '0';
readContent_o <= '0'; -- this line is to make sure that the CRC is complete read
stateRB <= IDLE;
 
when others =>
stateRB <= IDLE;
---------------------------------------------------------------------
--
---------------------------------------------------------------------
 
end case;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Transformation of wrsize and wdptr into length of access and byte lanes.
-----------------------------------------------------------------------------
process(clk, areset_n)
begin
if (areset_n = '0') then
length_o <= 0;
select_o <= (others=>'0');
elsif (clk'event and clk = '1') then
if (complete = '1') then
if (wdptr = '0') then
case wrsize is
when "0000" =>
length_o <= 0;
select_o <= "10000000";
when "0001" =>
length_o <= 0;
select_o <= "01000000";
when "0010" =>
length_o <= 0;
select_o <= "00100000";
when "0011" =>
length_o <= 0;
select_o <= "00010000";
when "0100" =>
length_o <= 0;
select_o <= "11000000";
when "0101" =>
length_o <= 0;
select_o <= "11100000";
when "0110" =>
length_o <= 0;
select_o <= "00110000";
when "0111" =>
length_o <= 0;
select_o <= "11111000";
when "1000" =>
length_o <= 0;
select_o <= "11110000";
when "1001" =>
length_o <= 0;
select_o <= "11111100";
when "1010" =>
length_o <= 0;
select_o <= "11111110";
when "1011" =>
length_o <= 0;
select_o <= "11111111";
when others =>
length_o <= memoryAddress;
select_o <= "11111111";
end case;
else
case wrsize is
when "0000" =>
length_o <= 0;
select_o <= "00001000";
when "0001" =>
length_o <= 0;
select_o <= "00000100";
when "0010" =>
length_o <= 0;
select_o <= "00000010";
when "0011" =>
length_o <= 0;
select_o <= "00000001";
when "0100" =>
length_o <= 0;
select_o <= "00001100";
when "0101" =>
length_o <= 0;
select_o <= "00000111";
when "0110" =>
length_o <= 0;
select_o <= "00000011";
when "0111" =>
length_o <= 0;
select_o <= "00011111";
when "1000" =>
length_o <= 0;
select_o <= "00001111";
when "1001" =>
length_o <= 0;
select_o <= "00111111";
when "1010" =>
length_o <= 0;
select_o <= "01111111";
when others =>
length_o <= memoryAddress;
select_o <= "11111111";
end case;
end if;
end if;
end if;
end process;
 
end process;
 
-----------------------------------------------------------------------------
-- Configuration memory.
-- Payload content memory.
-----------------------------------------------------------------------------
memoryConfig : process(clk, areset_n)
process(clk, areset_n)
begin
if (areset_n = '0') then
configDataRead <= (others => '0');
baseDeviceId <= DEFAULT_BASE_DEVICE_ID;
componentTag <= (others => '0');
hostBaseDeviceIdLocked <= '0';
hostBaseDeviceId <= (others => '1');
payloadIndex <= (others=>'0');
elsif (clk'event and clk = '1') then
if (payloadSetFirst_i = '1') then
payloadIndex <= (others=>'0');
elsif (payloadSetNext_i = '1') then
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
end if;
end if;
end process;
PayloadMemory: MemorySimpleDualPort
generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>64)
port map(clkA_i=>clk,
enableA_i=>memoryWrite,
addressA_i=>memoryAddress,
dataA_i=>memoryDataIn,
clkB_i=>clk,
enableB_i=>enable,
addressB_i=>payloadIndex,
dataB_o=>payload_o);
 
if (configEnable = '1') then
case (configAddress) is
when x"000000" =>
-- Device Identity CAR. Read-only.
configDataRead(31 downto 16) <= DEVICE_IDENTITY;
configDataRead(15 downto 0) <= DEVICE_VENDOR_IDENTITY;
when x"000004" =>
-- Device Information CAR. Read-only.
configDataRead(31 downto 0) <= DEVICE_REV;
when x"000008" =>
-- Assembly Identity CAR. Read-only.
configDataRead(31 downto 16) <= ASSY_IDENTITY;
configDataRead(15 downto 0) <= ASSY_VENDOR_IDENTITY;
when x"00000c" =>
-- Assembly Informaiton CAR. Read-only.
-- Extended features pointer to "0000".
configDataRead(31 downto 16) <= ASSY_REV;
configDataRead(15 downto 0) <= x"0000";
when x"000010" =>
-- Processing Element Features CAR. Read-only.
-- Bridge(31), Memory(30), Processor(29), Switch(28).
configDataRead(31) <= '1';
configDataRead(30 downto 4) <= (others => '0');
configDataRead(3) <= '1'; -- support 16 bits common transport large system
configDataRead(2 downto 0) <= "001"; -- support 34 bits address
when x"000018" =>
-- Source Operations CAR. Read-only.
configDataRead(31 downto 0) <= (others => '0');
when x"00001C" =>
-- Destination Operations CAR. Read-only.
configDataRead(31 downto 16) <= (others => '0');
configDataRead(15) <= '1';
configDataRead(14) <= '1';
configDataRead(13 downto 0) <= (others => '0');
when x"00004C" =>
-- Processing Element Logical Layer Control CSR.
configDataRead(31 downto 3) <= (others => '0');
configDataRead(2 downto 0) <= "001"; -- support 34 bits address
when x"000060" =>
-- Base Device ID CSR.
-- Only valid for end point devices.
if (configWrite = '1') then
baseDeviceId <= configDataWrite(15 downto 0);
else
configDataRead(15 downto 0) <= baseDeviceId;
end architecture;
 
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
entity ResponseClassOutbound is
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
ready_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);
tid_i : in std_logic_vector(7 downto 0);
error_i : in std_logic;
payloadPresent_i : in std_logic;
payloadLength_i : in std_logic_vector(3 downto 0);
payloadWrite_i : in std_logic;
payloadIndex_i : in std_logic_vector(3 downto 0);
payload_i : in std_logic_vector(31 downto 0);
done_o : out std_logic;
masterCyc_o : out std_logic;
masterStb_o : out std_logic;
masterDat_o : out std_logic_vector(31 downto 0);
masterAck_i : in std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture ResponseClassOutbound of ResponseClassOutbound 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 65;
signal header : std_logic_vector(31 downto 0);
signal payload : std_logic_vector(63 downto 0);
signal payloadIndex : std_logic_vector(4 downto 0);
signal memoryEnable : std_logic;
signal memoryAddress : std_logic_vector(4 downto 0);
signal memoryDataRead : std_logic_vector(63 downto 0);
 
begin
header <= x"0000" & "000000" & vc_i & crf_i & prio_i & tt_i & x"d";
 
Response: process(clk, areset_n)
begin
if (areset_n = '0') then
masterCyc_o <= '0';
masterStb_o <= '0';
 
memoryEnable <= '0';
memoryAddress <= (others=>'0');
 
payloadIndex <= (others=>'0');
done_o <= '0';
state <= WAIT_PACKET;
elsif (clk'event and clk = '1') then
if (enable = '1') then
case state is
when WAIT_PACKET =>
-------------------------------------------------------------------
--
-------------------------------------------------------------------
if (ready_i = '1') then
masterCyc_o <= '1';
masterStb_o <= '1';
masterDat_o <= responseHeader;
packetIndex <= 1;
 
memoryEnable <= '1';
memoryAddress <= (others=>'0');
 
payloadIndex <= (others=>'0');
state <= SEND_RESPONSE;
end if;
when x"000068" =>
-- Host Base Device ID Lock CSR.
if (configWrite = '1') then
-- Check if this field has been written before.
if (hostBaseDeviceIdLocked = '0') then
-- The field has not been written.
-- Lock the field and set the host base device id.
hostBaseDeviceIdLocked <= '1';
hostBaseDeviceId <= configDataWrite(15 downto 0);
else
-- The field has been written.
-- Check if the written data is the same as the stored.
if (hostBaseDeviceId = configDataWrite(15 downto 0)) then
-- Same as stored, reset the value to its initial value.
hostBaseDeviceIdLocked <= '0';
hostBaseDeviceId <= (others => '1');
else
-- Not writing the same as the stored value.
-- Ignore the write.
end if;
end if;
else
configDataRead(31 downto 16) <= (others => '0');
configDataRead(15 downto 0) <= hostBaseDeviceId;
 
when SEND_RESPONSE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (masterAck_i = '1') then
case (packetIndex) is
when 1 =>
-- destination
masterDat_o <= dstId_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- source
masterDat_o <= srcId_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & status & targetTID & double-word0(63:48)
if (error_i = '0') then
if (payloadPresent_i = '0') then
masterDat_o <= "0000" & "0000" & tid_i & x"0000";
state <= WAIT_COMPLETE;
else
masterDat_o <= "1000" & "0000" & tid_i & memoryDataRead(63 downto 48);;
end if;
else
masterDat_o <= "0000" & "0111" & tid_i & x"0000";
state <= WAIT_COMPLETE;
end if;
packetIndex <= packetIndex + 1;
when 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 |
36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 =>
-- double-wordN(47:16)
masterDat_o <= memoryDataRead(47 downto 16);
responsePayload <= memoryDataRead(15 downto 0);
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
packetIndex <= packetIndex + 1;
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 33 | 35 |
37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 59 | 61 | 63 | 65 | 67 =>
-- double-wordN(15:0) & double-wordN(63:48)
masterDat_o <= responsePayload & memoryDataRead(31 downto 16);
packetIndex <= packetIndex + 1;
 
responsePayloadIndex <=
std_logic_vector(unsigned(responsePayloadIndex) + 1);
if (responsePayloadIndex = responsePayloadLength_i) then
state <= WAIT_COMPLETE;
else
packetIndex <= packetIndex + 1;
end if;
when others =>
-- Unallowed response length.
-- Dont do anything.
end case;
end if;
when x"00006C" =>
-- Component TAG CSR.
if (configWrite = '1') then
componentTag <= configDataWrite;
when WAIT_COMPLETE =>
-------------------------------------------------------------------
--
-------------------------------------------------------------------
if (masterAck_i = '1') then
masterCyc_o <= '0';
masterStb_o <= '0';
state <= RESPONSE_DONE;
end if;
when RESPONSE_DONE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
memoryEnable <= '0';
if (ready_i = '0') then
state <= WAIT_PACKET;
done_o <= '0';
else
configDataRead <= componentTag;
done_o <= '1';
end if;
 
when others =>
configDataRead <= (others => '0');
---------------------------------------------------------------------
--
---------------------------------------------------------------------
state <= WAIT_PACKET;
end case;
else
-- Config memory not enabled.
end if;
end if;
end process;
 
-----------------------------------------------------------------------------
-- findInPayload
-- find out number of the bytes and first byte's position in the payload.
-- Payload content memory.
-----------------------------------------------------------------------------
findInPayload: process(wdptr, size)
begin
case size is
when "0000" =>
reserved <= '0';
numberOfByte <= 1;
if wdptr = '1' then
pos <= 4;
else
pos <= 0;
end if;
when "0001" =>
reserved <= '0';
numberOfByte <= 1;
if wdptr = '1' then
pos <= 5;
else
pos <= 1;
end if;
when "0010" =>
reserved <= '0';
numberOfByte <= 1;
if wdptr = '1' then
pos <= 6;
else
pos <= 2;
end if;
when "0011" =>
reserved <= '0';
numberOfByte <= 1;
if wdptr = '1' then
pos <= 7;
else
pos <= 3;
end if;
when "0100" =>
reserved <= '0';
numberOfByte <= 2;
if wdptr = '1' then
pos <= 4;
else
pos <= 0;
end if;
when "0101" =>
reserved <= '0';
numberOfByte <= 3;
if wdptr = '1' then
pos <= 5;
else
pos <= 0;
end if;
when "0110" =>
reserved <= '0';
numberOfByte <= 2;
if wdptr = '1' then
pos <= 6;
else
pos <= 2;
end if;
when "0111" =>
reserved <= '0';
numberOfByte <= 5;
if wdptr = '1' then
pos <= 3;
else
pos <= 0;
end if;
when "1000" =>
reserved <= '0';
numberOfByte <= 4;
if wdptr = '1' then
pos <= 4;
else
pos <= 0;
end if;
when "1001" =>
reserved <= '0';
numberOfByte <= 6;
if wdptr = '1' then
pos <= 2;
else
pos <= 0;
end if;
when "1010" =>
reserved <= '0';
numberOfByte <= 7;
if wdptr = '1' then
pos <= 1;
else
pos <= 0;
end if;
when "1011" =>
reserved <= '0';
if wdptr = '1' then
numberOfByte <= 16;
else
numberOfByte <= 8;
end if;
pos <= 0;
when "1100" =>
reserved <= '0';
if wdptr = '1' then
numberOfByte <= 64;
else
numberOfByte <= 32;
end if;
pos <= 0;
when "1101" =>
if wdptr = '1' then
reserved <= '0';
numberOfByte <= 128;
else
reserved <= '1';
numberOfByte <= 96;
end if;
pos <= 0;
when "1110" =>
if wdptr = '1' then
numberOfByte <= 192;
else
numberOfByte <= 160;
end if;
reserved <= '1';
pos <= 0;
when "1111" =>
if wdptr = '1' then
reserved <= '0';
numberOfByte <= 256;
else
reserved <= '1';
numberOfByte <= 224;
end if;
pos <= 0;
when others =>
reserved <= '1';
numberOfByte <= 0;
pos <= 0;
end case;
end process;
PayloadMemory: MemorySimpleDualPort
generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>64)
port map(clkA_i=>clk,
enableA_i=>payloadWrite_i,
addressA_i=>payloadIndex_i,
dataA_i=>payload_i,
clkB_i=>clk,
enableB_i=>memoryEnable,
addressB_i=>memoryAddress,
dataB_o=>memoryDataRead);
 
end architecture;
/branches/singleSymbol/rtl/vhdl/RioLogicalMaintenance.vhd
0,0 → 1,944
-------------------------------------------------------------------------------
--
-- RapidIO IP Library Core
--
-- This file is part of the RapidIO IP library project
-- http://www.opencores.org/cores/rio/
--
-- Description
-- Contains a platform to build endpoints on.
--
-- To Do:
-- -
--
-- Author(s):
-- - Magnus Rosenius, magro732@opencores.org
--
-------------------------------------------------------------------------------
--
-- Copyright (C) 2013 Authors and OPENCORES.ORG
--
-- This source file may be used and distributed without
-- restriction provided that this copyright statement is not
-- removed from the file and that any derivative work contains
-- the original copyright notice and the associated disclaimer.
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.opencores.org/lgpl.shtml
--
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
-- RioLogicalMaintenance
-- This logical layer module handles ingress maintenance requests and converts
-- them into accesses on a Wishbone compatible bus accessing the configuration
-- space.
-- Addresses: 0x80 (maint read request) and 0x81 (maint write request).
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
 
-------------------------------------------------------------------------------
-- Entity for RioLogicalMaintenance.
-------------------------------------------------------------------------------
entity 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;
slaveCyc_i : in std_logic;
slaveStb_i : in std_logic;
slaveAdr_i : in std_logic_vector(7 downto 0);
slaveDat_i : in std_logic_vector(31 downto 0);
slaveAck_o : out std_logic;
 
masterCyc_o : out std_logic;
masterStb_o : out std_logic;
masterDat_o : out std_logic_vector(31 downto 0);
masterAck_i : in std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
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;
slaveCyc_i : in std_logic;
slaveStb_i : in std_logic;
slaveAdr_i : in std_logic_vector(7 downto 0);
slaveDat_i : in std_logic_vector(31 downto 0);
slaveAck_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;
masterCyc_o : out std_logic;
masterStb_o : out std_logic;
masterDat_o : out std_logic_vector(31 downto 0);
masterAck_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 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
 
configAdr_o <= configAdr;
configDat_o <= configDat;
-----------------------------------------------------------------------------
--
-----------------------------------------------------------------------------
Maintenance: process(clk, areset_n)
begin
if (areset_n = '0') then
configStb_o <= '0';
configWe_o <= '0';
configAdr <= (others=>'0');
configDat <= (others=>'0');
 
responseReadReady <= '0';
responseWriteReady <= '0';
responsePayloadWrite <= '0';
 
requestDone <= '0';
requestPayloadIndex <= (others=>'0');
elsif (clk'event and clk = '1') then
requestDone <= '0';
responsePayloadWrite <= '0';
 
if (responsePayloadWrite = '1') then
responsePayloadIndex <= std_logic_vector(unsigned(responsePayloadIndex) + 1);
end if;
case state is
when IDLE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
responsePayloadIndex <= (others=>'0');
if (requestReadReady = '1') then
configStb_o <= '1';
configWe_o <= '0';
configAdr <= requestOffset & wdptr;
state <= CONFIG_READ;
elsif (requestWriteReady = '1') then
configStb_o <= '1';
configWe_o <= '1';
configAdr <= requestOffset & wdptr;
configDat <= requestPayload;
requestPayloadIndex <= std_logic_vector(unsigned(requestPayloadIndex) + 1);
state <= CONFIG_WRITE;
else
responsePayloadIndex <= (others=>'0');
requestPayloadIndex <= (others=>'0');
end if;
 
when CONFIG_READ =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (configAck_i = '1') then
responsePayloadWrite <= '1';
if (responsePayloadIndex /= requestPayloadLength) then
configAdr <= std_logic_vector(unsigned(configAdr) + 1);
else
requestDone <= '1';
configStb_o <= '0';
state <= CONFIG_READ_RESPONSE;
end if;
end if;
 
when CONFIG_READ_RESPONSE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (responseDone = '1') then
responseReadReady <= '0';
state <= IDLE;
else
responseReadReady <= '1';
end if;
 
when CONFIG_WRITE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (configAck_i = '1') then
responsePayloadWrite <= '1';
 
if (responsePayloadIndex /= requestPayloadLength) then
configAdr <= std_logic_vector(unsigned(configAdr) + 1);
configDat <= requestPayload;
requestPayloadIndex <= std_logic_vector(unsigned(requestPayloadIndex) + 1);
else
requestDone <= '1';
configStb_o <= '0';
state <= CONFIG_WRITE_RESPONSE;
end if;
end if;
 
when CONFIG_WRITE_RESPONSE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (responseDone = '1') then
responseWriteReady <= '0';
state <= IDLE;
else
responseWriteReady <= '1';
end if;
 
when others =>
 
end case;
end if;
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,
slaveCyc_i=>slaveCyc_i,
slaveStb_i=>slaveStb_i,
slaveAdr_i=>slaveAdr_i,
slaveDat_i=>slaveDat_i,
slaveAck_o=>slaveAck_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,
masterCyc_o=>masterCyc_o,
masterStb_o=>masterStb_o,
masterDat_o=>masterDat_o,
masterAck_i=>masterAck_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;
slaveCyc_i : in std_logic;
slaveStb_i : in std_logic;
slaveAdr_i : in std_logic_vector(7 downto 0);
slaveDat_i : in std_logic_vector(31 downto 0);
slaveAck_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 slaveAck : 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
 
slaveAck_o <= slaveAck;
 
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
slaveAck <= '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 (slaveCyc_i = '1') then
if (slaveAck = '0') then
if (slaveStb_i = '1') then
if (slaveAdr_i = x"80") then
-------------------------------------------------------------
-- Maintenance Read Request packet parser.
-------------------------------------------------------------
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
requestVc_o <= slaveDat_i(9);
requestCrf_o <= slaveDat_i(8);
requestPrio_o <= slaveDat_i(7 downto 6);
requestTt_o <= slaveDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- destid
requestDstId_o <= slaveDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcid
requestSrcId_o <= slaveDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & rdsize & srcTID & hop & config_offset(20:13)
size <= slaveDat_i(27 downto 24);
requestTid_o <= slaveDat_i(23 downto 16);
requestOffset_o(20 downto 13) <= slaveDat_i(7 downto 0);
packetIndex <= packetIndex + 1;
when 4 =>
-- config_offset(12:0) & wdptr & rsrv & crc(15:0)
requestOffset_o(12 downto 0) <= slaveDat_i(31 downto 19);
wdptr <= slaveDat_i(18);
packetIndex <= packetIndex + 1;
maintReadComplete <= '1';
when others =>
-- There should be no more content in a maintenance read request.
-- Discard.
end case;
elsif (slaveAdr_i = x"81") then
-------------------------------------------------------------
-- Maintenance Write Request packet parser.
-------------------------------------------------------------
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
requestVc_o <= slaveDat_i(9);
requestCrf_o <= slaveDat_i(8);
requestPrio_o <= slaveDat_i(7 downto 6);
requestTt_o <= slaveDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- destId
requestDstId_o <= slaveDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcId
requestSrcId_o <= slaveDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & wrsize & srcTID & hop & config_offset(20:13)
size <= slaveDat_i(27 downto 24);
requestTid_o <= slaveDat_i(23 downto 16);
requestOffset_o(20 downto 13) <= slaveDat_i(7 downto 0);
packetIndex <= packetIndex + 1;
when 4 =>
-- config_offset(12:0) & wdptr & rsrv & double-word(63:48)
requestOffset_o(12 downto 0) <= slaveDat_i(31 downto 19);
wdptr <= slaveDat_i(18);
requestData(31 downto 16) <= slaveDat_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) <= slaveDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
 
if (not ((size = "1000") and (wdptr = '1'))) then
memoryWrite <= '1';
memoryDataIn <= requestData(31 downto 16) & slaveDat_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) <= slaveDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
 
memoryWrite <= '1';
memoryDataIn <= requestData(31 downto 16) & slaveDat_i(31 downto 16);
maintWriteComplete <= '1';
when others =>
-- There should be no more content in a maintenance write request.
-- Discard.
end case;
end if;
slaveAck <= '1';
end if;
else
if (memoryWrite = '1') then
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
end if;
memoryWrite <= '0';
slaveAck <= '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;
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
-- REMARK: Add handler for maintenance response with error also...
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;
masterCyc_o : out std_logic;
masterStb_o : out std_logic;
masterDat_o : out std_logic_vector(31 downto 0);
masterAck_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
masterCyc_o <= '0';
masterStb_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
masterCyc_o <= '1';
masterStb_o <= '1';
masterDat_o <= responseHeader;
packetIndex <= 1;
memoryEnable <= '1';
memoryAddress <= (others=>'0');
responsePayloadIndex <= (others=>'0');
state <= READ_RESPONSE;
elsif (responseWriteReady_i = '1') then
masterCyc_o <= '1';
masterStb_o <= '1';
masterDat_o <= responseHeader;
packetIndex <= 1;
state <= WRITE_RESPONSE;
end if;
 
when READ_RESPONSE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (masterAck_i = '1') then
case (packetIndex) is
when 1 =>
-- destination
masterDat_o <= responseDstId_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- source
masterDat_o <= responseSrcId_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & status & targetTID & hop & reserved(7:0)
masterDat_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
masterDat_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
masterDat_o <= x"0000" & x"0000";
else
masterDat_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
masterDat_o <= responsePayload(31 downto 16) & x"0000";
elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then
masterDat_o <= x"0000" & memoryDataRead(31 downto 16);
responsePayload(31 downto 16) <= memoryDataRead(15 downto 0);
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
else
masterDat_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
masterDat_o <= x"0000" & x"0000";
elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then
masterDat_o <= responsePayload(31 downto 16) & x"0000";
else
if (responsePayloadIndex /= responsePayloadLength_i(3 downto 1)) then
masterDat_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
masterDat_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 (masterAck_i = '1') then
case (packetIndex) is
when 1 =>
-- destination
masterDat_o <= responseDstId_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- source
masterDat_o <= responseSrcId_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & status & targetTID & hop & reserved(7:0)
masterDat_o <= "0011" & "0000" & responseTid_i & x"ff" & x"00";
packetIndex <= packetIndex + 1;
when others =>
-- reserved(15:0) & crc(15:0)
masterDat_o <= x"00000000";
packetIndex <= packetIndex + 1;
state <= WAIT_COMPLETE;
end case;
end if;
 
when WAIT_COMPLETE =>
-------------------------------------------------------------------
--
-------------------------------------------------------------------
if (masterAck_i = '1') then
masterCyc_o <= '0';
masterStb_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,
clkB_i=>clk,
enableB_i=>memoryEnable,
addressB_i=>memoryAddress,
dataB_o=>memoryDataRead);
 
end architecture;
/branches/singleSymbol/rtl/vhdl/RioLogicalCommon.vhd
78,6 → 78,7
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;
84,12 → 85,16
writeContent_o : out std_logic;
writeContentData_o : out std_logic_vector(31 downto 0);
 
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);
masterCyc_o : out std_logic;
masterStb_o : out std_logic;
masterAdr_o : out std_logic_vector(7 downto 0);
masterDat_o : out std_logic_vector(31 downto 0);
masterAck_i : in std_logic;
slaveCyc_i : in std_logic;
slaveStb_i : in std_logic;
slaveDat_i : in std_logic_vector(31 downto 0);
slaveAck_o : out std_logic);
end entity;
 
 
133,42 → 138,6
slaveAck_o : out 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;
slaveCyc_i : in std_logic;
slaveStb_i : in std_logic;
slaveAdr_i : in std_logic_vector(7 downto 0);
slaveDat_i : in std_logic_vector(31 downto 0);
slaveAck_o : out std_logic;
 
masterCyc_o : out std_logic;
masterStb_o : out std_logic;
masterDat_o : out std_logic_vector(31 downto 0);
masterAck_i : in std_logic);
end component;
 
signal masterCyc : std_logic;
signal masterStb : std_logic;
signal masterAdr : std_logic_vector(7 downto 0);
signal masterDat : std_logic_vector(31 downto 0);
signal masterAck : std_logic;
 
signal slaveCyc : std_logic;
signal slaveStb : std_logic;
signal slaveDat : std_logic_vector(31 downto 0);
signal slaveAck : std_logic;
 
begin
 
Ingress: RioLogicalCommonIngress
179,31 → 148,12
readContent_o=>readContent_o,
readContentEnd_i=>readContentEnd_i,
readContentData_i=>readContentData_i,
masterCyc_o=>masterCyc,
masterStb_o=>masterStb,
masterAdr_o=>masterAdr,
masterDat_o=>masterDat,
masterAck_i=>masterAck);
masterCyc_o=>masterCyc_o,
masterStb_o=>masterStb_o,
masterAdr_o=>masterAdr_o,
masterDat_o=>masterDat_o,
masterAck_i=>masterAck_i);
 
LogicalMaintenance: RioLogicalMaintenance
port map(
clk=>clk, areset_n=>areset_n, enable=>enable,
configStb_o=>configStb_o,
configWe_o=>configWe_o,
configAdr_o=>configAdr_o,
configDat_o=>configDat_o,
configDat_i=>configDat_i,
configAck_i=>configAck_i,
slaveCyc_i=>masterCyc,
slaveStb_i=>masterStb,
slaveAdr_i=>masterAdr,
slaveDat_i=>masterDat,
slaveAck_o=>masterAck,
masterCyc_o=>slaveCyc,
masterStb_o=>slaveStb,
masterDat_o=>slaveDat,
masterAck_i=>slaveAck);
 
Egress: RioLogicalCommonEgress
port map(
clk=>clk, areset_n=>areset_n,
212,10 → 162,10
writeFrameAbort_o=>writeFrameAbort_o,
writeContent_o=>writeContent_o,
writeContentData_o=>writeContentData_o,
slaveCyc_i=>slaveCyc,
slaveStb_i=>slaveStb,
slaveDat_i=>slaveDat,
slaveAck_o=>slaveAck);
slaveCyc_i=>slaveCyc_i,
slaveStb_i=>slaveStb_i,
slaveDat_i=>slaveDat_i,
slaveAck_o=>slaveAck_o);
 
end architecture;
 
767,1026 → 717,3
d_i=>writeContentData(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next);
 
end architecture;
 
 
 
 
 
-------------------------------------------------------------------------------
-- RioLogicalMaintenance
-- This logical layer module handles ingress maintenance requests and converts
-- them into accesses on a Wishbone compatible bus accessing the configuration
-- space.
-- Addresses: 0x80 (maint read request) and 0x81 (maint write request).
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
 
-------------------------------------------------------------------------------
-- Entity for RioLogicalMaintenance.
-------------------------------------------------------------------------------
entity 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;
slaveCyc_i : in std_logic;
slaveStb_i : in std_logic;
slaveAdr_i : in std_logic_vector(7 downto 0);
slaveDat_i : in std_logic_vector(31 downto 0);
slaveAck_o : out std_logic;
 
masterCyc_o : out std_logic;
masterStb_o : out std_logic;
masterDat_o : out std_logic_vector(31 downto 0);
masterAck_i : in std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
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;
slaveCyc_i : in std_logic;
slaveStb_i : in std_logic;
slaveAdr_i : in std_logic_vector(7 downto 0);
slaveDat_i : in std_logic_vector(31 downto 0);
slaveAck_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;
masterCyc_o : out std_logic;
masterStb_o : out std_logic;
masterDat_o : out std_logic_vector(31 downto 0);
masterAck_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 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
 
configAdr_o <= configAdr;
configDat_o <= configDat;
-----------------------------------------------------------------------------
--
-----------------------------------------------------------------------------
Maintenance: process(clk, areset_n)
begin
if (areset_n = '0') then
configStb_o <= '0';
configWe_o <= '0';
configAdr <= (others=>'0');
configDat <= (others=>'0');
 
responseReadReady <= '0';
responseWriteReady <= '0';
responsePayloadWrite <= '0';
 
requestDone <= '0';
requestPayloadIndex <= (others=>'0');
elsif (clk'event and clk = '1') then
requestDone <= '0';
responsePayloadWrite <= '0';
 
if (responsePayloadWrite = '1') then
responsePayloadIndex <= std_logic_vector(unsigned(responsePayloadIndex) + 1);
end if;
case state is
when IDLE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
responsePayloadIndex <= (others=>'0');
if (requestReadReady = '1') then
configStb_o <= '1';
configWe_o <= '0';
configAdr <= requestOffset & wdptr;
state <= CONFIG_READ;
elsif (requestWriteReady = '1') then
configStb_o <= '1';
configWe_o <= '1';
configAdr <= requestOffset & wdptr;
configDat <= requestPayload;
requestPayloadIndex <= std_logic_vector(unsigned(requestPayloadIndex) + 1);
state <= CONFIG_WRITE;
else
responsePayloadIndex <= (others=>'0');
requestPayloadIndex <= (others=>'0');
end if;
 
when CONFIG_READ =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (configAck_i = '1') then
responsePayloadWrite <= '1';
if (responsePayloadIndex /= requestPayloadLength) then
configAdr <= std_logic_vector(unsigned(configAdr) + 1);
else
requestDone <= '1';
configStb_o <= '0';
state <= CONFIG_READ_RESPONSE;
end if;
end if;
 
when CONFIG_READ_RESPONSE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (responseDone = '1') then
responseReadReady <= '0';
state <= IDLE;
else
responseReadReady <= '1';
end if;
 
when CONFIG_WRITE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (configAck_i = '1') then
responsePayloadWrite <= '1';
 
if (responsePayloadIndex /= requestPayloadLength) then
configAdr <= std_logic_vector(unsigned(configAdr) + 1);
configDat <= requestPayload;
requestPayloadIndex <= std_logic_vector(unsigned(requestPayloadIndex) + 1);
else
requestDone <= '1';
configStb_o <= '0';
state <= CONFIG_WRITE_RESPONSE;
end if;
end if;
 
when CONFIG_WRITE_RESPONSE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (responseDone = '1') then
responseWriteReady <= '0';
state <= IDLE;
else
responseWriteReady <= '1';
end if;
 
when others =>
 
end case;
end if;
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,
slaveCyc_i=>slaveCyc_i,
slaveStb_i=>slaveStb_i,
slaveAdr_i=>slaveAdr_i,
slaveDat_i=>slaveDat_i,
slaveAck_o=>slaveAck_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,
masterCyc_o=>masterCyc_o,
masterStb_o=>masterStb_o,
masterDat_o=>masterDat_o,
masterAck_i=>masterAck_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;
slaveCyc_i : in std_logic;
slaveStb_i : in std_logic;
slaveAdr_i : in std_logic_vector(7 downto 0);
slaveDat_i : in std_logic_vector(31 downto 0);
slaveAck_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 slaveAck : 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
 
slaveAck_o <= slaveAck;
 
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
slaveAck <= '0';
 
maintReadComplete <= '0';
maintWriteComplete <= '0';
requestVc_o <= '0';
requestCrf_o <= '0';
requestPrio_o <= "00";
requestTt_o <= "00";
requestOffset_o <= (others=>'0');
 
wdptr <= '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 (slaveCyc_i = '1') then
if (slaveAck = '0') then
if (slaveStb_i = '1') then
if (slaveAdr_i = x"80") then
-------------------------------------------------------------
-- Maintenance Read Request packet parser.
-------------------------------------------------------------
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
requestVc_o <= slaveDat_i(9);
requestCrf_o <= slaveDat_i(8);
requestPrio_o <= slaveDat_i(7 downto 6);
requestTt_o <= slaveDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- destid
requestDstId_o <= slaveDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcid
requestSrcId_o <= slaveDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & rdsize & srcTID & hop & config_offset(20:13)
size <= slaveDat_i(27 downto 24);
requestTid_o <= slaveDat_i(23 downto 16);
requestOffset_o(20 downto 13) <= slaveDat_i(7 downto 0);
packetIndex <= packetIndex + 1;
when 4 =>
-- config_offset(12:0) & wdptr & rsrv & crc(15:0)
requestOffset_o(12 downto 0) <= slaveDat_i(31 downto 19);
wdptr <= slaveDat_i(18);
packetIndex <= packetIndex + 1;
maintReadComplete <= '1';
when others =>
-- There should be no more content in a maintenance read request.
-- Discard.
end case;
elsif (slaveAdr_i = x"81") then
-------------------------------------------------------------
-- Maintenance Write Request packet parser.
-------------------------------------------------------------
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
requestVc_o <= slaveDat_i(9);
requestCrf_o <= slaveDat_i(8);
requestPrio_o <= slaveDat_i(7 downto 6);
requestTt_o <= slaveDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- destId
requestDstId_o <= slaveDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcId
requestSrcId_o <= slaveDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & wrsize & srcTID & hop & config_offset(20:13)
size <= slaveDat_i(27 downto 24);
requestTid_o <= slaveDat_i(23 downto 16);
requestOffset_o(20 downto 13) <= slaveDat_i(7 downto 0);
packetIndex <= packetIndex + 1;
when 4 =>
-- config_offset(12:0) & wdptr & rsrv & double-word(63:48)
requestOffset_o(12 downto 0) <= slaveDat_i(31 downto 19);
wdptr <= slaveDat_i(18);
requestData(31 downto 16) <= slaveDat_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) <= slaveDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
 
if (not ((size = "1000") and (wdptr = '1'))) then
memoryWrite <= '1';
memoryDataIn <= requestData(31 downto 16) & slaveDat_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) <= slaveDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
 
memoryWrite <= '1';
memoryDataIn <= requestData(31 downto 16) & slaveDat_i(31 downto 16);
maintWriteComplete <= '1';
when others =>
-- There should be no more content in a maintenance write request.
-- Discard.
end case;
end if;
slaveAck <= '1';
end if;
else
if (memoryWrite = '1') then
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
end if;
memoryWrite <= '0';
slaveAck <= '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;
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
-- REMARK: Add handler for maintenance response with error also...
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;
masterCyc_o : out std_logic;
masterStb_o : out std_logic;
masterDat_o : out std_logic_vector(31 downto 0);
masterAck_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
masterCyc_o <= '0';
masterStb_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
masterCyc_o <= '1';
masterStb_o <= '1';
masterDat_o <= responseHeader;
packetIndex <= 1;
memoryEnable <= '1';
memoryAddress <= (others=>'0');
responsePayloadIndex <= (others=>'0');
state <= READ_RESPONSE;
elsif (responseWriteReady_i = '1') then
masterCyc_o <= '1';
masterStb_o <= '1';
masterDat_o <= responseHeader;
packetIndex <= 1;
state <= WRITE_RESPONSE;
end if;
 
when READ_RESPONSE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (masterAck_i = '1') then
case (packetIndex) is
when 1 =>
-- destination
masterDat_o <= responseDstId_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- source
masterDat_o <= responseSrcId_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & status & targetTID & hop & reserved(7:0)
masterDat_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
masterDat_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
masterDat_o <= x"0000" & x"0000";
else
masterDat_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
masterDat_o <= responsePayload(31 downto 16) & x"0000";
elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then
masterDat_o <= x"0000" & memoryDataRead(31 downto 16);
responsePayload(31 downto 16) <= memoryDataRead(15 downto 0);
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
else
masterDat_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
masterDat_o <= x"0000" & x"0000";
elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then
masterDat_o <= responsePayload(31 downto 16) & x"0000";
else
if (responsePayloadIndex /= responsePayloadLength_i(3 downto 1)) then
masterDat_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
masterDat_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 (masterAck_i = '1') then
case (packetIndex) is
when 1 =>
-- destination
masterDat_o <= responseDstId_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- source
masterDat_o <= responseSrcId_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & status & targetTID & hop & reserved(7:0)
masterDat_o <= "0011" & "0000" & responseTid_i & x"ff" & x"00";
packetIndex <= packetIndex + 1;
when others =>
-- reserved(15:0) & crc(15:0)
masterDat_o <= x"00000000";
packetIndex <= packetIndex + 1;
state <= WAIT_COMPLETE;
end case;
end if;
 
when WAIT_COMPLETE =>
-------------------------------------------------------------------
--
-------------------------------------------------------------------
if (masterAck_i = '1') then
masterCyc_o <= '0';
masterStb_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,
clkB_i=>clk,
enableB_i=>memoryEnable,
addressB_i=>memoryAddress,
dataB_o=>memoryDataRead);
 
end architecture;
 
 
 
---- REMARK: Make this a common component? Can be used in IO-accesses as well.
---- REMARK: Not all of these are allowed in a maintenance request.
--process(clk, areset_n)
--begin
-- if (areset_n = '0') then
-- doubleWords <= 0;
-- byteLanes <= (others=>'0');
-- elsif (clk'event and clk = '1') then
-- if (maintReadComplete = '1') or (maintWriteComplete = '1') then
-- if (wdptr = '0') then
-- case to_integer(unsigned(size)) is
-- when 0 =>
-- doubleWords <= 0;
-- byteLanes <= "10000000";
-- when 1 =>
-- doubleWords <= 0;
-- byteLanes <= "01000000";
-- when 2 =>
-- doubleWords <= 0;
-- byteLanes <= "00100000";
-- when 3 =>
-- doubleWords <= 0;
-- byteLanes <= "00010000";
-- when 4 =>
-- doubleWords <= 0;
-- byteLanes <= "11000000";
-- when 5 =>
-- doubleWords <= 0;
-- byteLanes <= "11100000";
-- when 6 =>
-- doubleWords <= 0;
-- byteLanes <= "00110000";
-- when 7 =>
-- doubleWords <= 0;
-- byteLanes <= "11111000";
-- when 8 =>
-- doubleWords <= 0;
-- byteLanes <= "11110000";
-- when 9 =>
-- doubleWords <= 0;
-- byteLanes <= "11111100";
-- when 10 =>
-- doubleWords <= 0;
-- byteLanes <= "11111110";
-- when 11 =>
-- doubleWords <= 0;
-- byteLanes <= "11111111";
-- when 12 =>
-- doubleWords <= 3;
-- byteLanes <= "11111111";
-- when 13 =>
-- doubleWords <= 11;
-- byteLanes <= "11111111";
-- when 14 =>
-- doubleWords <= 19;
-- byteLanes <= "11111111";
-- when others =>
-- doubleWords <= 27;
-- byteLanes <= "11111111";
-- end case;
-- else
-- case to_integer(unsigned(size)) is
-- when 0 =>
-- doubleWords <= 0;
-- byteLanes <= "00001000";
-- when 1 =>
-- doubleWords <= 0;
-- byteLanes <= "00000100";
-- when 2 =>
-- doubleWords <= 0;
-- byteLanes <= "00000010";
-- when 3 =>
-- doubleWords <= 0;
-- byteLanes <= "00000001";
-- when 4 =>
-- doubleWords <= 0;
-- byteLanes <= "00001100";
-- when 5 =>
-- doubleWords <= 0;
-- byteLanes <= "00000111";
-- when 6 =>
-- doubleWords <= 0;
-- byteLanes <= "00000011";
-- when 7 =>
-- doubleWords <= 0;
-- byteLanes <= "00011111";
-- when 8 =>
-- doubleWords <= 0;
-- byteLanes <= "00001111";
-- when 9 =>
-- doubleWords <= 0;
-- byteLanes <= "00111111";
-- when 10 =>
-- doubleWords <= 0;
-- byteLanes <= "01111111";
-- when 11 =>
-- doubleWords <= 1;
-- byteLanes <= "11111111";
-- when 12 =>
-- doubleWords <= 7;
-- byteLanes <= "11111111";
-- when 13 =>
-- doubleWords <= 15;
-- byteLanes <= "11111111";
-- when 14 =>
-- doubleWords <= 23;
-- byteLanes <= "11111111";
-- when others =>
-- doubleWords <= 31;
-- byteLanes <= "11111111";
-- end case;
-- end if;
-- end if;
-- end if;
--end process;

powered by: WebSVN 2.1.0

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