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

Subversion Repositories pcie_ds_dma

[/] [pcie_ds_dma/] [trunk/] [core/] [ds_dma64/] [pcie_src/] [pcie_core64_m1/] [pcie_ctrl/] [core64_rx_engine_m4.vhd] - Rev 2

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
--
-- Title       : core64_rx_engine_m4
-- Author      : Dmitry Smekhov
-- Company     : Instrumental Systems
-- E-mail      : dsmv@insys.ru
--
-- Version     : 1.1
--
-------------------------------------------------------------------------------
--
-- Description : Обработчик входящих пакетов 
--				 Модификация 4 - Spartan-6 
--
-------------------------------------------------------------------------------
--
--  Version 1.1		19.06.2012
--					Добавлено формирование byte_count
--
-------------------------------------------------------------------------------
 
 
library ieee;
use ieee.std_logic_1164.all;
 
use work.core64_type_pkg.all;
 
package core64_rx_engine_m4_pkg is
 
component core64_rx_engine_m4 is	 
	port(
 
		--- General ---
		rstp			: in std_logic;		--! 1 - сброс 
		clk				: in std_logic;		--! тактовая частота ядра - 250 MHz 
 
		trn_rx			: in  type_trn_rx;			--! приём пакета
		trn_rx_back		: out type_trn_rx_back;		--! готовность к приёму пакета
 
		reg_access		: out type_reg_access;		--! запрос на доступ к регистрам 
 
		rx_tx_engine	: out type_rx_tx_engine;	--! обмен RX->TX 
		tx_rx_engine	: in  type_tx_rx_engine;	--! обмен TX->RX 
 
		rx_ext_fifo		: out type_rx_ext_fifo		--! обмен RX->EXT_FIFO 
 
 
 
	);
end component;
 
end package;
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
use work.core64_type_pkg.all;
 
entity core64_rx_engine_m4 is	 
	port(
 
		--- General ---
		rstp			: in std_logic;		--! 1 - сброс 
		clk				: in std_logic;		--! тактовая частота ядра - 250 MHz 
 
		trn_rx			: in  type_trn_rx;			--! приём пакета
		trn_rx_back		: out type_trn_rx_back;		--! готовность к приёму пакета
 
		reg_access		: out type_reg_access;		--! запрос на доступ к регистрам 
 
		rx_tx_engine	: out type_rx_tx_engine;	--! обмен RX->TX 
		tx_rx_engine	: in  type_tx_rx_engine;	--! обмен TX->RX 
 
		rx_ext_fifo		: out type_rx_ext_fifo		--! обмен RX->EXT_FIFO 
 
 
 
	);
end core64_rx_engine_m4;
 
 
architecture core64_rx_engine_m4 of core64_rx_engine_m4 is
 
 
component ctrl_fifo64x37st is
  port (
    clk : in std_logic;
    rst : in std_logic;
    din : in std_logic_vector(36 downto 0);
    wr_en : in std_logic;
    rd_en : in std_logic;
    dout : out std_logic_vector(36 downto 0);
    full : out std_logic;
    empty : out std_logic;
    valid : out std_logic;
    prog_full : out std_logic;
    prog_empty : out std_logic
  );
end component;
 
 
signal	rstpz			: std_logic;
 
type	stp_type		is ( s0, s1, s2, s3, s31, s32, s33, s34, s35, s36, s37, s38, s39, s4, s5 );
signal	stp				: stp_type;
 
type	stf_type		is ( s0, s1, s2, s3, s31, s4, s5, s6 );
signal	stf				: stf_type;
 
signal  trn_rdst_rdy_n 			: std_logic;
signal  trn_rnp_ok_n 			: std_logic;
signal  trn_rcpl_streaming_n    : std_logic;
 
signal	tlp_dw0					: std_logic_vector( 31 downto 0 );
signal	tlp_dw1					: std_logic_vector( 31 downto 0 );
signal	tlp_dw2					: std_logic_vector( 31 downto 0 );
signal	tlp_dw3					: std_logic_vector( 31 downto 0 );
 
