library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity pcie_rx is port ( clk : in std_logic; frame : in std_logic_vector(63 downto 0); sof : in std_logic; eof : in std_logic; valid : in std_logic; read : out std_logic := '0'; write : out std_logic := '0'; complete : out std_logic := '0'; data : out std_logic_vector(63 downto 0) := (others => '0'); address : out std_logic_vector(63 downto 3) := (others => '0'); tag : out std_logic_vector(4 downto 0) := (others => '0'); remote : out std_logic_vector(23 downto 0) := (others => '0'); bar0 : in std_logic ); end pcie_rx; architecture arch of pcie_rx is type state_t is (state_idle, state_read, state_write, state_write_head, state_complete, state_complete_head); signal fmt : std_logic_vector(1 downto 0); signal typ : std_logic_vector(4 downto 0); signal status : std_logic_vector(2 downto 0); begin fmt <= frame(62 downto 61); typ <= frame(60 downto 56); status <= frame(15 downto 13); process (clk) variable state : state_t := state_idle; variable extra : std_logic_vector(31 downto 0) := (others => '0'); begin if rising_edge(clk) then read <= '0'; write <= '0'; complete <= '0'; if valid = '0' then -- nothing elsif state = state_idle and sof = '1' then data <= (others => '0'); address <= (others => '0'); tag <= (others => '0'); if fmt = "00" and typ = "00000" and bar0 = '1' then state := state_read; remote <= frame(31 downto 8); elsif fmt = "10" and typ = "00000" and bar0 = '1' then state := state_write_head; elsif fmt = "10" and typ = "01010" and status = "000" then state := state_complete_head; end if; elsif state = state_read then state := state_idle; read <= '1'; address <= x"00000000" & frame(63 downto 35); elsif state = state_write_head then state := state_write; address <= x"00000000" & frame(63 downto 35); extra := frame(31 downto 0); elsif state = state_write then state := state_idle; write <= '1'; data <= extra & frame(63 downto 32); elsif state = state_complete_head then state := state_complete; tag <= frame(44 downto 40); extra := frame(31 downto 0); elsif state = state_complete then complete <= '1'; data <= extra & frame(63 downto 32); extra := frame(31 downto 0); end if; if valid = '1' and eof = '1' then state := state_idle; end if; end if; end process; end arch;