Line 4... |
Line 4... |
--
|
--
|
-- Create Date: 05/30/2010
|
-- Create Date: 05/30/2010
|
-- Modify date: 04/26/2011
|
-- 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.1
|
-- Version: 1.2
|
-- Project Name:
|
-- Project Name:
|
-- Target Devices: Xilinx Series-5/6/7 FPGAs
|
-- Target Devices: Xilinx Series-5/6/7 FPGAs (This code is tested on Spartan-6 XC6SLX45T)
|
-- 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
|
-- purpose of this file is to make a useable back-end interface and handle flow control
|
-- purpose of this file is to make a useable back-end interface and handle flow control
|
-- for the xilinx auto-generated PCIe endpoint IP.
|
-- for the xilinx auto-generated PCIe endpoint IP.
|
Line 38... |
Line 38... |
--
|
--
|
-- Dependencies: The CoreGenerator's configured PCIe core is included.
|
-- Dependencies: The CoreGenerator's configured PCIe core is included.
|
-- If we generate a new pcie endpoint, then copy the new files from the source
|
-- If we generate a new pcie endpoint, then copy the new files from the source
|
-- directory into the project's directory, and copy the generic section of the "pcie"
|
-- directory into the project's directory, and copy the generic section of the "pcie"
|
-- from the file: xilinx_pcie_1_1_ep_s6.vhd, into this file.
|
-- from the file: xilinx_pcie_1_1_ep_s6.vhd, into this file.
|
|
--
|
|
-- Device Type Migration:
|
|
-- This core should work on any Xilinx Series-5/6/7 FPGAs, but at now it runs on XC6SLX45T.
|
|
-- For a new device (not an XC6SLX45T) we have to regenerate the Coregenerator cores,
|
|
-- replace all BUFIO2/MGT/BUFG/BRAM (and other) to the chosen device's appropriate resources,
|
|
-- in both the VHDL and the UCF sources. Also in the UCF the BUFIO2 and MGT placements
|
|
-- will have to be re-specified with the appropriate resources/locations. The coregenerator
|
|
-- will have to be set up to generate cores with the same parameters and ports as they are
|
|
-- used here (to be useable as a drop-in replacement). Some resources are instantiated as
|
|
-- part of the Coregen cores, so they will be chosen by Coregen appropriately, we just need
|
|
-- to adjust their LOC placement constraints in the UCF file.
|
|
--
|
|
-- Coregenerator parameters:
|
|
-- PCIe-EP: Name=pcie, Type=LegacyPCIe-EP, BAR0=mem/256MB, BAR1+=off, ROM=off, Max Payload=512Bytes,
|
|
-- ASPM-L1=off, SlotCLK=off, IRQ=INTA, DeviceSpecInit=off, D1/D2=on, PME_from=D0,
|
|
-- Set D0 power (4W), DSN=enabled, PCI_ConfSp=off, PCIe_Extended_ConfSp=off,
|
|
-- no_scram =off, Xil_Refboard=None, RefClkFreq=125MHz, TranscLoc/Ch="leave default".
|
|
-- Blockram: Name=blk_mem_gen_v4_1, Type=SimpleDpRAM, WriteEn=off, Algor=MinArea,
|
|
-- WriteWidth=32, WriteDepth=512, Ena=AlwaysEnabled, ReadWidth=32, RegisterPorttB=off
|
|
-- LoadInitFile=off, Fill=off, UseRSTB=off.
|
|
--
|
-- Synthesis: Set the "FSM Encoding Algorithm" to "user".
|
-- Synthesis: Set the "FSM Encoding Algorithm" to "user".
|
--
|
--
|
-- Revision:
|
-- Revision:
|
-- Revision 0.01 - File Created
|
-- Revision 0.01 - File Created
|
|
|
Line 242... |
Line 263... |
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 rxstm_readytoroll : std_logic;
|
SIGNAL tlpstm_isin_idle : std_logic;
|
SIGNAL tlpstm_isin_idle : std_logic;
|
|
SIGNAL pcierx_detected : std_logic;
|
|
SIGNAL pcierx_detect_ff_clear : std_logic;
|
|
|
|
|
|
|
|
|
-- COMPONENT DECLARATIONS (introducing the IPs) --------------------------------
|
-- COMPONENT DECLARATIONS (introducing the IPs) --------------------------------
|
Line 940... |
Line 962... |
|
|
--fixed connections:
|
--fixed connections:
|
--trn_rnp_ok_ntrn_rnp_ok_n <= '0'; --ready to receive non-posted
|
--trn_rnp_ok_ntrn_rnp_ok_n <= '0'; --ready to receive non-posted
|
--not connected: trn_rerrfwd_n, trn_rsrc_dsc_n, trn_rbar_hit_n
|
--not connected: trn_rerrfwd_n, trn_rsrc_dsc_n, trn_rbar_hit_n
|
|
|
|
--RX detection flip-flop
|
|
process (pciewb_localreset_n, trn_clk)
|
|
begin
|
|
if (pciewb_localreset_n='0') then
|
|
pcierx_detected <= '0';
|
|
else
|
|
if (trn_clk'event and trn_clk = '1') then
|
|
if (pcie_just_received_a_new_tlp ='1') then
|
|
pcierx_detected <= '1';
|
|
elsif (pcierx_detect_ff_clear ='1') then
|
|
pcierx_detected <= '0';
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
|
|
|
|
|
-- flow control: INTERFACE TO THE PCIE-EP: - ----
|
-- flow control: INTERFACE TO THE PCIE-EP: - ----
|
Line 953... |
Line 990... |
|
|
|
|
|
|
|
|
|
|
|
|
-- --- GLUE LOGIC BETWEEN THE PCIE CORE-IF AND THE WB INTERFACES -----------------------
|
-- --- GLUE LOGIC BETWEEN THE PCIE CORE-IF AND THE WB INTERFACES -----------------------
|
-- --- ALSO TLP PACKET PROCESSING.
|
-- --- ALSO TLP PACKET PROCESSING.
|
--Theory of operation:
|
--Theory of operation:
|
--RX: If we receive a TLP (pcie_just_received_a_new_tlp goes high for one clock cycle),
|
--RX: If we receive a TLP (pcie_just_received_a_new_tlp goes high for one clock cycle),
|
--then store it (pcie_received_tlp), decode it (to figure out if its read request,
|
--then store it (pcie_received_tlp), decode it (to figure out if its read request,
|
Line 1009... |
Line 1047... |
--REQUESTER_ID------------------- tag------------ r lower_address
|
--REQUESTER_ID------------------- tag------------ r lower_address
|
|
|
|
|
--TLP-protocol statemachine:
|
--TLP-protocol statemachine:
|
process (pciewb_localreset_n, trn_clk, tlp_state,
|
process (pciewb_localreset_n, trn_clk, tlp_state,
|
pcie_just_received_a_new_tlp, tlp_datacount,
|
pcierx_detected, tlp_datacount,
|
bram_rxtlp_readdata, bram_txtlp_writeaddress, bram_rxtlp_readaddress,
|
bram_rxtlp_readdata, bram_txtlp_writeaddress, bram_rxtlp_readaddress,
|
tlp_state_copy, rxtlp_decodedaddress,
|
tlp_state_copy, rxtlp_decodedaddress,
|
rxtlp_header_dw1, rxtlp_header_dw2, rxtlp_header_dw3, rxtlp_header_dw4,
|
rxtlp_header_dw1, rxtlp_header_dw2, rxtlp_header_dw3, rxtlp_header_dw4,
|
bit10, rxtlp_firstdw_be, wb_transaction_complete, flag1, rxdw1_23_0, pcie_rxtlp_tag,
|
bit10, rxtlp_firstdw_be, wb_transaction_complete, flag1, rxdw1_23_0, pcie_rxtlp_tag,
|
tlp_payloadsize_dwords, pcie_bar0_wb_data_i_latched, cfg_completer_id,
|
tlp_payloadsize_dwords, pcie_bar0_wb_data_i_latched, cfg_completer_id,
|
Line 1044... |
Line 1082... |
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';
|
tlpstm_isin_idle <= '1';
|
|
pcierx_detect_ff_clear <= '0';
|
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 (pcierx_detected='1') then
|
tlp_state <= "00000001"; --to tlp decoding state
|
tlp_state <= "00000001"; --to tlp decoding state
|
tlpstm_isin_idle <= '0';
|
tlpstm_isin_idle <= '0';
|
else
|
else
|
tlpstm_isin_idle <= '1';
|
tlpstm_isin_idle <= '1';
|
end if;
|
end if;
|
Line 1081... |
Line 1120... |
tlp_payloadsize_dwords <= (others => '0');
|
tlp_payloadsize_dwords <= (others => '0');
|
rxtlp_firstdw_be <= (others => '0');
|
rxtlp_firstdw_be <= (others => '0');
|
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');
|
|
pcierx_detect_ff_clear <= '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
|
Line 1093... |
Line 1133... |
when "00000001" => --state 1
|
when "00000001" => --state 1
|
--latch the header:
|
--latch the header:
|
bram_rxtlp_readaddress <= bram_rxtlp_readaddress +1;
|
bram_rxtlp_readaddress <= bram_rxtlp_readaddress +1;
|
if (bram_rxtlp_readaddress = "000000010") then
|
if (bram_rxtlp_readaddress = "000000010") then
|
rxtlp_header_dw1 <= bram_rxtlp_readdata;
|
rxtlp_header_dw1 <= bram_rxtlp_readdata;
|
|
pcierx_detect_ff_clear <= '1';
|
elsif (bram_rxtlp_readaddress = "000000011") then
|
elsif (bram_rxtlp_readaddress = "000000011") then
|
rxtlp_header_dw2 <= bram_rxtlp_readdata;
|
rxtlp_header_dw2 <= bram_rxtlp_readdata;
|
elsif (bram_rxtlp_readaddress = "000000100") then
|
elsif (bram_rxtlp_readaddress = "000000100") then
|
rxtlp_header_dw3 <= bram_rxtlp_readdata;
|
rxtlp_header_dw3 <= bram_rxtlp_readdata;
|
|
pcierx_detect_ff_clear <= '0';
|
elsif (bram_rxtlp_readaddress = "000000101") then
|
elsif (bram_rxtlp_readaddress = "000000101") then
|
rxtlp_header_dw4 <= bram_rxtlp_readdata;
|
rxtlp_header_dw4 <= bram_rxtlp_readdata;
|
end if;
|
end if;
|
--decode some parameters:
|
--decode some parameters:
|
tlp_payloadsize_dwords <= rxtlp_header_dw1(7 downto 0);
|
tlp_payloadsize_dwords <= rxtlp_header_dw1(7 downto 0);
|
Line 1167... |
Line 1209... |
end if;
|
end if;
|
end if;
|
end if;
|
--* Write restart state *
|
--* Write restart state *
|
when "00010100" => --state 20
|
when "00010100" => --state 20
|
tlp_state <= "00000010";
|
tlp_state <= "00000010";
|
|
tlp_state_copy <= tlp_state;
|
|
|
|
|
--********** READ STATE **********
|
--********** READ STATE **********
|
--initiate WB read, then go to completion state
|
--initiate WB read, then go to completion state
|
when "00000011" => --state 3
|
when "00000011" => --state 3
|
Line 1199... |
Line 1242... |
end if;
|
end if;
|
--* read restart STATE *
|
--* read restart STATE *
|
when "00011110" => --state 30
|
when "00011110" => --state 30
|
tlp_state <= "00000011";
|
tlp_state <= "00000011";
|
bram_txtlp_we <= "0";
|
bram_txtlp_we <= "0";
|
|
tlp_state_copy <= tlp_state;
|
--intermediate state before completion (to ensure data latch at address-4)
|
--intermediate state before completion (to ensure data latch at address-4)
|
when "01111110" => --state 126
|
when "01111110" => --state 126
|
tlp_state <= "00000100";
|
tlp_state <= "00000100";
|
|
tlp_state_copy <= tlp_state;
|
bram_txtlp_writeaddress <= (OTHERS => '0');
|
bram_txtlp_writeaddress <= (OTHERS => '0');
|
--pre-write header-DW1:
|
--pre-write header-DW1:
|
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);
|