146 lines
5.3 KiB
VHDL
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;
|
|
|