-- EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*-
-- vim: tabstop=2:shiftwidth=2:noexpandtab
-- kate: tab-width 2; replace-tabs off; indent-width 2;
-- =============================================================================
-- Authors: Patrick Lehmann
--
-- Entity: TODO
--
-- Description:
--
-- .. TODO:: No documentation available.
--
-- License:
-- =============================================================================
-- Copyright 2007-2015 Technische Universitaet Dresden - Germany
-- Chair of VLSI-Design, Diagnostics and Architecture
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
-- =============================================================================
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
library PoC;
use PoC.config.all;
use PoC.utils.all;
use PoC.vectors.all;
use PoC.net.all;
entity [docs]icmpv4_TX is
generic (
DEBUG : boolean := FALSE;
SOURCE_IPV4ADDRESS : T_NET_IPV4_ADDRESS := C_NET_IPV4_ADDRESS_EMPTY
);
port (
Clock : in std_logic; --
Reset : in std_logic; --
-- CSE interface
Command : in T_NET_ICMPV4_TX_COMMAND;
Status : out T_NET_ICMPV4_TX_STATUS;
Error : out T_NET_ICMPV4_TX_ERROR;
-- OUT port
Out_Valid : out std_logic;
Out_Data : out T_SLV_8;
Out_SOF : out std_logic;
Out_EOF : out std_logic;
Out_Ack : in std_logic;
Out_Meta_rst : in std_logic;
Out_Meta_SrcIPv4Address_nxt : in std_logic;
Out_Meta_SrcIPv4Address_Data : out T_SLV_8;
Out_Meta_DestIPv4Address_nxt : in std_logic;
Out_Meta_DestIPv4Address_Data : out T_SLV_8;
Out_Meta_Length : out T_SLV_16;
-- IN port
In_Meta_rst : out std_logic;
In_Meta_IPv4Address_nxt : out std_logic;
In_Meta_IPv4Address_Data : in T_SLV_8;
In_Meta_Type : in T_SLV_8;
In_Meta_Code : in T_SLV_8;
In_Meta_Identification : in T_SLV_16;
In_Meta_SequenceNumber : in T_SLV_16;
In_Meta_Payload_nxt : out std_logic;
In_Meta_Payload_last : in std_logic;
In_Meta_Payload_Data : in T_SLV_8
);
end entity;
architecture [docs]rtl of icmpv4_TX is
attribute FSM_ENCODING : string;
type T_STATE is (
ST_IDLE,
ST_SEND_ECHO_type,
ST_SEND_ECHO_CODE,
ST_SEND_ECHOREQUEST_CHECKSUM_0,
ST_SEND_ECHOREQUEST_CHECKSUM_1,
ST_SEND_ECHOREQUEST_IDENTIFIER_0,
ST_SEND_ECHOREQUEST_IDENTIFIER_1,
ST_SEND_ECHOREQUEST_SEQUENCENUMBER_0,
ST_SEND_ECHOREQUEST_SEQUENCENUMBER_1,
ST_SEND_ECHOREQUEST_DATA,
ST_SEND_ECHOREPLY_DATA,
ST_COMPLETE
);
signal State : T_STATE := ST_IDLE;
signal NextState : T_STATE;
attribute FSM_ENCODING of State : signal is ite(DEBUG, "gray", ite((VENDOR = VENDOR_XILINX), "auto", "default"));
signal Checksum : T_SLV_16;
constant PAYLOAD : std_logic_vector(255 downto 0) := x"00010203" & x"04050607" & x"08090A0B" & x"0C0D0E0F" & x"10111213" & x"14151617" & x"18191A1B" & x"1C1D1E1F";
constant PAYLOAD_ROM : T_SLVV_8 := to_slvv_8(PAYLOAD);
signal PayloadROM_Reader_nxt : std_logic;
signal PayloadROM_Reader_ov : std_logic;
signal PayloadROM_Reader_us : unsigned(log2ceilnz(PAYLOAD_ROM'length) - 1 downto 0) := (others => '0');
signal PayloadROM_Data : T_SLV_8;
begin
process(Clock)
begin
if rising_edge(Clock) then
if (Reset = '1') then
State <= ST_IDLE;
else
State <= NextState;
end if;
end if;
end process;
[docs]process(State, Command, Out_Ack, PayloadROM_Reader_ov, PayloadROM_Data)
begin
NextState <= State;
Status <= NET_ICMPV4_TX_STATUS_IDLE;
Error <= NET_ICMPV4_TX_ERROR_NONE;
Out_Valid <= '0';
Out_Data <= (others => '0');
Out_SOF <= '0';
Out_EOF <= '0';
Out_Meta_Length <= (others => '0');
PayloadROM_Reader_nxt <= '0';
case State is
when ST_IDLE =>
case Command is
when NET_ICMPV4_TX_CMD_NONE =>
null;
when NET_ICMPV4_TX_CMD_ECHO_REQUEST =>
-- TODO: check if Type equal to Command
NextState <= ST_SEND_ECHO_type;
when NET_ICMPV4_TX_CMD_ECHO_REPLY =>
-- TODO: check if Type equal to Command
NextState <= ST_SEND_ECHO_type;
end case;
when ST_SEND_ECHO_type =>
Status <= NET_ICMPV4_TX_STATUS_SENDING;
Out_Valid <= '1';
Out_Data <= In_Meta_Type;
Out_SOF <= '1';
if (Out_Ack = '1') then
NextState <= ST_SEND_ECHO_CODE;
end if;
when ST_SEND_ECHO_CODE =>
Status <= NET_ICMPV4_TX_STATUS_SENDING;
Out_Valid <= '1';
Out_Data <= In_Meta_Code;
if (Out_Ack = '1') then
NextState <= ST_SEND_ECHOREQUEST_CHECKSUM_0;
end if;
when ST_SEND_ECHOREQUEST_CHECKSUM_0 =>
Status <= NET_ICMPV4_TX_STATUS_SENDING;
Out_Valid <= '1';
Out_Data <= Checksum(15 downto 8);
if (Out_Ack = '1') then
NextState <= ST_SEND_ECHOREQUEST_CHECKSUM_1;
end if;
when ST_SEND_ECHOREQUEST_CHECKSUM_1 =>
Status <= NET_ICMPV4_TX_STATUS_SENDING;
Out_Valid <= '1';
Out_Data <= Checksum(7 downto 0);
if (Out_Ack = '1') then
NextState <= ST_SEND_ECHOREQUEST_IDENTIFIER_0;
end if;
when ST_SEND_ECHOREQUEST_IDENTIFIER_0 =>
Status <= NET_ICMPV4_TX_STATUS_SENDING;
Out_Valid <= '1';
Out_Data <= In_Meta_Identification(15 downto 8);
if (Out_Ack = '1') then
NextState <= ST_SEND_ECHOREQUEST_IDENTIFIER_1;
end if;
when ST_SEND_ECHOREQUEST_IDENTIFIER_1 =>
Status <= NET_ICMPV4_TX_STATUS_SENDING;
Out_Valid <= '1';
Out_Data <= In_Meta_Identification(7 downto 0);
if (Out_Ack = '1') then
NextState <= ST_SEND_ECHOREQUEST_SEQUENCENUMBER_0;
end if;
when ST_SEND_ECHOREQUEST_SEQUENCENUMBER_0 =>
Status <= NET_ICMPV4_TX_STATUS_SENDING;
Out_Valid <= '1';
Out_Data <= In_Meta_SequenceNumber(15 downto 8);
if (Out_Ack = '1') then
NextState <= ST_SEND_ECHOREQUEST_SEQUENCENUMBER_1;
end if;
when ST_SEND_ECHOREQUEST_SEQUENCENUMBER_1 =>
Status <= NET_ICMPV4_TX_STATUS_SENDING;
Out_Valid <= '1';
Out_Data <= In_Meta_SequenceNumber(7 downto 0);
if (Out_Ack = '1') then
NextState <= ST_SEND_ECHOREQUEST_DATA;
end if;
when ST_SEND_ECHOREQUEST_DATA =>
Status <= NET_ICMPV4_TX_STATUS_SENDING;
Out_Valid <= '1';
Out_Data <= PayloadROM_Data;
PayloadROM_Reader_nxt <= '1';
if (Out_Ack = '1') then
if (PayloadROM_Reader_ov = '1') then
Out_EOF <= '1';
NextState <= ST_COMPLETE;
end if;
end if;
when ST_SEND_ECHOREPLY_DATA =>
Status <= NET_ICMPV4_TX_STATUS_SENDING;
Out_Valid <= '1';
Out_Data <= In_Meta_Payload_Data;
In_Meta_Payload_nxt <= '1';
if (Out_Ack = '1') then
if (In_Meta_Payload_last = '1') then
Out_EOF <= '1';
NextState <= ST_COMPLETE;
end if;
end if;
when ST_COMPLETE =>
Status <= NET_ICMPV4_TX_STATUS_SEND_COMPLETE;
NextState <= ST_IDLE;
end case;
end process;
Checksum <= x"0000";
SourceIPv4Seq : entity PoC.misc_Sequencer
generic map (
INPUT_BITS => 32,
OUTPUT_BITS => 8,
REGISTERED => FALSE
)
port map (
Clock => Clock,
Reset => Reset,
Input => to_slv(SOURCE_IPV4ADDRESS),
rst => Out_Meta_rst,
rev => '1',
nxt => Out_Meta_SrcIPv4Address_nxt,
Output => Out_Meta_SrcIPv4Address_Data
);
process(Clock)
begin
if rising_edge(Clock) then
if (PayloadROM_Reader_nxt = '0') then
PayloadROM_Reader_us <= (others => '0');
else
PayloadROM_Reader_us <= PayloadROM_Reader_us + 1;
end if;
end if;
end process;
PayloadROM_Reader_ov <= to_sl(PayloadROM_Reader_us = (PAYLOAD_ROM'length - 1));
PayloadROM_Data <= PAYLOAD_ROM(to_integer(PayloadROM_Reader_us));
In_Meta_IPv4Address_nxt <= Out_Meta_DestIPv4Address_nxt;
Out_Meta_DestIPv4Address_Data <= In_Meta_IPv4Address_Data;
end architecture;