Files
alinx_z19_ad9082/source/eth_frame_unpacker.vhd

146 lines
5.3 KiB
VHDL

----------------------------------------------------------------------------------
-- 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;