---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 09/30/2025 05:47:45 PM -- Design Name: -- Module Name: eth_frame_unpacker - 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; entity eth_frame_unpacker is port ( clk : in std_logic; resetn : in std_logic; -- active-low synchronous reset s_axis_tdata : in std_logic_vector(511 downto 0); s_axis_tvalid : in std_logic; s_axis_tlast : in std_logic; s_axis_tkeep : in std_logic_vector(63 downto 0); s_axis_tuser : in std_logic; -- frame error indicator (qualified by s_axis_tvalid and s_axis_tlast) m_axis_tdata : out std_logic_vector(511 downto 0); m_axis_tvalid : out std_logic; m_axis_tlast : out std_logic; m_axis_tuser : out std_logic; -- frame error indicator (qualified by m_axis_tvalid and m_axis_tlast) rx_frame_err_cnt : out std_logic_vector(31 downto 0); rx_frame_cnt : out std_logic_vector(31 downto 0) ); end entity; architecture rtl of eth_frame_unpacker is type state_type is (IDLE, RUN); signal state_r : state_type := IDLE; signal state : state_type; signal carry : std_logic_vector(399 downto 0); signal carry_r : std_logic_vector(399 downto 0) := (others => '0'); signal frame_err_cnt_i : std_logic_vector(31 downto 0); signal frame_err_cnt_r : std_logic_vector(31 downto 0) := (others => '0'); signal frame_cnt_i : std_logic_vector(31 downto 0); signal frame_cnt_r : std_logic_vector(31 downto 0) := (others => '0'); signal m_tvalid : std_logic; signal m_tvalid_r : std_logic := '0'; signal m_tdata : std_logic_vector(511 downto 0); signal m_tdata_r : std_logic_vector(511 downto 0) := (others => '0'); signal m_tuser : std_logic; signal m_tuser_r : std_logic := '0'; signal m_tlast : std_logic; signal m_tlast_r : std_logic := '0'; begin -- Drive outputs m_axis_tuser <= m_tuser_r; m_axis_tdata <= m_tdata_r; m_axis_tlast <= m_tlast_r; m_axis_tvalid <= m_tvalid_r; rx_frame_err_cnt <= frame_err_cnt_r; rx_frame_cnt <= frame_cnt_r; ----------------------------------------------------------------------------- -- Combinational next-state / next-data ----------------------------------------------------------------------------- process(state_r, carry_r, m_tdata_r, m_tuser_r, m_tlast_r, frame_err_cnt_r, s_axis_tdata, s_axis_tvalid, s_axis_tlast, s_axis_tuser, frame_cnt_r) begin -- Defaults state <= state_r; carry <= carry_r; frame_err_cnt_i <= frame_err_cnt_r; frame_cnt_i <= frame_cnt_r; m_tvalid <= '0'; m_tdata <= m_tdata_r; m_tuser <= m_tuser_r; m_tlast <= m_tlast_r; case state_r is ------------------------------------------------------------------------- when IDLE => if s_axis_tvalid = '1' then -- cache high 50B; no output yet (need second beat to form first 64B payload) carry(399 downto 0) <= s_axis_tdata(511 downto 112); state <= RUN; end if; ------------------------------------------------------------------------- when RUN => if s_axis_tvalid = '1' then carry(399 downto 0) <= s_axis_tdata(511 downto 112); m_tdata <= s_axis_tdata(111 downto 0) & carry_r; m_tvalid <= '1'; m_tuser <= s_axis_tuser; m_tlast <= s_axis_tlast; if(s_axis_tlast = '1')then state <= IDLE; frame_cnt_i <= std_logic_vector(unsigned(frame_cnt_r) +1); end if; if(s_axis_tlast = '1' and s_axis_tuser = '1')then frame_err_cnt_i <= std_logic_vector(unsigned(frame_err_cnt_r) +1); end if; end if; ------------------------------------------------------------------------- end case; end process; ----------------------------------------------------------------------------- -- Regs ----------------------------------------------------------------------------- seq_proc : process(clk) begin if rising_edge(clk) then if resetn = '0' then state_r <= IDLE; frame_err_cnt_r <= (others => '0'); frame_cnt_r <= (others => '0'); m_tvalid_r <= '0'; else state_r <= state; frame_err_cnt_r <= frame_err_cnt_i; frame_cnt_r <= frame_cnt_i; m_tvalid_r <= m_tvalid; end if; carry_r <= carry; m_tdata_r <= m_tdata; m_tuser_r <= m_tuser; m_tlast_r <= m_tlast; end if; end process; end architecture;