📄 internetsnd.vhd
字号:
-------------------------------------------------------------------------------
-- internetsnd.vhd
--
-- Author(s): Ashley Partis and Jorgen Peddersen
-- Created: Jan 2001
-- Last Modified: Feb 2001
--
-- Internet packet sending layer. Sends TPDUs from the transport layers as IP
-- packets. If the datagram is too large to fit into one frame (1480 bytes),
-- fragments are transmitted until the full datagram is transmitted. All
-- fragments transmitted except for the last fragment are 1024 bytes long. The
-- last fragment may be anything from 1 byte to 1480 bytes long depending on
-- how much of the datagram is left. Fragments are transmitted as soon as the
-- previous fragment is transmitted, and all fragments will be transmitted
-- before the IP layer becomes idle again.
-------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use work.global_constants.all;
entity InternetSnd is
port (
clk: in STD_LOGIC; -- clock
rstn: in STD_LOGIC; -- active low asynchronous reset
frameSent: in STD_LOGIC; -- indicates the ethernet has sent a frame
sendDatagram: in STD_LOGIC; -- signal to send a datagram message
datagramSize: in STD_LOGIC_VECTOR (15 downto 0); -- size of datagram to transmit
destinationIP: in STD_LOGIC_VECTOR (31 downto 0); -- IP to transmit message to
addressOffset: in STD_LOGIC_VECTOR (2 downto 0); -- Indicates location in RAM of datagram
protocol: in STD_LOGIC_VECTOR (7 downto 0); -- protocol of the datagram to be sent
complete: in STD_LOGIC; -- complete signal from the RAM operation
rdData: in STD_LOGIC_VECTOR (7 downto 0); -- read data from RAM
rdRAM: out STD_LOGIC; -- read signal for RAM
rdAddr: out STD_LOGIC_VECTOR (18 downto 0); -- read address for RAM
wrRAM: out STD_LOGIC; -- write signal for RAM
wrData: buffer STD_LOGIC_VECTOR (7 downto 0); -- write data for RAM
wrAddr: out STD_LOGIC_VECTOR (18 downto 0); -- write address for RAM
sendFrame: out STD_LOGIC; -- signal to get ethernet to send frame
datagramSent: out STD_LOGIC; -- tells higher protocol when the datagram was sent
frameSize: out STD_LOGIC_VECTOR (10 downto 0); -- tells the ethernet layer how long the frame is
ARPIP: out STD_LOGIC_VECTOR (31 downto 0) -- IP that the ARP layer must look up
);
end InternetSnd;
architecture InternetSnd_arch of InternetSnd is
-- State types and signals
type STATETYPE is (stIdle, stSetHeader, stWrHeader, stWrChksumHi, stWrChksumLo, stGetData, stMoreFragments, stWrData);
signal presState: STATETYPE;
signal nextState: STATETYPE;
-- Remember value of wrData
signal nextWrData: STD_LOGIC_VECTOR (7 downto 0);
-- counter signals
signal cnt: STD_LOGIC_VECTOR (10 downto 0);
signal incCnt: STD_LOGIC;
signal rstCnt: STD_LOGIC;
-- identification counter to tell different messages apart
signal idenCnt: STD_LOGIC_VECTOR (25 downto 0);
-- length of datagram to transmit next
signal datagramLen: STD_LOGIC_VECTOR (15 downto 0);
-- latch data read from RAM into the write data register
signal latchRdData: STD_LOGIC;
-- checksum signals : see internet.vhd for comments
signal checkState : STD_LOGIC;
CONSTANT stMSB : STD_LOGIC := '0';
CONSTANT stLSB : STD_LOGIC := '1';
signal checksumLong : STD_LOGIC_VECTOR (16 downto 0);
signal checksumInt : STD_LOGIC_VECTOR (15 downto 0);
signal latchMSB : STD_LOGIC_VECTOR (7 downto 0);
signal lastNewByte : STD_LOGIC;
signal newHeader: STD_LOGIC;
signal newByte: STD_LOGIC;
signal inByte: STD_LOGIC_VECTOR (7 downto 0);
signal checksum: STD_LOGIC_VECTOR (15 downto 0);
signal valid: STD_LOGIC;
-- destination IP register and signal
signal destinationIPLatch : STD_LOGIC_VECTOR (31 downto 0);
signal latchDestinationIP : STD_LOGIC;
-- addressOffset register and signal
signal addressOffsetLatch : STD_LOGIC_VECTOR (2 downto 0);
signal latchAddressOffset : STD_LOGIC;
-- protocol register and signal
signal protocolLatch : STD_LOGIC_VECTOR(7 downto 0);
signal latchProtocol : STD_LOGIC;
-- datagram size register and signal
signal datagramSizeLatch : STD_LOGIC_VECTOR(15 downto 0);
signal latchDatagramSize : STD_LOGIC;
-- current fragment offset and control signals
signal fragmentOffset : STD_LOGIC_VECTOR(5 downto 0);
signal incFragmentOffset : STD_LOGIC;
signal rstFragmentOffset : STD_LOGIC;
signal sizeRemaining : STD_LOGIC_VECTOR(15 downto 0); -- size of untransmitted data
signal moreFragments : STD_LOGIC; -- '0' = last fragment
signal idenLatch : STD_LOGIC_VECTOR (15 downto 0); -- register to hold idenCnt value for all fragments
signal latchIden : STD_LOGIC; -- latch idenLatch register
begin
-- Transmit to destination IP
ARPIP <= destinationIPLatch;
-- Caclulate size remaining, whether this is the last fragment and the size of the next fragment to send
sizeRemaining <= datagramSizeLatch - (fragmentOffset & "0000000000");
moreFragments <= '0' when sizeRemaining <= 1480 else '1';
-- size is either sizeRemaining + 20 or 1024 + 20. The header is always 20 bytes
datagramLen <= sizeRemaining + 20 when moreFragments = '0' else x"0414"; -- x"414" = 1024 + 20
process (clk, rstn)
begin
if rstn = '0' then
presState <= stIdle;
elsif clk'event and clk = '1' then
presState <= nextState; -- change state
idenCnt <= idenCnt + 1; -- increment identification counter every cycle
if latchRdData = '1' then -- either latch wrData from RAM or get the next value
wrData <= rdData;
else
wrData <= nextWrData;
end if;
if incCnt = '1' then -- increment or clear counter
cnt <= cnt + 1;
elsif rstCnt = '1' then
cnt <= (others => '0');
end if;
if latchDestinationIP = '1' then -- latch destination IP
destinationIPLatch <= destinationIP;
end if;
if latchAddressOffset = '1' then -- latch address offset
addressOffsetLatch <= addressOffset;
end if;
if latchProtocol = '1' then -- latch protocol
protocolLatch <= protocol;
end if;
if latchDatagramSize = '1' then -- latch size of datagram
datagramSizeLatch <= datagramSize;
end if;
if rstFragmentOffset = '1' then -- reset fragment offset for first fragment
fragmentOffset <= (others => '0');
elsif incFragmentOffset = '1' then -- increment it for each further fragment
fragmentOffset <= fragmentOffset + 1;
end if;
if latchIden = '1' then -- Get current value of upper bits of identification counter
idenLatch <= idenCnt(25 downto 10);
end if;
-- end fragmentation
end if;
end process;
-- IP datagram header format
--
-- 0 4 8 16 19 24 31
-- --------------------------------------------------------------------------------------------
-- | Version | *Header | Service Type | Total Length including header |
-- | (4) | Length | (ignored) | (in bytes) |
-- --------------------------------------------------------------------------------------------
-- | Identification | Flags | Fragment Offset |
-- | | | (in 32 bit words) |
-- --------------------------------------------------------------------------------------------
-- | Time To Live | Protocol | Header Checksum |
-- | (ignored) | | |
-- --------------------------------------------------------------------------------------------
-- | Source IP Address |
-- | |
-- --------------------------------------------------------------------------------------------
-- | Destination IP Address |
-- | |
-- --------------------------------------------------------------------------------------------
-- | Options (if any - ignored) | Padding |
-- | | (if needed) |
-- --------------------------------------------------------------------------------------------
-- | Data |
-- | |
-- --------------------------------------------------------------------------------------------
-- | .... |
-- | |
-- --------------------------------------------------------------------------------------------
--
-- * - in 32 bit words
process (presState, wrData, datagramLen, datagramSize, checksum, cnt, sendDatagram,
complete, idenLatch, destinationIPLatch, addressOffsetLatch, protocolLatch,
frameSent, moreFragments, fragmentOffset)
begin
-- default signals and outputs
rstCnt <= '0';
incCnt <= '0';
nextWrData <= wrData;
newHeader <= '0';
newByte <= '0';
inByte <= (others => '0');
wrRAM <= '0';
wrAddr <= (others => '0');
rdRAM <= '0';
rdAddr <= (others => '0');
sendFrame <= '0';
frameSize <= (others => '0');
latchRdData <= '0';
datagramSent <= '0';
latchAddressOffset <= '0';
latchDestinationIP <= '0';
latchProtocol <= '0';
latchDatagramSize <= '0';
latchIden <= '0';
incFragmentOffset <= '0';
rstFragmentOffset <= '0';
case presState is
when stIdle =>
-- wait until told to transmit
if sendDatagram = '0' then
nextState <= stIdle;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -