Vous êtes sur la page 1sur 10

-- type udp_tx_header_type is record

-- dst_ip_addr : STD_LOGIC_VECTOR (31 downto 0);


-- dst_port

: STD_LOGIC_VECTOR (15 downto 0);

-- src_port

: STD_LOGIC_VECTOR (15 downto 0);

-- data_length : STD_LOGIC_VECTOR (15 downto 0);


-- checksum

-- user data size, bytes

: STD_LOGIC_VECTOR (15 downto 0);

-- end record;
-- type ipv4_rx_header_type is record
-- is_valid

: std_logic;

-- protocol

: std_logic_vector (7 downto 0);

-- data_length : STD_LOGIC_VECTOR (15 downto 0);

-- user data size, bytes

-- src_ip_addr : STD_LOGIC_VECTOR (31 downto 0);


-- num_frame_errors

: std_logic_vector (7 downto 0);

-- last_error_code

: std_logic_vector (3 downto 0); -- see RX_EC_xxx constants

-- is_broadcast

: std_logic;

-- set if the msg received is a broadcast

-- end record;
--type udp_rx_type is record
--hdr

: udp_rx_header_type;

--data

: axi_in_type;

-- header received
-- rx axi bus

--end record;
--type udp_tx_type is record
--hdr

: udp_tx_header_type;

-- header received

--data

: axi_out_type;

-- tx axi bus

--end record;
entity UDP_TX is
Port (
-- UDP Layer signals

udp_tx_start

: in std_logic;

-- indicates req to tx UDP

udp_txi

: in udp_tx_type;

-- UDP tx cxns

udp_tx_result

: out std_logic_vector (1 downto 0);-- tx status (changes during transmission)

udp_tx_data_out_ready : out std_logic;

-- indicates udp_tx is ready to take data

-- system signals
clk

: in STD_LOGIC;

reset

: in STD_LOGIC;

-- same clock used to clock mac data and ip data

-- IP layer TX signals
ip_tx_start

: out std_logic;

ip_tx

: out ipv4_tx_type;

-- IP tx cxns
ip_tx_result

: in std_logic_vector (1 downto 0); -- tx status (changes during transmission)

ip_tx_data_out_ready : in std_logic

-- indicates IP TX is ready to take data);

end UDP_TX;
architecture Behavioral of UDP_TX is
type tx_state_type is (IDLE,

PAUSE, SEND_UDP_HDR, SEND_USER_DATA);

type count_mode_type is (RST, INCR, HOLD);


type settable_cnt_type is (RST, SET, INCR, HOLD);
type set_clr_type is (SET, CLR, HOLD);
-- TX state variables
signal udp_tx_state

: tx_state_type;

signal tx_count

: unsigned (15 downto 0);

signal tx_result_reg

: std_logic_vector (1 downto 0);

signal ip_tx_start_reg

: std_logic;

signal data_out_ready_reg

: std_logic;

-- tx control signals
signal next_tx_state

: tx_state_type;

signal set_tx_state
signal next_tx_result

: std_logic;
: std_logic_vector (1 downto 0);

signal set_tx_result

: std_logic;

signal tx_count_val

: unsigned (15 downto 0);

signal tx_count_mode

: settable_cnt_type;

signal tx_data

: std_logic_vector (7 downto 0);

signal set_last
signal set_ip_tx_start

: std_logic;
: set_clr_type;

signal tx_data_valid

: std_logic;

-- indicates whether data is valid to tx or not

-- tx temp signals
signal total_length

: std_logic_vector (15 downto 0); -- computed combinatorially from header size

