URL
https://opencores.org/ocsvn/rio/rio/trunk
Subversion Repositories rio
[/] [rio/] [branches/] [2.0.0-development/] [rtl/] [vhdl/] [RioWbBridge.vhd] - Rev 41
Go to most recent revision | Compare with Previous | Blame | View Log
------------------------------------------------------------------------------- -- -- RapidIO IP Library Core -- -- This file is part of the RapidIO IP library project -- http://www.opencores.org/cores/rio/ -- -- Description -- Containing a bridge between a RapidIO network and a Wishbone bus. Packets -- NWRITE, NWRITER and NREAD are currently supported. -- -- 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 -- ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- RioWbBridge. ------------------------------------------------------------------------------- -- REMARK: Add support for EXTENDED_ADDRESS... library ieee; use ieee.numeric_std.ALL; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use work.rio_common.all; ------------------------------------------------------------------------------- -- Entity for RioWbBridge. ------------------------------------------------------------------------------- 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)); port( clk : in std_logic; areset_n : 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); 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 RioWbBridgeImpl of RioWbBridge is component 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; 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; 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; 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; component 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 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 ----------------------------------------------------------------------------- -- ----------------------------------------------------------------------------- adr_o <= adr; dat_o <= datOut; Bridge: process(clk, areset_n) begin if (areset_n = '0') then cyc_o <= '0'; stb_o <= '0'; we_o <= '0'; adr <= (others=>'0'); datOut <= (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 => --------------------------------------------------------------------- -- --------------------------------------------------------------------- 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 responseReadReady <= '1'; end if; when WRITE_CLASS => --------------------------------------------------------------------- -- --------------------------------------------------------------------- if (ack_i = '1') then responsePayloadWrite <= '1'; 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 WRITE_CLASS_RESPONSE => --------------------------------------------------------------------- -- --------------------------------------------------------------------- if (responseDone = '1') then responseWriteReady <= '0'; state <= IDLE; else responseWriteReady <= '1'; end if; when others => end case; end if; end process; ----------------------------------------------------------------------------- -- ----------------------------------------------------------------------------- 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); 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); 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); ----------------------------------------------------------------------------- -- 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 -- 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 others => -- configDataRead <= (others => '0'); -- end case; -- else -- -- Config memory not enabled. -- end if; -- end if; -- end process; end architecture; ------------------------------------------------------------------------------- -- ------------------------------------------------------------------------------- -- 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; ------------------------------------------------------------------------------- -- ------------------------------------------------------------------------------- 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; 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; slaveAck <= '1'; end if; else slaveAck <= '0'; end if; else if (complete = '1') then state <= READY; end if; packetIndex <= 0; end if; 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 others => --------------------------------------------------------------------- -- --------------------------------------------------------------------- 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; 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 (complete = '1') then state <= READY; end if; packetIndex <= 0; memoryAddress <= (others=>'0'); end if; when READY => --------------------------------------------------------------------- -- Wait for the handler of the packet to signal that it has been -- processed. --------------------------------------------------------------------- if (done_i = '1') then complete <= '0'; state <= RECEIVE_PACKET; end if; when others => --------------------------------------------------------------------- -- --------------------------------------------------------------------- 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; ----------------------------------------------------------------------------- -- Payload content memory. ----------------------------------------------------------------------------- process(clk, areset_n) begin if (areset_n = '0') then 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); 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 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 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 done_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=>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;
Go to most recent revision | Compare with Previous | Blame | View Log