📄 internet.vhd
字号:
-------------------------------------------------------------------------------
-- internet.vhd
--
-- Author(s): Ashley Partis and Jorgen Peddersen
-- Created: Jan 2001
-- Last Modified: Feb 2001
--
-- IP layer for network stack project. This accepts byte-streams of data from
-- the ethernet layer and decodes the IP information to send data to the upper
-- protocols. Reassembly is implemented and two incoming packets can be
-- reassembled at once. Reassembly only works if incoming packets come in
-- order.
-------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use work.global_constants.all;
entity internet is
port (
clk: in STD_LOGIC; -- clock
rstn: in STD_LOGIC; -- asynchronouse active low reset
complete: in STD_LOGIC; -- control signal from ram arbitrator
newFrame: in STD_LOGIC; -- new frame received from the layer below
frameType: in STD_LOGIC; -- frame type = '1' for IP
newFrameByte: in STD_LOGIC; -- signals a new byte in the stream
frameData: in STD_LOGIC_VECTOR (7 downto 0); -- data is streamed in here
endFrame: in STD_LOGIC; -- signals the end of a frame
frameValid: in STD_LOGIC; -- determines validity of frame when endFrame is high
newDatagram: out STD_LOGIC; -- an IP datagram has been fully received
bufferSelect: out STD_LOGIC; -- indicates location of data in RAM, '0' = 10000, '1' = 20000
datagramSize: out STD_LOGIC_VECTOR (15 downto 0); -- size of the datagram received
protocol: out STD_LOGIC_VECTOR (7 downto 0); -- protocol type of datagram
sourceIP: out STD_LOGIC_VECTOR (31 downto 0); -- lets upper protocol know the source IP
wrRAM: out STD_LOGIC; -- signal to write to the RAM
wrData: out STD_LOGIC_VECTOR (7 downto 0); -- data to write to the RAM
wrAddr: out STD_LOGIC_VECTOR (18 downto 0); -- address lines to the RAM for writing
timeLED0: out STD_LOGIC; -- indicates if buffer 0 is busy
timeLED1: out STD_LOGIC -- indicates if buffer 1 is busy
);
end internet;
architecture internet_arch of internet is
-- signal declarations
-- FSM states
type STATETYPE is (stIdle, stGetHeaderLen, stGetHeaderByte, stStoreHeaderByte,
stGetDataByte, stSetupWriteDataByte, stCompleteFragment, stDoWrite, stgetNewByte);
signal presState: STATETYPE;
signal nextState: STATETYPE;
signal returnState: STATETYPE; -- Used to return from RAM 'subroutines'
signal headerLen: STD_LOGIC_VECTOR (5 downto 0); -- IP datagram header length
signal nextHeaderLen: STD_LOGIC_VECTOR (5 downto 0); -- signal for the next header lengh
signal datagramLen: STD_LOGIC_VECTOR (10 downto 0); -- IP datagram total length in bytes
signal nextDatagramLen: STD_LOGIC_VECTOR (10 downto 0); -- signal for the next datagram length
signal dataLen: STD_LOGIC_VECTOR (10 downto 0); -- IP datagram data length in bytes
signal nextDataLen: STD_LOGIC_VECTOR (10 downto 0); -- signal for the next data length
signal incCnt: STD_LOGIC; -- increments byte address counter
signal rstCnt: STD_LOGIC; -- resets byte address counter
signal cnt: STD_LOGIC_VECTOR (10 downto 0); -- byte address counter for the frame received
signal incWrCnt: STD_LOGIC; -- increments the write address counter
signal rstWrCnt: STD_LOGIC; -- resets the write address counter
signal wrCnt: STD_LOGIC_VECTOR (15 downto 0); -- write address counter for storing that data
signal doWrite: STD_LOGIC; -- tell RAM controller to write data
signal getNewByte: STD_LOGIC; -- wait for new data on the stream
signal latchFrameData: STD_LOGIC; -- latch in the data from the stream
signal frameDataLatch: STD_LOGIC_VECTOR (7 downto 0); -- register to hold latched data
signal targetIP: STD_LOGIC_VECTOR (31 downto 0); -- stores target IP (destination)
signal shiftInTargetIP: STD_LOGIC; -- signal to shift in target IP
signal shiftInSourceIP: STD_LOGIC; -- stores source IP
signal latchProtocol: STD_LOGIC; -- signal to shift in source IP
-- checksum signals
signal checkState : STD_LOGIC;
CONSTANT stMSB : STD_LOGIC := '0';
CONSTANT stLSB : STD_LOGIC := '1';
signal checksumLong : STD_LOGIC_VECTOR (16 downto 0); -- stores 2's complement sum
signal checksumInt : STD_LOGIC_VECTOR (15 downto 0); -- stores 1's complement sum
signal latchMSB : STD_LOGIC_VECTOR (7 downto 0); -- latch in first byte
signal newHeader: STD_LOGIC; -- resets checksum
signal newByte: STD_LOGIC; -- indicate new byte
signal lastNewByte : STD_LOGIC; -- detect changes in newByte
signal inByte: STD_LOGIC_VECTOR (7 downto 0); -- byte to calculate
signal checksum: STD_LOGIC_VECTOR (15 downto 0); -- current checksum
-- bufferSelect is used both to indicate which area in RAM to write to
-- and to indicate which buffer control signals are to operate on
signal nextBufferSelect: STD_LOGIC; -- allows memory of bufferSelect
signal bufferSelectSig : STD_LOGIC; -- allows memory of bufferSelect
signal identification: STD_LOGIC_VECTOR (15 downto 0); -- identification field
signal shiftInIdentification: STD_LOGIC; -- signal to shift in identification
signal fragmentOffset: STD_LOGIC_VECTOR (12 downto 0); -- fragment offset field
signal shiftInFragmentOffset: STD_LOGIC; -- signal to shift in offset
signal moreFragments : STD_LOGIC; -- more fragments flag
signal latchMoreFragments : STD_LOGIC; -- signal to determine MF flag
-- The ident signals are of the form "source IP : protocol : identification" and
-- are used in reassembly.
signal targetIdent: STD_LOGIC_VECTOR (55 downto 0); -- incoming frame's ident
signal ident0: STD_LOGIC_VECTOR (55 downto 0); -- current ident for buffer 0
signal ident1: STD_LOGIC_VECTOR (55 downto 0); -- current ident for buffer 1
signal latchIdent: STD_LOGIC; -- latch targetIdent into specified buffer ident
signal resetIdent: STD_LOGIC; -- clear ident of specified buffer to indicate a vacant buffer
signal position0: STD_LOGIC_VECTOR (15 downto 0); -- stores expected offset of next fragment
signal position1: STD_LOGIC_VECTOR (15 downto 0); -- stores expected offset of next fragment
signal updatePosition: STD_LOGIC; -- add dataLen to current position
signal resetPosition: STD_LOGIC; -- set position to be dataLen
constant TIMERWIDTH : INTEGER := 30; -- can be used to vary timeout length
signal timeout0: STD_LOGIC_VECTOR (TIMERWIDTH - 1 downto 0); -- timeout counter
signal timeout1: STD_LOGIC_VECTOR (TIMERWIDTH - 1 downto 0); -- timeout counter
signal resetTimeout: STD_LOGIC; -- start timeout counter
constant FULLTIME: STD_LOGIC_VECTOR (TIMERWIDTH - 1 downto 0) := (others => '1'); -- last value of timeout counter
signal sourceIPSig : STD_LOGIC_VECTOR (31 downto 0); -- internal signal for output
signal protocolSig : STD_LOGIC_VECTOR (7 downto 0); -- internal signal for output
begin
-- These signals are used instead of buffer ports
sourceIP <= sourceIPSig;
protocol <= protocolSig;
bufferSelect <= bufferSelectSig;
-- Indicate when buffers are busy
timeLED0 <= '0' when timeout0 = FULLTIME or ident0 = 0 else '1';
timeLED1 <= '0' when timeout1 = FULLTIME or ident1 = 0 else '1';
-- Some definitions to make further code simpler
targetIdent <= sourceIPSig & protocolSig & identification;
dataLen <= datagramLen - ("00000" & headerLen);
-- main clocked process
process (rstn, clk)
begin
if rstn = '0' then -- only need to reset required signals
presState <= stIdle;
returnState <= stIdle;
ident0 <= (others => '0');
ident1 <= (others => '0');
timeout0 <= FULLTIME;
timeout1 <= FULLTIME;
elsif clk'event and clk = '1' then
-- Go to next state wither directly or via a RAM state.
-- If a RAM write or a new byte from the data stream are requested,
-- the state machine stores nextState in returnState and goes to the
-- required state. After completion, the state machine will go to
-- returnState. This is like a 'subroutine' in the state machine.
if doWrite = '1' then
presState <= stDoWrite;
returnState <= nextState;
elsif getNewByte = '1' then
presState <= stGetNewByte;
returnState <= nextState;
else
presState <= nextState;
end if;
-- increment and reset the counter synchronously to avoid race conditions
if incCnt = '1' then
cnt <= cnt + 1;
elsif rstCnt = '1' then
cnt <= (others => '0');
end if;
-- increment and reset the write address counter synchronously
if incWrCnt = '1' then
wrCnt <= wrCnt + 1;
elsif rstWrCnt = '1' then
wrCnt <= (others => '0');
end if;
-- latch data read from RAM
if latchFrameData = '1' then
frameDataLatch <= frameData;
end if;
-- these signals must remember their values once set
headerLen <= nextHeaderLen;
datagramLen <= nextDatagramLen;
-- shift registers and latches to hold important data
if shiftInSourceIP = '1' then
sourceIPSig <= sourceIPSig(23 downto 0) & frameDataLatch;
end if;
if shiftInTargetIP = '1' then
TargetIP <= TargetIP(23 downto 0) & frameDataLatch;
end if;
if latchProtocol = '1' then
protocolSig <= frameDataLatch;
end if;
if shiftInFragmentOffset = '1' then
fragmentOffset <= fragmentOffset (4 downto 0) & frameDataLatch;
end if;
if latchMoreFragments = '1' then
moreFragments <= frameDataLatch(5);
end if;
if shiftInIdentification = '1' then
identification <= identification (7 downto 0) & frameDataLatch;
end if;
-- bufferSelect will remember its previous value
bufferSelectSig <= nextBufferSelect;
-- handle timeout counters, resetTimeout will only reset the current buffer
if resetTimeout = '1' then
if bufferSelectSig = '0' then
timeout0 <= (others => '0');
else
timeout1 <= (others => '0');
end if;
else
-- increment timeout counters but don't let them overflow
if timeout0 /= FULLTIME then
timeout0 <= timeout0 + 1;
else
timeout0 <= FULLTIME;
end if;
if timeout1 /= FULLTIME then
timeout1 <= timeout1 + 1;
else
timeout1 <= FULLTIME;
end if;
end if;
-- the following signals will operate only on the current buffer which
-- is chosen with bufferSelect.
if bufferSelectSig = '0' then
-- manage the ident register of the buffer
if latchIdent = '1' then
ident0 <= targetIdent;
elsif resetIdent = '1' then
ident0 <= (others => '0');
end if;
-- manage the position register of the buffer
if resetPosition = '1' then
position0 <= "00000" & dataLen;
elsif updatePosition = '1' then
position0 <= position0 + dataLen;
end if;
else
-- manage the ident register of the buffer
if latchIdent = '1' then
ident1 <= targetIdent;
elsif resetIdent = '1' then
ident1 <= (others => '0');
end if;
-- manage the position register of the buffer
if resetPosition = '1' then
position1 <= "00000" & dataLen;
elsif updatePosition = '1' then
position1 <= position1 + dataLen;
end if;
end if;
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) | | |
-- --------------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -