Line 1... |
Line 1... |
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
-- Company:
|
-- Company:
|
-- Engineer: Istvan Nagy, buenos@freemail.hu
|
-- Engineer: Istvan Nagy, buenos@freemail.hu
|
--
|
--
|
-- Create Date: 15:58:13 05/30/2010
|
-- Create Date: 05/30/2010
|
|
-- Modify date: 04/26/2011
|
-- Design Name: pcie_mini
|
-- Design Name: pcie_mini
|
-- Module Name: xilinx_pcie2wb - Behavioral
|
-- Module Name: xilinx_pcie2wb - Behavioral
|
-- Version: 1.0
|
-- Version: 1.1
|
-- Project Name:
|
-- Project Name:
|
-- Target Devices: Xilinx Series-5/6/7 FPGAs
|
-- Target Devices: Xilinx Series-5/6/7 FPGAs
|
-- Tool versions: ISE-DS 12.1
|
-- Tool versions: ISE-DS 12.1
|
-- Description:
|
-- Description:
|
-- PCI-express endpoint block, transaction layer logic and back-end logic. The main
|
-- PCI-express endpoint block, transaction layer logic and back-end logic. The main
|
Line 239... |
Line 240... |
SIGNAL pciewb_localreset_n : std_logic;
|
SIGNAL pciewb_localreset_n : std_logic;
|
SIGNAL cfg_interrupt_assert_n_1 : std_logic;
|
SIGNAL cfg_interrupt_assert_n_1 : std_logic;
|
SIGNAL trn_tsrc_rdy_n_1 : std_logic;
|
SIGNAL trn_tsrc_rdy_n_1 : std_logic;
|
SIGNAL trn_tsof_n1 : std_logic;
|
SIGNAL trn_tsof_n1 : std_logic;
|
SIGNAL rcompl_bytecount_field : std_logic_vector(9 downto 0);
|
SIGNAL rcompl_bytecount_field : std_logic_vector(9 downto 0);
|
|
SIGNAL rxstm_readytoroll : std_logic;
|
|
SIGNAL tlpstm_isin_idle : std_logic;
|
|
|
|
|
|
|
|
|
|
|
Line 666... |
Line 669... |
case ( wb0_state ) is
|
case ( wb0_state ) is
|
|
|
--********** IDLE STATE **********
|
--********** IDLE STATE **********
|
when "00000000" => --state 0
|
when "00000000" => --state 0
|
wb_transaction_complete <='0';
|
wb_transaction_complete <='0';
|
pcie_bar0_wb_sel_o(0) <= pcie_bar0_wb_sel_o_feed(3); --swap endianism
|
pcie_bar0_wb_sel_o <= pcie_bar0_wb_sel_o_feed;
|
pcie_bar0_wb_sel_o(1) <= pcie_bar0_wb_sel_o_feed(2); --swap endianism
|
|
pcie_bar0_wb_sel_o(2) <= pcie_bar0_wb_sel_o_feed(1); --swap endianism
|
|
pcie_bar0_wb_sel_o(3) <= pcie_bar0_wb_sel_o_feed(0); --swap endianism
|
|
--or no endian swap on SEL: pcie_bar0_wb_sel_o <= pcie_bar0_wb_sel_o_feed;
|
|
pcie_bar0_wb_addr_o <= pcie_bar0_wb_addr_o_feed;
|
pcie_bar0_wb_addr_o <= pcie_bar0_wb_addr_o_feed;
|
if (start_read_wb0 ='1') then --go to read
|
if (start_read_wb0 ='1') then --go to read
|
wb0_state <= "00000001";
|
wb0_state <= "00000001";
|
elsif (start_write_wb0 ='1') then --go to write
|
elsif (start_write_wb0 ='1') then --go to write
|
wb0_state <= "00000010";
|
wb0_state <= "00000010";
|
Line 861... |
Line 860... |
|
|
|
|
|
|
|
|
-- RX: INTERFACE TO THE PCIE-EP: GET thereceived TLP PACKETS:- ----
|
-- RX: INTERFACE TO THE PCIE-EP: GET thereceived TLP PACKETS:- ----
|
process (pciewb_localreset_n, trn_clk, epif_rx_state, tlp_state, trn_rx_counter, bram_rxtlp_writeaddress)
|
process (pciewb_localreset_n, trn_clk, epif_rx_state, tlp_state, trn_rx_counter,
|
|
bram_rxtlp_writeaddress, rxstm_readytoroll, trn_rsof_n, tlpstm_isin_idle, trn_rdst_rdy_n)
|
begin
|
begin
|
if (pciewb_localreset_n='0') then
|
if (pciewb_localreset_n='0') then
|
pcie_just_received_a_new_tlp <= '0';
|
pcie_just_received_a_new_tlp <= '0';
|
epif_rx_state <= "00000000";
|
epif_rx_state <= "00000000";
|
trn_rdst_rdy_n <= '1';
|
trn_rdst_rdy_n <= '1';
|
trn_rx_counter <= (OTHERS => '0');
|
trn_rx_counter <= (OTHERS => '0');
|
bram_rxtlp_we <= "0";
|
bram_rxtlp_we <= "0";
|
bram_rxtlp_writeaddress <= (OTHERS => '0');
|
bram_rxtlp_writeaddress <= (OTHERS => '0');
|
bram_rxtlp_writedata <= (OTHERS => '0');
|
bram_rxtlp_writedata <= (OTHERS => '0');
|
|
rxstm_readytoroll <= '0';
|
else
|
else
|
if (trn_clk'event and trn_clk = '1') then
|
if (trn_clk'event and trn_clk = '1') then
|
|
|
if (tlp_state = 0)then
|
|
trn_rdst_rdy_n <= '0';
|
|
else
|
|
trn_rdst_rdy_n <= '1';
|
|
end if;
|
|
|
|
case ( epif_rx_state ) is
|
case ( epif_rx_state ) is
|
|
|
--********** idle STATE **********
|
--********** idle STATE **********
|
when "00000000" => --state 0
|
when "00000000" => --state 0
|
pcie_just_received_a_new_tlp <= '0';
|
pcie_just_received_a_new_tlp <= '0';
|
bram_rxtlp_writedata <= trn_rd;
|
bram_rxtlp_writedata <= trn_rd;
|
if (trn_rsrc_rdy_n='0' and trn_rsof_n='0') then
|
if (trn_rsrc_rdy_n='0' and trn_rsof_n='0' and tlpstm_isin_idle = '1' and trn_rdst_rdy_n='0') then
|
trn_rx_counter <= trn_rx_counter +1;
|
trn_rx_counter <= trn_rx_counter +1;
|
bram_rxtlp_writeaddress <= bram_rxtlp_writeaddress +1;
|
bram_rxtlp_writeaddress <= bram_rxtlp_writeaddress +1;
|
epif_rx_state <= "00000001";
|
epif_rx_state <= "00000001";
|
--read first DW:
|
|
bram_rxtlp_we <= "1";
|
|
else
|
else
|
trn_rx_counter <= (OTHERS => '0');
|
trn_rx_counter <= (OTHERS => '0');
|
bram_rxtlp_writeaddress <= (OTHERS => '0');
|
bram_rxtlp_writeaddress <= (OTHERS => '0');
|
|
end if;
|
|
--destination ready:
|
|
if (tlpstm_isin_idle = '1')then
|
|
trn_rdst_rdy_n <= '0';
|
|
else
|
|
trn_rdst_rdy_n <= '1';
|
|
end if;
|
|
--write into buffer:
|
|
if (trn_rsrc_rdy_n='0' and trn_rsof_n='0' and tlpstm_isin_idle = '1') then
|
|
bram_rxtlp_we <= "1";
|
|
rxstm_readytoroll <= '1';
|
|
else
|
bram_rxtlp_we <= "0";
|
bram_rxtlp_we <= "0";
|
|
rxstm_readytoroll <= '0';
|
end if;
|
end if;
|
|
|
--********** read STATE **********
|
--********** read STATE **********
|
when "00000001" => --state 1
|
when "00000001" => --state 1
|
|
rxstm_readytoroll <= '0';
|
if (trn_reof_n ='0') then --last dw
|
if (trn_reof_n ='0') then --last dw
|
epif_rx_state <= "00000010"; --for the next clk cycle
|
epif_rx_state <= "00000010"; --for the next clk cycle
|
|
trn_rdst_rdy_n <= '1'; --ok, dont send more yet
|
end if;
|
end if;
|
if (trn_rsrc_rdy_n='0') then --only act if the EP was ready
|
if (trn_rsrc_rdy_n='0') then --only act if the EP was ready
|
trn_rx_counter <= trn_rx_counter +1;
|
trn_rx_counter <= trn_rx_counter +1;
|
bram_rxtlp_writeaddress <= bram_rxtlp_writeaddress +1;
|
bram_rxtlp_writeaddress <= bram_rxtlp_writeaddress +1;
|
bram_rxtlp_writedata <= trn_rd;
|
bram_rxtlp_writedata <= trn_rd;
|
Line 1035... |
Line 1043... |
rxtlp_header_dw4 <= (others => '0');
|
rxtlp_header_dw4 <= (others => '0');
|
flag1 <= '0';
|
flag1 <= '0';
|
rxdw1_23_0 <= (others => '0');
|
rxdw1_23_0 <= (others => '0');
|
pcie_rxtlp_tag <= (others => '0');
|
pcie_rxtlp_tag <= (others => '0');
|
rcompl_bytecount_field <= (others => '0');
|
rcompl_bytecount_field <= (others => '0');
|
|
tlpstm_isin_idle <= '1';
|
else
|
else
|
if (trn_clk'event and trn_clk = '1') then
|
if (trn_clk'event and trn_clk = '1') then
|
case ( tlp_state ) is
|
case ( tlp_state ) is
|
|
|
--********** IDLE STATE **********
|
--********** IDLE STATE **********
|
--also re-initialize signals...
|
--also re-initialize signals...
|
when "00000000" => --state 0
|
when "00000000" => --state 0
|
if (pcie_just_received_a_new_tlp='1') then
|
if (pcie_just_received_a_new_tlp='1') then
|
tlp_state <= "00000001"; --to tlp decoding state
|
tlp_state <= "00000001"; --to tlp decoding state
|
|
tlpstm_isin_idle <= '0';
|
|
else
|
|
tlpstm_isin_idle <= '1';
|
end if;
|
end if;
|
start_write_wb0 <= '0';
|
start_write_wb0 <= '0';
|
start_read_wb0 <= '0';
|
start_read_wb0 <= '0';
|
tlp_state_copy <= tlp_state;
|
tlp_state_copy <= tlp_state;
|
bram_txtlp_we <= "0";
|
bram_txtlp_we <= "0";
|
Line 1057... |
Line 1069... |
tlp_datacount <= "00000001";
|
tlp_datacount <= "00000001";
|
rxtlp_header_dw1 <= "01111111000000000000000000000000"; --this is to prevent false decode
|
rxtlp_header_dw1 <= "01111111000000000000000000000000"; --this is to prevent false decode
|
pcie_bar0_wb_data_o_feed <= (others => '0');
|
pcie_bar0_wb_data_o_feed <= (others => '0');
|
pcie_bar0_wb_addr_o_feed <= (others => '0');
|
pcie_bar0_wb_addr_o_feed <= (others => '0');
|
pcie_bar0_wb_sel_o_feed <= (others => '0');
|
pcie_bar0_wb_sel_o_feed <= (others => '0');
|
rxtlp_header_dw1 <= "01111111000000000000000000000000";
|
|
rxtlp_header_dw2 <= (others => '0');
|
rxtlp_header_dw2 <= (others => '0');
|
rxtlp_header_dw3 <= (others => '0');
|
rxtlp_header_dw3 <= (others => '0');
|
rxtlp_header_dw4 <= (others => '0');
|
rxtlp_header_dw4 <= (others => '0');
|
rxdw1_23_0 <= (others => '0');
|
rxdw1_23_0 <= (others => '0');
|
pcie_rxtlp_tag <= (others => '0');
|
pcie_rxtlp_tag <= (others => '0');
|
Line 1072... |
Line 1083... |
rxtlp_lastdw_be <= (others => '0');
|
rxtlp_lastdw_be <= (others => '0');
|
rxtlp_requesterid <= (others => '0');
|
rxtlp_requesterid <= (others => '0');
|
rcompl_bytecount_field <= (others => '0');
|
rcompl_bytecount_field <= (others => '0');
|
|
|
|
|
|
|
--********** TLP ARRIVED STATE **********
|
--********** TLP ARRIVED STATE **********
|
--read TLP out of EP, decode and decide,
|
--read TLP out of EP, decode and decide,
|
--latch address/sel/wr_data
|
--latch address/sel/wr_data
|
--All the "IF"-statements use address+1, because the BRAM read side has data available 1clk late!!!
|
--All the "IF"-statements use address+1, because the BRAM read side has data available 1clk late!!!
|
--Added an ectra clock delay, based on testing, since the data is one more CLK late.
|
--Added an ectra clock delay, based on testing, since the data is one more CLK late.
|
Line 1253... |
Line 1263... |
--********** UNSUPPORTED REQUEST STATE **********
|
--********** UNSUPPORTED REQUEST STATE **********
|
--completion response with status=001
|
--completion response with status=001
|
when "00000101" => --state 5
|
when "00000101" => --state 5
|
tlp_state_copy <= tlp_state;
|
tlp_state_copy <= tlp_state;
|
tlp_payloadsize_dwords <= "00000000";
|
tlp_payloadsize_dwords <= "00000000";
|
|
bram_txtlp_writeaddress <= bram_txtlp_writeaddress +1;
|
--assembling the TLP packet: )
|
--assembling the TLP packet: )
|
if (bram_txtlp_writeaddress="111111111") then --header 1.dw
|
if (bram_txtlp_writeaddress="111111111") then --header 1.dw
|
bram_txtlp_writeaddress <= bram_txtlp_writeaddress +1;
|
|
bram_txtlp_we <= "1";
|
bram_txtlp_we <= "1";
|
bram_txtlp_writedata (31) <= flag1; --reserved
|
bram_txtlp_writedata (31) <= flag1; --reserved
|
bram_txtlp_writedata (30 downto 24) <= "1001010"; --type= rd completion
|
bram_txtlp_writedata (30 downto 24) <= "1001010"; --type= rd completion
|
bram_txtlp_writedata (23 downto 0) <= rxdw1_23_0; --various fields pcie_received_tlp (23 downto 0);
|
bram_txtlp_writedata (23 downto 0) <= rxdw1_23_0; --various fields pcie_received_tlp (23 downto 0);
|
elsif (bram_txtlp_writeaddress="000000000") then --header 2.dw
|
elsif (bram_txtlp_writeaddress="000000000") then --header 2.dw
|
bram_txtlp_writeaddress <= bram_txtlp_writeaddress +1;
|
|
bram_txtlp_we <= "1";
|
bram_txtlp_we <= "1";
|
bram_txtlp_writedata (31 downto 16) <= cfg_completer_id; --completer ID
|
bram_txtlp_writedata (31 downto 16) <= cfg_completer_id; --completer ID
|
bram_txtlp_writedata (15 downto 13) <= "000"; --status= UNSUPPORTED REQUEST ***
|
bram_txtlp_writedata (15 downto 13) <= "000"; --status= UNSUPPORTED REQUEST ***
|
bram_txtlp_writedata (12) <= '0'; --reserved
|
bram_txtlp_writedata (12) <= '0'; --reserved
|
bram_txtlp_writedata (11 downto 0) <= "000000000000"; --remaining byte count
|
bram_txtlp_writedata (11 downto 0) <= "000000000000"; --remaining byte count
|
elsif (bram_txtlp_writeaddress="000000001") then --header 3.dw
|
elsif (bram_txtlp_writeaddress="000000001") then --header 3.dw
|
bram_txtlp_writeaddress <= bram_txtlp_writeaddress +1;
|
|
bram_txtlp_we <= "1";
|
bram_txtlp_we <= "1";
|
bram_txtlp_writedata (31 downto 16) <= rxtlp_requesterid; --requester ID
|
bram_txtlp_writedata (31 downto 16) <= rxtlp_requesterid; --requester ID
|
bram_txtlp_writedata (15 downto 8) <= pcie_rxtlp_tag ; --pcie_received_tlp (47 downto 40);--tag
|
bram_txtlp_writedata (15 downto 8) <= pcie_rxtlp_tag ; --pcie_received_tlp (47 downto 40);--tag
|
bram_txtlp_writedata (7) <= '0'; --reserved
|
bram_txtlp_writedata (7) <= '0'; --reserved
|
bram_txtlp_writedata (6 downto 2) <= rxtlp_decodedaddress(6 downto 2); --lower address
|
bram_txtlp_writedata (6 downto 2) <= rxtlp_decodedaddress(6 downto 2); --lower address
|
bram_txtlp_writedata (1 downto 0) <= bit10(1 downto 0); --lower address
|
bram_txtlp_writedata (1 downto 0) <= bit10(1 downto 0); --lower address
|
else --data dwords
|
else --data dwords
|
--2. read data : no data in this type of packet
|
|
--this was written directly during the read state.
|
|
bram_txtlp_writeaddress <= bram_txtlp_writeaddress;
|
|
bram_txtlp_we <= "0";
|
bram_txtlp_we <= "0";
|
end if;
|
end if;
|
--one pulse to start the ep-if statemachine, upon arriving to this state
|
--one pulse to start the ep-if statemachine, upon arriving to this state
|
if (tlp_state_copy = tlp_state) then
|
if (tlp_state_copy = tlp_state) then
|
pcie_there_is_a_new_tlp_to_transmit <= '0';
|
pcie_there_is_a_new_tlp_to_transmit <= '0';
|
Line 1304... |
Line 1309... |
|
|
|
|
|
|
|
|
--byte enable encoding to wb_address bit1:0
|
--byte enable encoding to wb_address bit1:0
|
--this also takes the endian swapping into account.
|
--this does not swap the endian, since only the data is swapped in the pcie packets.
|
process ( pciewb_localreset_n, rxtlp_firstdw_be )
|
process ( pciewb_localreset_n, rxtlp_firstdw_be )
|
begin
|
begin
|
if (pciewb_localreset_n = '0') then
|
if (pciewb_localreset_n = '0') then
|
bit10(1 downto 0) <="00";
|
bit10(1 downto 0) <="00";
|
else
|
else
|
if (rxtlp_firstdw_be ="0001") then
|
if (rxtlp_firstdw_be ="0001") then
|
bit10(1 downto 0) <= "11";
|
bit10(1 downto 0) <= "00";
|
elsif (rxtlp_firstdw_be ="0010") then
|
elsif (rxtlp_firstdw_be ="0010") then
|
bit10(1 downto 0) <= "10";
|
|
elsif (rxtlp_firstdw_be ="0100") then
|
|
bit10(1 downto 0) <= "01";
|
bit10(1 downto 0) <= "01";
|
|
elsif (rxtlp_firstdw_be ="0100") then
|
|
bit10(1 downto 0) <= "10";
|
elsif (rxtlp_firstdw_be ="1000") then
|
elsif (rxtlp_firstdw_be ="1000") then
|
bit10(1 downto 0) <= "00";
|
bit10(1 downto 0) <= "11";
|
elsif (rxtlp_firstdw_be ="0011") then
|
elsif (rxtlp_firstdw_be ="0011") then
|
bit10(1 downto 0) <= "10";
|
|
elsif (rxtlp_firstdw_be ="1100") then
|
|
bit10(1 downto 0) <= "00";
|
bit10(1 downto 0) <= "00";
|
|
elsif (rxtlp_firstdw_be ="1100") then
|
|
bit10(1 downto 0) <= "10";
|
elsif (rxtlp_firstdw_be ="1111") then
|
elsif (rxtlp_firstdw_be ="1111") then
|
bit10(1 downto 0) <= "00";
|
bit10(1 downto 0) <= "00";
|
else --this should never happen
|
else --this should never happen
|
bit10(1 downto 0) <= "00";
|
bit10(1 downto 0) <= "00";
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
--without endian swap:
|
|
-- process ( pciewb_localreset_n, rxtlp_firstdw_be )
|
|
-- begin
|
|
-- if (pciewb_localreset_n = '0') then
|
|
-- bit10(1 downto 0) <="00";
|
|
-- else
|
|
-- if (rxtlp_firstdw_be ="0001") then
|
|
-- bit10(1 downto 0) <= "00";
|
|
-- elsif (rxtlp_firstdw_be ="0010") then
|
|
-- bit10(1 downto 0) <= "01";
|
|
-- elsif (rxtlp_firstdw_be ="0100") then
|
|
-- bit10(1 downto 0) <= "10";
|
|
-- elsif (rxtlp_firstdw_be ="1000") then
|
|
-- bit10(1 downto 0) <= "11";
|
|
-- elsif (rxtlp_firstdw_be ="0011") then
|
|
-- bit10(1 downto 0) <= "00";
|
|
-- elsif (rxtlp_firstdw_be ="1100") then
|
|
-- bit10(1 downto 0) <= "10";
|
|
-- elsif (rxtlp_firstdw_be ="1111") then
|
|
-- bit10(1 downto 0) <= "00";
|
|
-- else --this should never happen
|
|
-- bit10(1 downto 0) <= "00";
|
|
-- end if;
|
|
-- end if;
|
|
-- end process;
|
|
|
|
|
|
|
|
|
|
|
|