📄 utopia_master_rx.vhd
字号:
---------------------------------------------------------------------------------------------------
--
-- 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 + -