begin
------------------------------------------------------------------------ combinatorial process to implement FSM and determine control signals
----------------------------------------------------------------------tx_combinatorial : process(
-- input signals
udp_tx_start, udp_txi, clk, ip_tx_result, ip_tx_data_out_ready,
-- state variables
udp_tx_state, tx_count, tx_result_reg, ip_tx_start_reg, data_out_ready_reg,
-- control signals
next_tx_state, set_tx_state, next_tx_result, set_tx_result, tx_count_mode, tx_count_val,
tx_data, set_last, total_length, set_ip_tx_start, tx_data_valid
begin
-- set output followers
ip_tx_start <= ip_tx_start_reg;
ip_tx.hdr.protocol <= x"11";

-- UDP protocol

ip_tx.hdr.data_length <= total_length;


ip_tx.hdr.dst_ip_addr <= udp_txi.hdr.dst_ip_addr;
if udp_tx_start = '1' and ip_tx_start_reg = '0' then
udp_tx_result <= UDPTX_RESULT_NONE;

-- kill the result until have started the IP

layer
else
udp_tx_result <= tx_result_reg;
end if;
case udp_tx_state is
when SEND_USER_DATA =>
ip_tx.data.data_out <= udp_txi.data.data_out;
tx_data_valid <= udp_txi.data.data_out_valid;
ip_tx.data.data_out_last <= udp_txi.data.data_out_last;
when SEND_UDP_HDR =>
ip_tx.data.data_out <= tx_data;
tx_data_valid <= ip_tx_data_out_ready;
ip_tx.data.data_out_last <= set_last;
when others =>
ip_tx.data.data_out <= (others => '0');
tx_data_valid <= '0';
ip_tx.data.data_out_last <= set_last;
end case;
ip_tx.data.data_out_valid <= tx_data_valid and ip_tx_data_out_ready;
-- set signal defaults
next_tx_state <= IDLE;
set_tx_state <= '0';
tx_count_mode <= HOLD;
tx_data <= x"00";

set_last <= '0';


next_tx_result <= UDPTX_RESULT_NONE;
set_tx_result <= '0';
set_ip_tx_start <= HOLD;
tx_count_val <= (others => '0');
udp_tx_data_out_ready <= '0';
-- set temp signals
total_length <= std_logic_vector(unsigned(udp_txi.hdr.data_length) + 8);
-- total length = user data length + header length (bytes)
-- TX FSM
case udp_tx_state is
when IDLE =>
udp_tx_data_out_ready <= '0'; -- in this state, we are unable to accept user data for
tx
tx_count_mode <= RST;
if udp_tx_start = '1' then
-- check header count for error if too high
if unsigned(udp_txi.hdr.data_length) > 1472 then
next_tx_result <= UDPTX_RESULT_ERR;
set_tx_result <= '1';
else
-- start to send UDP header
tx_count_mode <= RST;
next_tx_result <= UDPTX_RESULT_SENDING;
set_ip_tx_start <= SET;
set_tx_result <= '1';
next_tx_state <= PAUSE;
set_tx_state <= '1';

end if;
end if;
when PAUSE =>
-- delay one clock for IP layer to respond to ip_tx_start and remove any tx error
result
next_tx_state <= SEND_UDP_HDR;
set_tx_state <= '1';

when SEND_UDP_HDR =>


udp_tx_data_out_ready <= '0'; -- in this state, we are unable to accept user data for
tx
if ip_tx_result = IPTX_RESULT_ERR then
set_ip_tx_start <= CLR;
next_tx_result <= UDPTX_RESULT_ERR;
set_tx_result <= '1';
next_tx_state <= IDLE;
set_tx_state <= '1';
elsif ip_tx_data_out_ready = '1' then
if tx_count = x"0007" then
tx_count_val <= x"0001";
tx_count_mode <= SET;
next_tx_state <= SEND_USER_DATA;
set_tx_state <= '1';
else
tx_count_mode <= INCR;
end if;
case tx_count is
when x"0000" => tx_data <= udp_txi.hdr.src_port (15 downto 8);

-- src port

when x"0001" => tx_data <= udp_txi.hdr.src_port (7 downto 0);


when x"0002" => tx_data <= udp_txi.hdr.dst_port (15 downto 8);

-- dst port

when x"0003" => tx_data <= udp_txi.hdr.dst_port (7 downto 0);


when x"0004" => tx_data <= total_length (15 downto 8);

-- length

when x"0005" => tx_data <= total_length (7 downto 0);


when x"0006" => tx_data <= udp_txi.hdr.checksum (15 downto 8);

-- checksum (set by

upstream)
when x"0007" => tx_data <= udp_txi.hdr.checksum (7 downto 0);
when others =>
-- shouldnt get here - handle as error
next_tx_result <= UDPTX_RESULT_ERR;
set_tx_result <= '1';
end case;
end if;
when SEND_USER_DATA =>
udp_tx_data_out_ready <= ip_tx_data_out_ready;-- in this state, we can accept user data if IP TX
rdy
if ip_tx_data_out_ready = '1' then
if udp_txi.data.data_out_valid = '1' or tx_count = x"000" then

-- only increment if

ready and valid has been subsequently established, otherwise data count moves on too
fast
if unsigned(tx_count) = unsigned(udp_txi.hdr.data_length) then
-- TX terminated due to count - end normally
set_last <= '1';
tx_data <= udp_txi.data.data_out;
next_tx_result <= UDPTX_RESULT_SENT;
set_ip_tx_start <= CLR;
set_tx_result <= '1';
next_tx_state <= IDLE;

set_tx_state <= '1';


elsif udp_txi.data.data_out_last = '1' then
-- terminate tx with error as got last from upstream before exhausting
count
set_last <= '1';
tx_data <= udp_txi.data.data_out;
next_tx_result <= UDPTX_RESULT_ERR;
set_ip_tx_start <= CLR;
set_tx_result <= '1';
next_tx_state <= IDLE;
set_tx_state <= '1';

else
-- TX continues
tx_count_mode <= INCR;
tx_data <= udp_txi.data.data_out;
end if;
end if;
end if;
end case;
end process;
------------------------------------------------------------------------------ sequential process to action control signals and change states and outputs
----------------------------------------------------------------------------tx_sequential : process (clk,reset,data_out_ready_reg)
begin
if rising_edge(clk) then
data_out_ready_reg <= ip_tx_data_out_ready;

else
data_out_ready_reg <= data_out_ready_reg;
end if;
if rising_edge(clk) then
if reset = '1' then
-- reset state variables
udp_tx_state <= IDLE;
tx_count <= x"0000";
tx_result_reg <= IPTX_RESULT_NONE;
ip_tx_start_reg <= '0';
else
-- Next udp_tx_state processing
if set_tx_state = '1' then
udp_tx_state <= next_tx_state;
else
udp_tx_state <= udp_tx_state;
end if;
-- ip_tx_start_reg processing
case set_ip_tx_start is
when SET => ip_tx_start_reg <= '1';
when CLR => ip_tx_start_reg <= '0';
when HOLD => ip_tx_start_reg <= ip_tx_start_reg;
end case;
-- tx result processing
if set_tx_result = '1' then
tx_result_reg <= next_tx_result;
else

tx_result_reg <= tx_result_reg;


end if;
-- tx_count processing
case tx_count_mode is
when RST =>

tx_count <= x"0000";

when SET =>

tx_count <= tx_count_val;

when INCR => tx_count <= tx_count + 1;


when HOLD => tx_count <= tx_count;
end case;
end if; end if; end process; end Behavioral;

Vous aimerez peut-être aussi