signal	trn_data				: std_logic_vector( 63 downto 0 );
signal	trn_data_we				: std_logic;
 
signal	tlp_cnt					: std_logic_vector( 5 downto 0 );
 
signal	request_reg_wr			: std_logic;		  
signal	request_reg_rd			: std_logic;
signal	tlp_complete			: std_logic;	
signal	bar						: std_logic_vector( 1 downto 0 );
 
signal	fifo_wr					: std_logic;
signal	fifo_wr_z				: std_logic;
signal	fifo_din				: std_logic_vector( 36 downto 0 );
 
signal	fifo0_wr				: std_logic;
signal	fifo0_wr_en				: std_logic;
signal	fifo0_wr_en_z			: std_logic;
signal	fifo0_rd				: std_logic;
signal	fifo0_full				: std_logic;
signal	fifo0_empty				: std_logic;
signal	fifo0_valid				: std_logic;
signal	fifo0_paf				: std_logic;
signal	fifo0_pae				: std_logic;
signal	fifo0_dout				: std_logic_vector( 36 downto 0 );
 
signal	fifo1_wr				: std_logic;
signal	fifo1_wr_en				: std_logic;
signal	fifo1_wr_en_z			: std_logic;
signal	fifo1_rd				: std_logic;
signal	fifo1_rd_x				: std_logic;
signal	fifo1_full				: std_logic;
signal	fifo1_empty				: std_logic;
signal	fifo1_valid				: std_logic;
signal	fifo1_paf				: std_logic;
signal	fifo1_pae				: std_logic;
signal	fifo1_dout				: std_logic_vector( 36 downto 0 );
 
signal	data_rx					: std_logic_vector( 63 downto 0 );
signal	data_rx_we				: std_logic;
signal	data_rx_we_en			: std_logic;
signal	data_lrx				: std_logic_vector( 31 downto 0 );
signal	data_hrx				: std_logic_vector( 31 downto 0 );
 
signal	tlp_cp_dw0				: std_logic_vector( 31 downto 0 );
signal	tlp_cp_dw1				: std_logic_vector( 31 downto 0 );
signal	tlp_cp_dw2				: std_logic_vector( 31 downto 0 );
signal	tlp_cp_dw3				: std_logic_vector( 31 downto 0 );
 
signal	adr_rx					: std_logic_vector( 8 downto 0 );
signal	adr_cnt					: std_logic_vector( 3 downto 0 );
 
signal	flag_rx_we				: std_logic;
 
signal	byte_count				: std_logic_vector( 2 downto 0 );
 
begin
 
rstpz <= rstp after 1 ns when rising_edge( clk );	
 
trn_rx_back.trn_rdst_rdy_n 			  <= trn_rdst_rdy_n;
trn_rx_back.trn_rnp_ok_n 			  <= trn_rnp_ok_n; 			
trn_rx_back.trn_rcpl_streaming_n      <= trn_rcpl_streaming_n;    
 
trn_rnp_ok_n <= '0';
trn_rcpl_streaming_n <= '0';
 
trn_rdst_rdy_n <= fifo0_paf or fifo1_paf;
 
fifo_wr <= not ( trn_rx.trn_rsrc_rdy_n or trn_rdst_rdy_n );
fifo_wr_z <= fifo_wr after 1 ns when rising_edge( clk );
 
fifo_din  <= not trn_rx.trn_rbar_hit_n(1) & not trn_rx.trn_rbar_hit_n(0) & 
				  trn_rx.trn_rerrfwd_n & trn_rx.trn_reof_n & trn_rx.trn_rsof_n & 
				  trn_rx.trn_rd( 31 downto 0 ) after 1 ns when rising_edge( clk );
 
pr_fifo0_wr: process( clk ) begin
	if( rising_edge( clk ) ) then
		if( rstpz='1' or (fifo_wr='1' and trn_rx.trn_reof_n='0' ) ) then
			fifo0_wr_en <= '0' after 1 ns;
		elsif( fifo_wr='1' and  trn_rx.trn_rd(31)='0' and trn_rx.trn_rd(29 downto 25)="00000" and trn_rx.trn_rsof_n='0' ) then
			fifo0_wr_en <= '1' after 1 ns;
		end if;
	end if;
end process;
 
fifo0_wr_en_z <= fifo0_wr_en after 1 ns when rising_edge( clk );
 
fifo0_wr <= fifo_wr_z and (fifo0_wr_en or fifo0_wr_en_z);
 
fifo0_reg: ctrl_fifo64x37st 
  port map(
    clk 		=> clk,
    rst 		=> rstpz,
    din 		=> fifo_din, 
    wr_en 		=> fifo0_wr,
    rd_en 		=> fifo0_rd,
    dout 		=> fifo0_dout, 
    full 		=> fifo0_full,
    empty 		=> fifo0_empty,
    valid 		=> fifo0_valid,
    prog_full 	=> fifo0_paf,
    prog_empty 	=> fifo0_pae
  );
 
 
pr_fifo1_wr: process( clk ) begin
	if( rising_edge( clk ) ) then
		if( rstpz='1' or (fifo_wr='1' and trn_rx.trn_reof_n='0' ) ) then
			fifo1_wr_en <= '0' after 1 ns;
		elsif( fifo_wr='1' and  trn_rx.trn_rd(31 downto 25)="0100101" and trn_rx.trn_rsof_n='0' ) then
			fifo1_wr_en <= '1' after 1 ns;
		end if;
	end if;
end process;
 
fifo1_wr_en_z <= fifo1_wr_en after 1 ns when rising_edge( clk );
 
fifo1_wr <= fifo_wr_z and (fifo1_wr_en or fifo1_wr_en_z);
 
fifo1_cmpl: ctrl_fifo64x37st 
  port map(
    clk 		=> clk,
    rst 		=> rstpz,
    din 		=> fifo_din, 
    wr_en 		=> fifo1_wr,
    rd_en 		=> fifo1_rd_x,
    dout 		=> fifo1_dout, 
    full 		=> fifo1_full,
    empty 		=> fifo1_empty,
    valid 		=> fifo1_valid,
    prog_full 	=> fifo1_paf,
    prog_empty 	=> fifo1_pae
  );
 
 
 
fifo1_rd_x <= fifo1_rd and ( not ( data_rx_we_en  and not fifo1_dout(33) ) );
 
reg_access.adr <= tlp_dw2;
 
reg_access.data( 7 downto 0 )   <= tlp_dw3( 31 downto 24 );
reg_access.data( 15 downto 8 )  <= tlp_dw3( 23 downto 16 );
reg_access.data( 23 downto 16 ) <= tlp_dw3( 15 downto 8 );
reg_access.data( 31 downto 24 ) <= tlp_dw3( 7 downto 0 );
 
reg_access.req_wr(0) <=request_reg_wr and bar(0);
reg_access.req_wr(1) <=request_reg_wr and bar(1);
reg_access.req_rd(0) <=request_reg_rd and ( bar(0) or ( not (bar(0) or bar(1)) ) );
reg_access.req_rd(1) <=request_reg_rd and bar(1);
 
bar(0) <= fifo0_dout(35);
bar(1) <= fifo0_dout(36);
 
rx_tx_engine.request_reg_wr <= request_reg_wr;
rx_tx_engine.request_reg_rd <= request_reg_rd;
rx_tx_engine.request_tag <= tlp_dw1( 15 downto 8 );
rx_tx_engine.request_tc  <= tlp_dw0( 22 downto 20 );
rx_tx_engine.request_attr <= tlp_dw0( 7 downto 4 );
rx_tx_engine.request_id <= tlp_dw1( 31 downto 16 );	   
rx_tx_engine.lower_adr <= tlp_dw2( 6 downto 2 );
 
rx_tx_engine.byte_count <= byte_count after 1 ns when rising_edge( clk );
 
byte_count <= "000" when request_reg_rd='0' else
			  "100" when tlp_dw1( 3 downto 0 )="1111" else
			  "010" when tlp_dw1( 3 downto 0 )="0011" or tlp_dw1( 3 downto 0 )="0110" or tlp_dw1( 3 downto 0 )="1100" else
			  "001";-- when tlp_dw1( 3 downto 0 )="0001" or tlp_dw1( 3 downto 0 )="0010" or tlp_dw1( 3 downto 0 )="0100" or tlp_dw1( 3 downto 0 )="1000" 
 
 
 
pr_stp: process( clk ) begin
	if( rising_edge( clk ) ) then
 
		case( stp ) is
			when s0 =>
				if( fifo0_empty='0' ) then
					stp <= s1 after 1 ns;
				end if;				
				request_reg_wr <= '0' after 1 ns;
				request_reg_rd <= '0' after 1 ns;
				fifo0_rd <= '0' after 1 ns;
 
			when s1 => 
					stp <= s2 after 1 ns;
					fifo0_rd <= '1' after 1 ns;
 
			when s2 =>	
					stp <= s3 after 1 ns;
					fifo0_rd <= '0' after 1 ns;
 
			when s3 =>					  
					tlp_dw0 <= fifo0_dout( 31 downto 0 ) after 1 ns;
					if( fifo0_empty='0' ) then
						stp <= s31 after 1 ns;
					end if;
 
			when s31 =>
					fifo0_rd <= '1' after 1 ns;
					stp <= s32 after 1 ns;	  
 
			when s32 =>
					fifo0_rd <= '0' after 1 ns;
					stp <= s33 after 1 ns;	
 
 
			when s33 =>					  
					tlp_dw1 <= fifo0_dout( 31 downto 0 ) after 1 ns;
					if( fifo0_empty='0' ) then
						stp <= s34 after 1 ns;
					end if;
 
			when s34 =>
					fifo0_rd <= '1' after 1 ns;
					stp <= s35 after 1 ns;	  
 
			when s35 =>
					fifo0_rd <= '0' after 1 ns;
					if( tlp_dw0(30)='1' ) then
						stp <= s36 after 1 ns;
					else
						stp <= s4 after 1 ns;
					end if;
 
			when s36 =>
					tlp_dw2 <= fifo0_dout( 31 downto 0 ) after 1 ns;
					if( fifo0_empty='0' ) then
						stp <= s37 after 1 ns;
					end if;	
 
			when s37 =>
					fifo0_rd <= '1' after 1 ns;
					stp <= s38 after 1 ns;
 
			when s38 =>
					fifo0_rd <= '0' after 1 ns;
					stp <= s39 after 1 ns;
 
			when s39 =>
					tlp_dw3 <= fifo0_dout( 31 downto 0 ) after 1 ns;
					request_reg_wr <= '1' after 1 ns;
					stp <= s5 after 1 ns;
 
			when s4 => 
					tlp_dw2 <= fifo0_dout( 31 downto 0 ) after 1 ns;
					request_reg_rd <= '1' after 1 ns;
					stp <= s5 after 1 ns;
 
			when s5 =>
					if( tx_rx_engine.complete_reg='1' ) then
						stp <= s0 after 1 ns;
					end if;
 
		end case;
 
 
 
		if( rstpz='1' ) then
			stp <= s0 after 1 ns;
		end if;
 
	end if;
