⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 internet.vhd

📁 设计ip协议的vhdl实现
💻 VHD
📖 第 1 页 / 共 2 页
字号:
-------------------------------------------------------------------------------
-- 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 + -