⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utopia_master_rx.vhd

📁 utopia主模式发送和接收 主要针对5384
💻 VHD
📖 第 1 页 / 共 2 页
字号:
---------------------------------------------------------------------------------------------------
--
-- Title       : utopia_master_rx.vhd
-- Design      : 
                           
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;

entity utopia_master_rx is 
  	port (

    	RST          	: 	in  std_logic;
    	----------------UTOPIA RX INTERFACE---------------------------------------------- 
    	PM5384_RFCLK 	: 	in  std_logic;
    	PM5384_RSOC  	: 	in  std_logic;
    	PM5384_RDATA 	: 	in  std_logic_vector(15 downto 0);
    	PM5384_RADR  	: 	out std_logic_vector(4 downto 0);
    	PM5384_RENB  	: 	out std_logic;
    	PM5384_RCA   	: 	in  std_logic;

    	PollAddr_S    	: 	in  std_logic_vector(4 downto 0);
    	PollAddr_E    	: 	in  std_logic_vector(4 downto 0);
    	Module_En     	: 	in  std_logic;
    	----------------FIFO INTERFACE ---------------------------------------------------
    	FIFO_DATA     	: 	out std_logic_vector(15 downto 0);
    	FIFO_WRUSEDW0 	: 	in  std_logic_vector(6 downto 0);
    	FIFO_WRUSEDW1 	: 	in  std_logic_vector(6 downto 0);
    	FIFO_WRUSEDW2 	: 	in  std_logic_vector(6 downto 0);
    	FIFO_WRUSEDW3 	: 	in  std_logic_vector(6 downto 0);
    	FIFO_WRREQ    	: 	out std_logic_vector(3 downto 0);
    	----------------FOR TEST  -----------------------------------------------------------
    	detection		:	out	std_logic;
    	TST_SM        	: 	out std_logic_vector(2 downto 0)    	
    	);                        

end utopia_master_rx;
architecture bhv of utopia_master_rx is
type SM is(
    sm_rx_en,                           -- TST_SM <= "111";      
    sm_rx_wait,
    sm_rx_s0,                           -- TST_SM <= "000";
    sm_rx_s1,                           -- TST_SM <= "001";
    sm_rx_s2,                           -- TST_SM <= "010";
    sm_rx_s3,                           -- TST_SM <= "011";
    sm_rx_s4,                           -- TST_SM <= "100";
    sm_rx_s5,                            -- TST_SM <= "101";
	sm_rx_s6,
	sm_rx_j1,
	sm_rx_j2
--	sm_rx_soc, 
--	sm_rx_bb1,
--	sm_rx_bb2,
--	sm_rx_bb3,
--	sm_rx_bb4,
--	sm_rx_bb5
    );
signal sm_rx            : 	SM;
signal sig_rxcounter    : 	std_logic_vector(4 downto 0);
signal sig_pm5384_raddr : 	std_logic_vector(4 downto 0);
signal sig_addr_keep    : 	std_logic_vector(4 downto 0);

subtype ram7 is std_logic_vector(6 downto 0);
type    ram_wrusedw is array (0 to 3) of ram7;
signal  sig_wrusedw_array 	: 	ram_wrusedw;

signal sig_index 	: 	integer range 0 to 3;
signal sel_addr		:	std_logic_vector(4 downto 0);
signal poll_flag	:	std_logic;
signal	select_addr		:	std_logic_vector(4 downto 0);
signal	phy_status		:	std_logic_vector(3 downto 0);
signal	fifo_flag		:	std_logic_vector(3 downto 0);
type	state2			is (wait0,idle,phy1,phy2,phy3,phy4);
signal	select_state	:	state2;
signal	select_stop		:	std_logic;
signal	select_suc		:	std_logic;
signal	select_flag		:	std_logic_vector(1 downto 0);
signal	select_flag0	:	integer range 0 to 3;