end process;
 
 
pr_stf: process( clk ) begin
 
	if( rising_edge( clk ) ) then
 
		case( stf ) is
 
			when s0 => 
			--if( fifo1_empty='0' ) then
				if( fifo1_pae='0' ) then
					stf <= s1 after 1 ns;
				end if;
				fifo1_rd <= '0' after 1 ns;		
				data_rx_we_en	<= '0' after 1 ns;
 
			when s1 =>
				fifo1_rd <= '1' after 1 ns;
				stf <= s2 after 1 ns;
 
			when s2 => 
				stf <= s3 after 1 ns;
 
			when s3 =>					  
					tlp_cp_dw0   <= fifo1_dout( 31 downto 0 ) after 1 ns;
					stf <= s31 after 1 ns;	  
 
			when s31 =>
					tlp_cp_dw1 <= fifo1_dout( 31 downto 0 ) after 1 ns; 
					fifo1_rd <= '0' after 1 ns;
					stf <= s4 after 1 ns;
 
			when s4 =>					
					tlp_cp_dw2 <= fifo1_dout( 31 downto 0 ) after 1 ns;
					if( tlp_cp_dw0( 30 )='1' ) then
						stf <= s5 after 1 ns;	-- есть данные --
					else
						stf <= s6 after 1 ns;	-- нет данных --
					end if;
 
 
			when s5 =>
 
					if( fifo1_dout(33)='0' and fifo1_valid='1' ) then
						stf <= s6 after 1 ns;  
						fifo1_rd <= '0' after 1 ns;		  
						data_rx_we_en	<= '0' after 1 ns;
					else
						fifo1_rd <= '1' after 1 ns;
						data_rx_we_en	<= '1' after 1 ns;
					end if;
 
			when s6 => 
					stf <= s0 after 1 ns;
 
 
 
		end case;
 
		if( rstpz='1' ) then
			stf <= s0 after 1 ns;
		end if;
 
	end if;
 
 
end process;
 
pr_flag_rx_we: process( clk ) begin
	if( rising_edge( clk ) ) then
		if( stf=s0 ) then
			flag_rx_we <= '0' after 1 ns;
		elsif( data_rx_we='1' ) then
			flag_rx_we <= not flag_rx_we after 1 ns;
		end if;
	end if;
end process;
 
 
data_rx_we <= fifo1_valid and data_rx_we_en;
 
data_lrx <= fifo1_dout( 31 downto 0 ) after 1 ns when rising_edge( clk ) and fifo1_valid='1';
data_hrx <= fifo1_dout( 31 downto 0 );
 
data_rx( 32+31 downto 32+24 )  <= data_hrx( 7 downto 0 ); 
data_rx( 32+23 downto 32+16 )  <= data_hrx( 15 downto 8 ); 
data_rx( 32+15 downto 32+8 )   <= data_hrx( 23 downto 16 ); 
data_rx( 32+7 downto 32+0 )    <= data_hrx( 31 downto 24 ); 
 
 
data_rx( 31 downto 24 )  <= data_lrx( 7 downto 0 ); 
data_rx( 23 downto 16 )  <= data_lrx( 15 downto 8 ); 
data_rx( 15 downto 8 )   <= data_lrx( 23 downto 16 ); 
data_rx( 7 downto 0 )    <= data_lrx( 31 downto 24 ); 
 
pr_adr_cnt: process( clk ) begin
	if( rising_edge( clk ) ) then
		if( stf/=s5 ) then
			adr_cnt <= "0000" after 1 ns;
		elsif( data_rx_we='1' and flag_rx_we='1' ) then
			adr_cnt( 2 downto 0 ) <= adr_cnt( 2 downto 0 ) + 1 after 1 ns;
			if( adr_cnt( 2 downto 0 )="111" ) then
				adr_cnt( 3 ) <= '1' after 1 ns;
			end if;
		end if;
	end if;
end process;	
 
adr_rx( 2 downto 0 ) <= adr_cnt( 2 downto 0 );
adr_rx( 3 ) <=  tlp_cp_dw2(6) or adr_cnt( 3 );
adr_rx( 8 downto 4 ) <= tlp_cp_dw2( 12 downto 8 );
 
rx_ext_fifo.adr <= adr_rx after 1 ns when rising_edge( clk );
rx_ext_fifo.data <= data_rx after 1 ns when rising_edge( clk );
rx_ext_fifo.data_we <= data_rx_we and flag_rx_we after 1 ns when rising_edge( clk );
 
rx_tx_engine.complete_we <= data_rx_we and flag_rx_we after 1 ns when rising_edge( clk );
 
end core64_rx_engine_m4;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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