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

Subversion Repositories pcie_mini

[/] [pcie_mini/] [trunk/] [main_sources/] [xilinx_pcie2wb.vhd] - Diff between revs 8 and 9

Show entire file | Details | Blame | View Log

Rev 8 Rev 9
Line 4... Line 4...
-- 
-- 
-- Create Date:    05/30/2010
-- Create Date:    05/30/2010
-- Modify date:    08/10/2012
-- Modify date:    08/10/2012
-- Design Name:    pcie_mini
-- Design Name:    pcie_mini
-- Module Name:    xilinx_pcie2wb - Behavioral 
-- Module Name:    xilinx_pcie2wb - Behavioral 
-- Version:        1.2
-- Version:        1.4
-- 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 44... Line 44...
--
--
-- Revision: 
-- Revision: 
-- Revision 1.0 - File Created by Istvan Nagy
-- Revision 1.0 - File Created by Istvan Nagy
-- Revision 1.1 - some fixes by Istvan Nagy
-- Revision 1.1 - some fixes by Istvan Nagy
-- Revision 1.2 - interrupt fix by Stephen Battazzo
-- Revision 1.2 - interrupt fix by Stephen Battazzo
 
-- Revision 1.3 - 64-bit read fix, support for unaligned 32-bit read, and custom BAR0 address space size by Scott Cogan, FRIB
 
-- Revision 1.4 - Compatibility for MSI and Legacy interrupts by Scott Cogan, FRIB
--
--
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
 
 
library IEEE;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_1164.ALL;
Line 60... Line 62...
use UNISIM.VComponents.all;
use UNISIM.VComponents.all;
 
 
 
 
 
 
entity xilinx_pcie2wb is
entity xilinx_pcie2wb is
 
        generic (
 
                -- BAR0_WIDTH = 28 sets address space for 2^28 bytes = 256MB, BARO = x"F0000000"
 
                -- BAR0_WIDTH = 22 sets address space for 2^22 bytes = 4MB,   BARO = x"FFC00000"
 
                BAR0            : bit_vector := x"FFC00000";
 
                BAR0_WIDTH      : integer    := 22
 
        );
    Port ( --FPGA PINS(EXTERNAL):
    Port ( --FPGA PINS(EXTERNAL):
                         pci_exp_txp             : out std_logic;
                         pci_exp_txp             : out std_logic;
                         pci_exp_txn             : out std_logic;
                         pci_exp_txn             : out std_logic;
                         pci_exp_rxp             : in  std_logic;
                         pci_exp_rxp             : in  std_logic;
                         pci_exp_rxn             : in  std_logic;
                         pci_exp_rxn             : in  std_logic;
Line 81... Line 89...
                         pcie_bar0_wb_ack_i : in std_logic;
                         pcie_bar0_wb_ack_i : in std_logic;
                         pcie_bar0_wb_clk_o : out std_logic; --62.5MHz          
                         pcie_bar0_wb_clk_o : out std_logic; --62.5MHz          
                         pcie_bar0_wb_sel_o : out std_logic_vector(3 downto 0);
                         pcie_bar0_wb_sel_o : out std_logic_vector(3 downto 0);
                         --OTHER:
                         --OTHER:
                         pcie_irq : in std_logic;
                         pcie_irq : in std_logic;
 
                         pcie_msi_enabled : out std_logic;      -- added to monitor if MSI interrupt is enabled
                         pcie_resetout  : out std_logic --active high
                         pcie_resetout  : out std_logic --active high
                        );
                        );