begin    
  	sig_wrusedw_array(0) <= FIFO_WRUSEDW0;
  	sig_wrusedw_array(1) <= FIFO_WRUSEDW1;
  	sig_wrusedw_array(2) <= FIFO_WRUSEDW2;
 	sig_wrusedw_array(3) <= FIFO_WRUSEDW3;
 	
 	-------------------------------------------------------------
	--The process judges FIFOs' status and save the results, which
	-- is used in "PHY Selection FSM"	
	-------------------------------------------------------------
	process(rst,PM5384_RFCLK)
	begin
		if rst = '0' then
			fifo_flag <= (others => '0');
		elsif rising_edge(PM5384_RFCLK) then
			for i in 0 to 3 loop
				if sig_wrusedw_array(i) < 75 then
					fifo_flag(i) <= '1';
				else
					fifo_flag(i) <= '0';
				end if;
			end loop;
		end if;
	end process;
	-------------------------------------------------------------
	

	-------------------------------------------------------------
	-- "PHY Selection FSM", according to polling feedback results
	-- and FIFOs' status,one PHY is selected to transfer data. 
	-- The FSM is elaborately desinged to run as round-robin.	
	-------------------------------------------------------------
	process(rst, PM5384_RFCLK)
	begin
		if rst = '0' then
			select_addr  <= (others => '1');
			select_state <= phy1;
			select_suc	 <= '0';
			select_flag	 <= "00";
		elsif rising_edge(PM5384_RFCLK) then
			case select_state is
				when idle =>
					if select_stop = '0' then
						select_suc	<= '0';
						case select_flag is
							when "00" =>
								select_state <= phy2;
							when "01" =>
								select_state <= phy3;
							when "10" =>
								select_state <= phy4;	
							when "11" =>
								select_state <= phy1;
							when others =>
								select_state <= phy1;
						end case;
					else
						select_suc	<= '1';
						select_state <= idle;	
					end if;					
				when phy1 =>
					if phy_status(0) = '1' and  fifo_flag(0) = '1' then
						select_addr	<= PollAddr_S;
						select_suc	<= '1';
						select_flag	<= "00";
						select_state<= wait0;
					else
						select_suc	<= '0';
						select_state<= phy2;
					end if;
				when phy2 =>
					if phy_status(1) = '1' and  fifo_flag(1) = '1' then
						select_addr	<= PollAddr_S + 1;
						select_suc	<= '1';
						select_flag	<= "01";
						select_state<= wait0;
					else
						select_suc	<= '0';
						select_state<= phy3;
					end if;				
				when phy3 =>
					if phy_status(2) = '1' and  fifo_flag(2) = '1' then
						select_addr	<= PollAddr_S + 2;
						select_suc	<= '1';
						select_flag	<= "10";
						select_state<= wait0;
					else
						select_suc	<= '0';
						select_state<= phy4;
					end if;				
				when phy4 =>
					if phy_status(3) = '1' and  fifo_flag(3) = '1' then
						select_addr	<= PollAddr_E;
						select_suc	<= '1';
						select_flag	<= "11";
						select_state<= wait0;
					else
						select_suc	<= '0';
						select_state<= phy1;
					end if;	
				when wait0 =>
						select_state <= idle;		
				when others =>
					select_addr  <= (others => '1');
					select_state <= phy1;
					select_suc	 <= '0';
					select_flag	 <= "00";					
			end case;
		end if;
	end process;
	-------------------------------------------------------------

polling_and_rx:	process(PM5384_RFCLK, RST)
	variable var_wait : integer range 0 to 63;
	begin
		if RST = '0' then 
      		FIFO_WRREQ       <= (others => '0');
      		FIFO_DATA        <= (others => '0');
      		PM5384_RENB      <= '1';
      		PM5384_RADR      <= (others => 'Z');
      		sig_rxcounter    <= (others => '0');
      		sig_pm5384_raddr <= PollAddr_S;
      		sig_addr_keep    <= (others => '0');
      		sig_index        <= 0;
      		poll_flag		   <= '1';
      		phy_status	  	 <= (others => '0');
      		select_stop		<= '0';
      		sm_rx            <= sm_rx_en;
      		TST_SM           <= "111";
		sel_addr  <= (others => '1');
      		detection		 <= '1';
		elsif rising_edge(PM5384_RFCLK) then
			case sm_rx is
        		when sm_rx_en =>
          			FIFO_WRREQ  <= (others => '0');
          			FIFO_DATA   <= (others => '0');
          			PM5384_RENB <= '1';
          			PM5384_RADR <= (others => 'Z');
          			if Module_En = '1' then
            			FIFO_WRREQ       <= (others => '0');
            			FIFO_DATA        <= (others => '0');
            			sig_rxcounter    <= (others => '0');
            			sig_pm5384_raddr <= PollAddr_S;
            			sig_addr_keep    <= (others => '0');
            			sig_index        <= 0;
            			sm_rx            <= sm_rx_wait;
            			TST_SM           <= "110";
          			else
            			PM5384_RENB <= '1';
            			PM5384_RADR <= (others => 'Z');
            			sm_rx       <= sm_rx_en;
            			TST_SM      <= "111";
          			end if;
          
        		when sm_rx_wait =>
          			if var_wait < 63 then
            			var_wait := var_wait + 1;
            			sm_rx    <= sm_rx_wait;
            			TST_SM   <= "110";
          			else
            			PM5384_RENB <= '1';
            			PM5384_RADR <= (others => '1');
            			var_wait    := 63;
            			sm_rx       <= sm_rx_s0;
            			TST_SM      <= "000";
          			end if;
          
          		when sm_rx_s0 =>
					FIFO_WRREQ       <= (others => '0');
          			poll_flag	<= '1';
          			if select_suc = '1' then         	
          				PM5384_RADR <= select_addr;
          				sel_addr	<= select_addr;
          				sig_index	<= conv_integer(select_flag);
          				

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -