136 lines
3.9 KiB
VHDL
136 lines
3.9 KiB
VHDL
----------------------------------------------------------------------------------
|
|
-- Company:
|
|
-- Engineer: Jason M Blevins
|
|
--
|
|
-- Create Date: 01/05/2026 11:59:12 AM
|
|
-- Design Name:
|
|
-- Module Name: eth_flowctrl_tx - behavioral
|
|
-- Project Name:
|
|
-- Target Devices:
|
|
-- Tool Versions:
|
|
-- Description:
|
|
--
|
|
-- Dependencies:
|
|
--
|
|
-- Revision:
|
|
-- Revision 0.01 - File Created
|
|
-- Additional Comments:
|
|
--
|
|
----------------------------------------------------------------------------------
|
|
|
|
|
|
library IEEE;
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
|
use IEEE.NUMERIC_STD.ALL;
|
|
--library UNISIM;
|
|
--use UNISIM.VComponents.all;
|
|
|
|
entity eth_flowctrl_tx is
|
|
Port (
|
|
clk : in STD_LOGIC;
|
|
resetn : in STD_LOGIC;
|
|
prog_full_manual : in STD_LOGIC;
|
|
data_cnt : in STD_LOGIC_VECTOR(31 downto 0);
|
|
prog_full_on : in STD_LOGIC_VECTOR(31 downto 0);
|
|
prog_full_off : in STD_LOGIC_VECTOR(31 downto 0);
|
|
ctl_tx_resend_pause : out STD_LOGIC;
|
|
ctl_tx_pause_req : out STD_LOGIC_VECTOR (8 downto 0);
|
|
tx_pause_cnt : out std_logic_vector(31 downto 0)
|
|
);
|
|
end eth_flowctrl_tx;
|
|
|
|
architecture behavioral of eth_flowctrl_tx is
|
|
|
|
signal cnt : unsigned(3 downto 0);
|
|
signal cnt_r : unsigned(3 downto 0) := (others => '0');
|
|
signal tx_pause_cnt_i : unsigned(31 downto 0);
|
|
signal tx_pause_cnt_r : unsigned(31 downto 0) := (others => '0');
|
|
type state_type is (s0, s1, s2, s3);
|
|
signal state : state_type;
|
|
signal state_r : state_type := s0;
|
|
signal resend_pause : std_logic;
|
|
signal pause_req : std_logic_vector(8 downto 0);
|
|
signal resend_pause_r : std_logic := '0';
|
|
signal pause_req_r : std_logic_vector(8 downto 0) := (others => '0');
|
|
signal prog_full_r : std_logic := '0';
|
|
|
|
begin
|
|
|
|
ctl_tx_resend_pause <= resend_pause_r;
|
|
ctl_tx_pause_req <= pause_req_r;
|
|
tx_pause_cnt <= std_logic_vector(tx_pause_cnt_r);
|
|
|
|
process(clk)
|
|
begin
|
|
if(rising_edge(clk))then
|
|
if(resetn = '0')then
|
|
resend_pause_r <= '0';
|
|
pause_req_r <= (others => '0');
|
|
state_r <= s0;
|
|
cnt_r <= (others => '0');
|
|
prog_full_r <= '0';
|
|
tx_pause_cnt_r <= (others => '0');
|
|
else
|
|
resend_pause_r <= resend_pause;
|
|
pause_req_r <= pause_req;
|
|
state_r <= state;
|
|
cnt_r <= cnt;
|
|
tx_pause_cnt_r <= tx_pause_cnt_i;
|
|
if(unsigned(data_cnt) > unsigned(prog_full_on) or prog_full_manual = '1')then
|
|
prog_full_r <= '1';
|
|
elsif (unsigned(data_cnt) <= unsigned(prog_full_off) and prog_full_manual = '0')then
|
|
prog_full_r <= '0';
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
process(state_r, cnt_r, prog_full_r, resend_pause_r, pause_req_r, tx_pause_cnt_r)
|
|
begin
|
|
-- defaults
|
|
state <= state_r;
|
|
cnt <= cnt_r;
|
|
resend_pause <= resend_pause_r;
|
|
pause_req <= pause_req_r;
|
|
tx_pause_cnt_i <= tx_pause_cnt_r;
|
|
|
|
case state_r is
|
|
when s0 =>
|
|
if(prog_full_r = '1')then
|
|
state <= s1;
|
|
tx_pause_cnt_i <= tx_pause_cnt_r +1;
|
|
end if;
|
|
|
|
when s1 =>
|
|
pause_req <= "100000000";
|
|
cnt <= cnt_r +1;
|
|
if(cnt_r = 15)then
|
|
state <= s2;
|
|
end if;
|
|
|
|
when s2 =>
|
|
if(prog_full_r = '0')then
|
|
state <= s3;
|
|
tx_pause_cnt_i <= tx_pause_cnt_r +1;
|
|
end if;
|
|
|
|
when s3 =>
|
|
pause_req <= (others => '0');
|
|
cnt <= cnt_r +1;
|
|
if(cnt_r = 0)then
|
|
resend_pause <= '1';
|
|
else
|
|
resend_pause <= '0';
|
|
end if;
|
|
if(cnt_r = 15)then
|
|
state <= s0;
|
|
end if;
|
|
|
|
when others =>
|
|
end case;
|
|
|
|
end process;
|
|
|
|
|
|
end behavioral;
|