end xilinx_pcie2wb;
end xilinx_pcie2wb;
 
 
 
 
Line 211... Line 220...
    SIGNAL   pcie_tlp_tx_complete       :  std_logic;
    SIGNAL   pcie_tlp_tx_complete       :  std_logic;
 
 
         --this signal added by StBa, AAC Microtec
         --this signal added by StBa, AAC Microtec
         SIGNAL  irq_prohibit    :   std_logic;
         SIGNAL  irq_prohibit    :   std_logic;
 
 
         SIGNAL  pcieirq_state    :  std_logic_vector(7 downto 0);
         SIGNAL  pcieirq_state    :  std_logic_vector(2 downto 0);
         SIGNAL  txtrn_counter   :  std_logic_vector(7 downto 0);
         SIGNAL  txtrn_counter   :  std_logic_vector(7 downto 0);
         SIGNAL  trn_rx_counter   :  std_logic_vector(7 downto 0);
         SIGNAL  trn_rx_counter   :  std_logic_vector(7 downto 0);
         SIGNAL cfg_completer_id  :  std_logic_vector(15 downto 0);
         SIGNAL cfg_completer_id  :  std_logic_vector(15 downto 0);
         SIGNAL wb0_state :   std_logic_vector(7 downto 0);
         SIGNAL wb0_state :   std_logic_vector(7 downto 0);
         SIGNAL epif_tx_state :   std_logic_vector(7 downto 0);
         SIGNAL epif_tx_state :   std_logic_vector(7 downto 0);
Line 274... Line 283...
    VC0_TOTAL_CREDITS_PD              : integer    := 211;
    VC0_TOTAL_CREDITS_PD              : integer    := 211;
    VC0_TOTAL_CREDITS_NPH             : integer    := 8;
    VC0_TOTAL_CREDITS_NPH             : integer    := 8;
    VC0_TOTAL_CREDITS_CH              : integer    := 40;
    VC0_TOTAL_CREDITS_CH              : integer    := 40;
    VC0_TOTAL_CREDITS_CD              : integer    := 211;
    VC0_TOTAL_CREDITS_CD              : integer    := 211;
    VC0_CPL_INFINITE                  : boolean    := TRUE;
    VC0_CPL_INFINITE                  : boolean    := TRUE;
    BAR0                              : bit_vector := x"F0000000";
    BAR0                              : bit_vector := BAR0; --x"F0000000";
    BAR1                              : bit_vector := x"00000000";
    BAR1                              : bit_vector := x"00000000";
    BAR2                              : bit_vector := x"00000000";
    BAR2                              : bit_vector := x"00000000";
    BAR3                              : bit_vector := x"00000000";
    BAR3                              : bit_vector := x"00000000";
    BAR4                              : bit_vector := x"00000000";
    BAR4                              : bit_vector := x"00000000";
    BAR5                              : bit_vector := x"00000000";
    BAR5                              : bit_vector := x"00000000";
Line 1152... Line 1161...
 
 
 
 
                --********** WRITE STATE **********
                --********** WRITE STATE **********
                                         --initiate WB write(s) (1...N DWORD accesses)
                                         --initiate WB write(s) (1...N DWORD accesses)
                when "00000010" =>   --state 2
                when "00000010" =>   --state 2
                                                pcie_bar0_wb_addr_o_feed(27 downto 2) <= rxtlp_decodedaddress(27 downto 2) + tlp_datacount -1; --256MBytes size is hardcoded here, by cutting 4-MSB off
                                                pcie_bar0_wb_addr_o_feed(BAR0_WIDTH-1 downto 2) <= rxtlp_decodedaddress(BAR0_WIDTH-1 downto 2) + tlp_datacount -1; -- BAR0 size is hardcoded here, by cutting MSB's off
                                                pcie_bar0_wb_addr_o_feed(1 downto 0) <= bit10(1 downto 0);
                                                pcie_bar0_wb_addr_o_feed(1 downto 0) <= bit10(1 downto 0);
                                                pcie_bar0_wb_sel_o_feed  <= rxtlp_firstdw_be;
                                                pcie_bar0_wb_sel_o_feed  <= rxtlp_firstdw_be;
                                                pcie_bar0_wb_data_o_feed <= bram_rxtlp_readdata;
                                                pcie_bar0_wb_data_o_feed <= bram_rxtlp_readdata;
                                                tlp_state_copy <= tlp_state;
                                                tlp_state_copy <= tlp_state;
                                                if (tlp_state_copy = tlp_state) then
                                                if (tlp_state_copy = tlp_state) then
