moving repo from git to local repo
This commit is contained in:
@@ -0,0 +1,258 @@
|
||||
----------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 09/30/2025 05:40:20 PM
|
||||
-- Design Name:
|
||||
-- Module Name: eth_frame_packer - 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_packer is
|
||||
port (
|
||||
clk : in std_logic;
|
||||
resetn : in std_logic;
|
||||
|
||||
pause : in std_logic := '0';
|
||||
cfg_dst_mac : in std_logic_vector(47 downto 0); -- DA
|
||||
cfg_src_mac : in std_logic_vector(47 downto 0); -- SA
|
||||
cfg_eth_type : in std_logic_vector(15 downto 0); -- EtherType/Length
|
||||
|
||||
-- AXIS payload in (512-bit, 64B beats; multiples of 64B, aligned)
|
||||
s_axis_tdata : in std_logic_vector(511 downto 0);
|
||||
s_axis_tvalid : in std_logic;
|
||||
s_axis_tready : out std_logic;
|
||||
s_axis_tlast : in std_logic;
|
||||
|
||||
-- AXIS to CMAC TX client (512-bit)
|
||||
m_axis_tdata : out std_logic_vector(511 downto 0);
|
||||
m_axis_tkeep : out std_logic_vector(63 downto 0);
|
||||
m_axis_tvalid : out std_logic;
|
||||
m_axis_tready : in std_logic;
|
||||
m_axis_tlast : out std_logic;
|
||||
m_axis_tuser : out std_logic; -- error flag to CMAC
|
||||
|
||||
tx_cnt : out std_logic_vector(31 downto 0);
|
||||
underrun_cnt : out std_logic_vector(31 downto 0) := (others => '0')
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture rtl of eth_frame_packer is
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- Functions (VHDL-93 safe)
|
||||
---------------------------------------------------------------------------
|
||||
function mk_header(
|
||||
da : std_logic_vector(47 downto 0);
|
||||
sa : std_logic_vector(47 downto 0);
|
||||
ety : std_logic_vector(15 downto 0)
|
||||
) return std_logic_vector is
|
||||
variable h : std_logic_vector(111 downto 0);
|
||||
begin
|
||||
-- DA [0..5]
|
||||
h( 7 downto 0) := da(47 downto 40);
|
||||
h( 15 downto 8) := da(39 downto 32);
|
||||
h( 23 downto 16) := da(31 downto 24);
|
||||
h( 31 downto 24) := da(23 downto 16);
|
||||
h( 39 downto 32) := da(15 downto 8);
|
||||
h( 47 downto 40) := da( 7 downto 0);
|
||||
-- SA [6..11]
|
||||
h( 55 downto 48) := sa(47 downto 40);
|
||||
h( 63 downto 56) := sa(39 downto 32);
|
||||
h( 71 downto 64) := sa(31 downto 24);
|
||||
h( 79 downto 72) := sa(23 downto 16);
|
||||
h( 87 downto 80) := sa(15 downto 8);
|
||||
h( 95 downto 88) := sa( 7 downto 0);
|
||||
-- Type/Len [12..13]
|
||||
h(103 downto 96) := ety(15 downto 8);
|
||||
h(111 downto 104) := ety( 7 downto 0);
|
||||
return h;
|
||||
end function;
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
--
|
||||
---------------------------------------------------------------------------
|
||||
type state_type is (IDLE, RUN, FLUSH);
|
||||
signal state : state_type;
|
||||
signal state_r : state_type := IDLE;
|
||||
signal carry_r : std_logic_vector(111 downto 0) := (others => '0');
|
||||
signal carry : std_logic_vector(111 downto 0);
|
||||
signal m_tdata_r : std_logic_vector(511 downto 0) := (others => '0');
|
||||
signal m_tdata : std_logic_vector(511 downto 0);
|
||||
signal m_tkeep_r : std_logic_vector(63 downto 0) := (others => '1');
|
||||
signal m_tkeep : std_logic_vector(63 downto 0);
|
||||
signal m_tlast_r : std_logic := '0';
|
||||
signal m_tlast : std_logic;
|
||||
signal m_tvalid_r : std_logic := '0';
|
||||
signal m_tvalid : std_logic;
|
||||
signal m_tuser_r : std_logic := '0';
|
||||
signal m_tuser : std_logic;
|
||||
signal header : std_logic_vector(111 downto 0);
|
||||
signal underrun_cnt_r : std_logic_vector(31 downto 0) := (others => '0');
|
||||
signal tx_cnt_r : std_logic_vector(31 downto 0) := (others => '0');
|
||||
|
||||
begin
|
||||
|
||||
header <= mk_header(cfg_dst_mac, cfg_src_mac, cfg_eth_type);
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- Drive Outputs
|
||||
---------------------------------------------------------------------------
|
||||
m_axis_tuser <= m_tuser_r;
|
||||
m_axis_tdata <= m_tdata_r;
|
||||
m_axis_tkeep <= m_tkeep_r;
|
||||
m_axis_tlast <= m_tlast_r;
|
||||
m_axis_tvalid <= m_tvalid_r;
|
||||
underrun_cnt <= underrun_cnt_r;
|
||||
tx_cnt <= tx_cnt_r;
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- Combinational next-state / next-data
|
||||
---------------------------------------------------------------------------
|
||||
process(state_r, carry_r, s_axis_tlast, s_axis_tvalid, m_axis_tready, m_tvalid_r,
|
||||
m_tdata_r, m_tkeep_r, m_tlast_r, m_tuser_r, header, s_axis_tdata, pause)
|
||||
begin
|
||||
-- Defaults
|
||||
state <= state_r;
|
||||
carry <= carry_r;
|
||||
m_tdata <= m_tdata_r;
|
||||
m_tkeep <= m_tkeep_r;
|
||||
m_tlast <= m_tlast_r;
|
||||
m_tuser <= m_tuser_r;
|
||||
m_tvalid <= m_tvalid_r;
|
||||
s_axis_tready <= '0';
|
||||
|
||||
case state_r is
|
||||
-----------------------------------------------------------------------
|
||||
when IDLE =>
|
||||
|
||||
--s_axis_tready <= m_axis_tready or not(m_tvalid_r);
|
||||
|
||||
--m_tvalid <= (s_axis_tvalid = '1' and (m_axis_tready = '1' or m_tvalid_r = '0')) or (not(m_axis_tready) and m_tvalid_r);
|
||||
if(m_axis_tready = '1')then
|
||||
m_tvalid <= '0';
|
||||
end if;
|
||||
|
||||
if (s_axis_tvalid = '1' and (m_axis_tready = '1' or m_tvalid_r = '0') and pause = '0') then
|
||||
|
||||
s_axis_tready <= '1';
|
||||
|
||||
-- Emit first beat = [14B header] ++ [first 50B payload]
|
||||
m_tdata <= s_axis_tdata(399 downto 0) & header;
|
||||
m_tkeep <= (others => '1');
|
||||
m_tvalid <= '1';
|
||||
m_tuser <= '0';
|
||||
m_tlast <= '0';
|
||||
|
||||
-- Next carry = bytes 50..63
|
||||
carry <= s_axis_tdata(511 downto 400);
|
||||
|
||||
if s_axis_tlast = '1' then
|
||||
state <= FLUSH;
|
||||
else
|
||||
state <= RUN;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
when RUN =>
|
||||
|
||||
s_axis_tready <= m_axis_tready;
|
||||
|
||||
if(s_axis_tvalid = '0')then
|
||||
m_tuser <= '1'; -- s_axis_tvalid must be '1' or else this is an error condition, tx data underrun.
|
||||
end if;
|
||||
|
||||
if (m_axis_tready = '1') then
|
||||
|
||||
-- Steady-state emit = [prev carry 14B] ++ [new payload 0..49]
|
||||
m_tdata <= s_axis_tdata(399 downto 0) & carry_r;
|
||||
--m_tkeep <= (others => '1');
|
||||
--m_tvalid <= '1';
|
||||
--m_tlast <= '0';
|
||||
|
||||
-- Next carry = bytes 50..63
|
||||
carry <= s_axis_tdata(511 downto 400);
|
||||
|
||||
if s_axis_tlast = '1' then
|
||||
state <= FLUSH;
|
||||
else
|
||||
state <= RUN;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
when FLUSH =>
|
||||
|
||||
--s_axis_tready <= '0';
|
||||
|
||||
-- if(s_axis_tvalid = '0')then
|
||||
-- m_tuser <= '1';
|
||||
-- end if;
|
||||
|
||||
if (m_axis_tready = '1') then
|
||||
|
||||
-- Emit the final 14B tail
|
||||
m_tdata <= std_logic_vector(to_unsigned(0, 400)) & carry_r;
|
||||
m_tkeep <= x"0000000000003FFF";
|
||||
m_tlast <= '1';
|
||||
--m_tvalid <= '1';
|
||||
|
||||
state <= IDLE;
|
||||
end if;
|
||||
|
||||
--when others =>
|
||||
|
||||
end case;
|
||||
end process;
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- Registers
|
||||
---------------------------------------------------------------------------
|
||||
seq_proc : process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if resetn = '0' then
|
||||
state_r <= IDLE;
|
||||
m_tvalid_r <= '0';
|
||||
underrun_cnt_r <= (others => '0');
|
||||
tx_cnt_r <= (others => '0');
|
||||
else
|
||||
state_r <= state;
|
||||
m_tvalid_r <= m_tvalid;
|
||||
|
||||
if(m_tlast_r = '1' and m_tvalid_r = '1' and m_tuser_r = '1' and m_axis_tready = '1')then
|
||||
underrun_cnt_r <= std_logic_vector(unsigned(underrun_cnt_r) +1);
|
||||
end if;
|
||||
|
||||
if(m_tlast_r = '1' and m_tvalid_r = '1' and m_axis_tready = '1')then
|
||||
tx_cnt_r <= std_logic_vector(unsigned(tx_cnt_r) +1);
|
||||
end if;
|
||||
|
||||
end if;
|
||||
carry_r <= carry;
|
||||
m_tdata_r <= m_tdata;
|
||||
m_tkeep_r <= m_tkeep;
|
||||
m_tlast_r <= m_tlast;
|
||||
m_tuser_r <= m_tuser;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture;
|
||||
|
||||
Reference in New Issue
Block a user