mac: tx: Implement automatic padding
This also renames the bit_cnt signal to sr_cnt.
97d0905c08
was kinda BS.
This fixes #4.
This commit is contained in:
parent
22b7d99b1f
commit
ef6b6378f8
@ -32,7 +32,8 @@ entity trashernet_mac is
|
||||
end entity trashernet_mac;
|
||||
|
||||
architecture rtl of trashernet_mac is
|
||||
constant ETH_POLYNOMIAL : std_logic_vector(31 downto 0) := x"04C11DB7";
|
||||
constant ETH_POLYNOMIAL : std_logic_vector(31 downto 0) := x"04C11DB7";
|
||||
constant ETH_FRAME_MIN_LENGTH : integer := 64;
|
||||
|
||||
begin
|
||||
rx : block
|
||||
@ -134,12 +135,14 @@ begin
|
||||
end block rx;
|
||||
|
||||
tx : block
|
||||
type tx_state_t is (IDLE, HEADER, DATA, TXCRC);
|
||||
type tx_state_t is (IDLE, HEADER, DATA, PAD, TXCRC);
|
||||
signal tx_state : tx_state_t;
|
||||
|
||||
signal sr : byte_vector(0 to mac_in.tx_header.mac_destination'length + mac_in.tx_header.mac_source'length + mac_in.tx_header.mac_ethertype'length - 1);
|
||||
constant BIT_CNT_MAX : integer := sr'high;
|
||||
signal bit_cnt : integer range 0 to BIT_CNT_MAX;
|
||||
signal sr : byte_vector(0 to mac_in.tx_header.mac_destination'length + mac_in.tx_header.mac_source'length + mac_in.tx_header.mac_ethertype'length - 1);
|
||||
constant SR_CNT_MAX : integer := sr'high;
|
||||
signal sr_cnt : integer range 0 to SR_CNT_MAX;
|
||||
constant BYTE_CNT_MAX : integer := ETH_FRAME_MIN_LENGTH - 4; -- Minus four because the CRC is *after* the PAD
|
||||
signal byte_cnt : integer range 0 to BYTE_CNT_MAX;
|
||||
|
||||
signal crc : std_logic_vector(ETH_POLYNOMIAL'range);
|
||||
signal crc_clear : std_logic;
|
||||
@ -173,40 +176,49 @@ begin
|
||||
if phy_out.tx_data_ack then
|
||||
sr <= sr(sr'low + 1 to sr'high) & x"00";
|
||||
crc_valid <= '1';
|
||||
if bit_cnt /= 0 then
|
||||
bit_cnt <= bit_cnt - 1;
|
||||
if sr_cnt /= 0 then
|
||||
sr_cnt <= sr_cnt - 1;
|
||||
end if;
|
||||
if byte_cnt /= 0 then
|
||||
byte_cnt <= byte_cnt - 1;
|
||||
end if;
|
||||
end if;
|
||||
case tx_state is
|
||||
when IDLE =>
|
||||
when IDLE => -- Idle + prepare sync header
|
||||
if not phy_out.tx_active and mac_in.tx_mac_data_en then
|
||||
sr(0 to 7) <= byte_vector'(0 to 6 => x"55", 7 => x"D5");
|
||||
bit_cnt <= 7;
|
||||
sr_cnt <= 7;
|
||||
tx_state <= HEADER;
|
||||
end if;
|
||||
|
||||
when HEADER =>
|
||||
if (phy_out.tx_data_ack = '1') and (bit_cnt = 0) then -- Sync Header TX complete
|
||||
when HEADER => -- Wait for sync header + prepare MAC header
|
||||
if (phy_out.tx_data_ack = '1') and (sr_cnt = 0) then -- Sync Header TX complete
|
||||
sr <= mac_in.tx_header.mac_destination & mac_in.tx_header.mac_source & mac_in.tx_header.mac_ethertype;
|
||||
crc_valid <= '1';
|
||||
bit_cnt <= BIT_CNT_MAX;
|
||||
sr_cnt <= SR_CNT_MAX;
|
||||
tx_state <= DATA;
|
||||
end if;
|
||||
byte_cnt <= BYTE_CNT_MAX;
|
||||
|
||||
when DATA =>
|
||||
if (phy_out.tx_data_ack = '1') and (bit_cnt = 0) then -- MAC Header TX complete
|
||||
when DATA => -- Wait for MAC header + transmit payload until tx_mac_data_en goes away
|
||||
if (phy_out.tx_data_ack = '1') and (sr_cnt = 0) then -- MAC Header TX complete
|
||||
if mac_in.tx_mac_data_en then
|
||||
sr(0) <= mac_in.tx_mac_data;
|
||||
mac_out.tx_mac_data_ack <= '1';
|
||||
else
|
||||
sr(0 to 3) <= (crc(7 downto 0), crc(15 downto 8), crc(23 downto 16), crc(31 downto 24));
|
||||
bit_cnt <= 4 - 1;
|
||||
tx_state <= TXCRC;
|
||||
tx_state <= PAD;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when TXCRC =>
|
||||
if (phy_out.tx_data_ack = '1') and (bit_cnt = 0) then -- CRC TX complete
|
||||
when PAD => -- Wait for PADs / last payload byte + prepare CRC
|
||||
if (byte_cnt = 0) then
|
||||
sr(0 to 3) <= (crc(7 downto 0), crc(15 downto 8), crc(23 downto 16), crc(31 downto 24));
|
||||
sr_cnt <= 4 - 1;
|
||||
tx_state <= TXCRC;
|
||||
end if;
|
||||
|
||||
when TXCRC => -- Wait for CRC + jump back to idle
|
||||
if (phy_out.tx_data_ack = '1') and (sr_cnt = 0) then -- CRC TX complete
|
||||
tx_state <= IDLE;
|
||||
end if;
|
||||
end case;
|
||||
|
Loading…
Reference in New Issue
Block a user