Line 1180... Line 1189...
 
 
 
 
                --********** 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
                                                pcie_bar0_wb_addr_o_feed(27 downto 2) <= rxtlp_decodedaddress(27 downto 2) + tlp_datacount -1;
                                                pcie_bar0_wb_addr_o_feed(BAR0_WIDTH-1 downto 2) <= rxtlp_decodedaddress(BAR0_WIDTH-1 downto 2) + tlp_datacount -1;
                                                pcie_bar0_wb_addr_o_feed(1 downto 0) <= bit10(1 downto 0);
                                                pcie_bar0_wb_addr_o_feed(1 downto 0) <= bit10(1 downto 0);
                                                pcie_bar0_wb_sel_o_feed  <= rxtlp_firstdw_be;
                                                pcie_bar0_wb_sel_o_feed  <= rxtlp_firstdw_be;
                                                tlp_state_copy <= tlp_state;
                                                tlp_state_copy <= tlp_state;
                                                if (tlp_state_copy = tlp_state) then
                                                if (tlp_state_copy = tlp_state) then
                                                  start_read_wb0 <= '0';
                                                  start_read_wb0 <= '0';
Line 1197... Line 1206...
                                                        if (tlp_payloadsize_dwords = tlp_datacount)then
                                                        if (tlp_payloadsize_dwords = tlp_datacount)then
                                                          tlp_state <= "01111110"; --read completion
                                                          tlp_state <= "01111110"; --read completion
                                                          --bram_txtlp_writeaddress remains the same to capture data in next clock cycle
                                                          --bram_txtlp_writeaddress remains the same to capture data in next clock cycle
                                                        else
                                                        else
                                                          tlp_state <= "00011110"; --one more wb read
                                                          tlp_state <= "00011110"; --one more wb read
                                                          bram_txtlp_writeaddress <= bram_txtlp_writeaddress +1;
 
                                                          tlp_datacount <= tlp_datacount +1;
                                                          tlp_datacount <= tlp_datacount +1;
                                                        end if;
                                                        end if;
                                                else
                                                else
                                                  bram_txtlp_we <= "0";
                                                  bram_txtlp_we <= "0";
                                                end if;
                                                end if;
                --* read restart STATE  *
                --* read restart STATE  *
                when "00011110" =>   --state 30
                when "00011110" =>   --state 30
 
                                                tlp_state_copy <= tlp_state;    -- SC:  required to re-trigger additional reads, start_read_wb0 <= '1'
 
                                                bram_txtlp_writeaddress <= bram_txtlp_writeaddress +1;  -- SC: increment address here (moved)
                                                tlp_state <= "00000011";
                                                tlp_state <= "00000011";
                                                bram_txtlp_we <= "0";
                                                bram_txtlp_we <= "0";
                --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";
Line 1378... Line 1388...
        --prohibit IRQ assert when TLP state machine not idle.
        --prohibit IRQ assert when TLP state machine not idle.
        -- if an IRQ is asserted between a read request and completion, it causes an error in the endpoint block.
        -- if an IRQ is asserted between a read request and completion, it causes an error in the endpoint block.
        -- added by StBa, AAC Microtec, 2012
        -- added by StBa, AAC Microtec, 2012
        irq_prohibit <= not tlpstm_isin_idle;
        irq_prohibit <= not tlpstm_isin_idle;
 
 
 
        -- fixed compatibility with both MSI interrupts and legacy interrupts
 
        -- added by SC, FRIB, 2016
 
        pcie_msi_enabled <= cfg_interrupt_msienable;
 
 
    process (pciewb_localreset_n, trn_clk, pcie_irq, pcieirq_state,
    process (pciewb_localreset_n, trn_clk, pcie_irq, pcieirq_state,
                                cfg_interrupt_rdy_n)
                                cfg_interrupt_rdy_n)
    begin
    begin
    if (pciewb_localreset_n='0') then
    if (pciewb_localreset_n='0') then
       pcieirq_state <= "00000000";
       pcieirq_state <= "000";
       cfg_interrupt_n <= '1';
       cfg_interrupt_n <= '1';
                 cfg_interrupt_assert_n_1 <= '1';
                 cfg_interrupt_assert_n_1 <= '1';
    else
    else
      if (trn_clk'event and trn_clk = '1') then
      if (trn_clk'event and trn_clk = '1') then
                case ( pcieirq_state ) is
                case ( pcieirq_state ) is
 
 
                --********** idle STATE  **********
                --********** idle STATE  **********
                when "00000000" =>   --state 0        
                        when "000" =>   --state 0        
                    if (pcie_irq = '1' and irq_prohibit = '0') then
 
                                                    pcieirq_state <= "00000001";
 
                                                         cfg_interrupt_n <= '0'; --active
 
                                                  else
 
                                                    cfg_interrupt_n <= '1'; --inactive
                                                    cfg_interrupt_n <= '1'; --inactive
 
                                cfg_interrupt_assert_n_1 <= '1'; --0=assert, 1=deassert
 
                                if (pcie_irq = '1') then
 
                                        pcieirq_state <= "001";
                                                  end if;
                                                  end if;
 
                                --********** wait for not irq_prohibit **********
 
                        when "001" =>   --state 1        
 
                                if (irq_prohibit = '0') then
 
                                        pcieirq_state <= "010";
 
                                        cfg_interrupt_n <= '0'; --active
                                                  cfg_interrupt_assert_n_1 <= '0'; --0=assert, 1=deassert
                                                  cfg_interrupt_assert_n_1 <= '0'; --0=assert, 1=deassert
 
                                end if;
                --********** assert STATE ********** 
                --********** assert STATE ********** 
                when "00000001" =>   --state 1
                        when "010" =>   --state 2
 
                                cfg_interrupt_n <= '0';  --request INTA assertion
                                                 if (cfg_interrupt_rdy_n ='0') then --ep accepted it
                                                 if (cfg_interrupt_rdy_n ='0') then --ep accepted it
                                                         cfg_interrupt_n <= '1'; --deassert the request 
                                                         cfg_interrupt_n <= '1'; --deassert the request 
                                                         pcieirq_state <= "00000010";
                                        cfg_interrupt_assert_n_1 <= '1'; --0=assert, 1=deassert
                                                 else
                                        pcieirq_state <= "011"; -- wait for IRQ deassert
                                                         cfg_interrupt_n <= '0'; --request INTA assertion
 
                                                 end if;
                                                 end if;
 
                                --********** (LEGACY) pcie_irq kept asserted STATE **********                                    
                --********** pcie_irq kept asserted STATE **********                                     
                        when "011" =>   --state 3
                when "00000010" =>   --state 2
                                if (pcie_irq='0' and irq_prohibit='0' and cfg_interrupt_msienable='0') then
                    if (pcie_irq = '0' and irq_prohibit='0') then --pcie_irq gets deasserted
                                        pcieirq_state <= "100"; -- LEGACY, pcie_irq gets deasserted
                                                    pcieirq_state <= "00000011";
                                end if;
 
                                if (pcie_irq='0' and cfg_interrupt_msienable='1') then
 
                                        pcieirq_state <= "000"; -- MSI IRQ, back to IDLE when pcie_irq deasserted
                                                  end if;
                                                  end if;
                                                 cfg_interrupt_n <= '1'; --inactive     
                                                 cfg_interrupt_n <= '1'; --inactive     
                                                 cfg_interrupt_assert_n_1 <= '1'; --0=assert, 1=deassert
                                                 cfg_interrupt_assert_n_1 <= '1'; --0=assert, 1=deassert
 
 
                --********** DEassert STATE ********** 
                --********** DEassert STATE ********** 
                when "00000011" =>   --state 3
                        -- below state only used for legacy interrupts
 
                        when "100" =>   --state 4
 
                                cfg_interrupt_n <= '0';  --request INTA DEassertion
                                                 if (cfg_interrupt_rdy_n ='0') then --ep accepted it
                                                 if (cfg_interrupt_rdy_n ='0') then --ep accepted it
                                                         cfg_interrupt_n <= '1'; --deassert the request 
                                                         cfg_interrupt_n <= '1'; --deassert the request 
                                                         pcieirq_state <= "00000000";
                                        pcieirq_state <= "000";
                                                 else
 
                                                         cfg_interrupt_n <= '0'; --request INTA DEassertion
 
                                                 end if;
                                                 end if;
 
 
                                                 when others => --error
                                                 when others => --error
                      pcieirq_state <= "00000000"; --go to state 0
                                pcieirq_state <= "000"; --go to state 0
                end case;
                end case;
       end if;
       end if;
    end if;
    end if;
    end process;
    end process;
 
 

powered by: WebSVN 2.1.0

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