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

📄 internet.vhd

📁 设计ip协议的vhdl实现
💻 VHD
📖 第 1 页 / 共 2 页
字号:
--	|                                   Source IP Address                                      |
--	|                                                                                          |
--	--------------------------------------------------------------------------------------------
--	|                                 Destination IP Address                                   |
--	|                                                                                          |
--	--------------------------------------------------------------------------------------------
--	|                          Options (if any - ignored)               |       Padding        |
--	|                                                                   |      (if needed)     |
--	--------------------------------------------------------------------------------------------
--	|                                          Data                                            |
--	|                                                                                          |
--	--------------------------------------------------------------------------------------------
--	|                                          ....                                            |
--	|                                                                                          |
--	--------------------------------------------------------------------------------------------
--
-- * - in 32 bit words 

	process (presState, returnState, cnt, frameDataLatch, datagramLen, headerLen, dataLen, newFrame, wrCnt,
			complete, frameType, checksum, targetIP, bufferSelectSig, targetIdent,
			position0, position1, ident0, ident1, fragmentOffset, moreFragments, timeout0, timeout1,
			endFrame, newFrameByte, frameValid)
	begin
		-- signal defaults
		wrRAM <= '0';
		wrData <= (others => '0');
		wrAddr <= (others => '0');
		datagramSize <= (others => '0');
		incCnt <= '0';
		rstCnt <= '0';
		incWrCnt <= '0';
		rstWrCnt <= '0';
		newDataGram <= '0';
		-- the following two signals remember their previous value if not reassigned
		nextHeaderLen <= headerLen;
		nextDatagramLen <= datagramLen;
		doWrite <= '0';
		getNewByte <= '0';
		latchFrameData <= '0';
		shiftInSourceIP <= '0';
		shiftInTargetIP <= '0';
		latchProtocol <= '0';
		newHeader <= '0';
		newByte <= '0';
		inByte <= (others => '0');
		latchMoreFragments <= '0';
		shiftInFragmentOffset <= '0';

		shiftInIdentification <= '0';		
		nextBufferSelect <= bufferSelectSig;
		latchIdent <= '0';
		resetIdent <= '0';
		updatePosition <= '0';
		resetPosition <= '0';
		resetTimeout <= '0';
	
		case presState is
			when stIdle =>
				-- wait for the arrival of a new frame that has a frameType of 1
				if newFrame = '0' or frameType = '0' then
					nextState <= stIdle;
				else
					-- reset the counters for the next datagram
					rstCnt <= '1';
					rstWrCnt <= '1';
					newHeader <= '1';
					nextState <= stGetHeaderLen;
					-- get header length and version information
					getNewByte <= '1';
				end if;

			when stGetHeaderLen =>
				-- check ip version
				if frameDataLatch (7 downto 4) /= 4 then
					nextState <= stIdle;
				else
					nextState <= stGetHeaderByte;
					-- send data to checksum machine
					inByte <= frameDataLatch;
					newByte <= '1';
					-- get the header length in bytes, rather than 32-bit words
					nextHeaderLen <= frameDataLatch (3 downto 0) & "00";
				end if;
			
			when stGetHeaderByte =>
				-- if we've finished getting the headers and processing them, start on the data
				-- once finished, refragmenting will come next
				if cnt = headerLen then
					-- only operate on data meant for us, or broadcast data
					if checksum = 0 and (targetIP = DEVICE_IP or targetIP = x"FFFFFFFF") then
					
						-- determine which buffer should be used to handle the data
						if ident0 = targetIdent and timeout0 /= FULLTIME then
							-- the ident matches and the timeout counter has not expired
							nextBufferSelect <= '0';
							-- accept the frame if its offset matches what we think it should be
							-- this drops out of order and duplicate frames.
							if position0 = fragmentOffset & "000" then
								nextState <= stGetDataByte;
							else
								nextState <= stIdle;
							end if;												
						elsif ident1 = targetIdent and timeout1 /= FULLTIME then
							-- the ident matches and the timeout counter has not expired							
							nextBufferSelect <= '1';
							-- accept the frame if its offset matches what we think it should be
							-- this drops out of order and duplicate frames.
							if position1 = fragmentOffset & "000" then
								nextState <= stGetDataByte;
							else
								nextState <= stIdle;
							end if;												
						elsif (ident0 = 0 or timeout0 = FULLTIME) and fragmentOffset = 0 then
							-- The ident doesn't match either of the buffers so check if buffer 0
							-- is free.  If ident = 0 or the timeout has expired then the buffer is free
							-- This must be the first fragment if it is to go here so also check the offset
							nextState <= stGetDataByte;
							nextBufferSelect <= '0';
						elsif (ident1 = 0 or timeout1 = FULLTIME) and fragmentOffset = 0 then
							-- The ident doesn't match either of the buffers so check if buffer 1
							-- is free.  If ident = 0 or the timeout has expired then the buffer is free
							-- This must be the first fragment if it is to go here so also check the offset
							nextState <= stGetDataByte;
							nextBufferSelect <= '1';
						else
							nextState <= stIdle;
						end if;
					else
						-- ignore frame as it wasn't for us
						nextState <= stIdle;
					end if;
					
				-- otherwise get the next header byte from RAM
				else
					nextState <= stStoreHeaderByte;
					getNewByte <= '1';
				end if;
				
			when stStoreHeaderByte =>
				nextState <= stGetHeaderByte;
				-- operate on each value of the header received according to count
				-- count will be one higher than the last byte received, as it is incremented
				-- at the same time as the data is streamed in, so
				-- when the data is seen to be available, count should also be one higher
				
				-- Send data to checksum process
				newByte <= '1';
				inByte <= frameDataLatch;
				
				-- Operate on data in the header
				case cnt(4 downto 0) is				
					when "00011" =>
						nextDatagramLen (10 downto 8) <= frameDataLatch (2 downto 0);
					when "00100" =>
						nextDatagramLen (7 downto 0) <= frameDataLatch;
					when "00101" | "00110" =>
						shiftInIdentification <= '1';
					when "00111" =>
						shiftInFragmentOffset <= '1';
						latchMoreFragments <= '1';
					when "01000" =>
						shiftInFragmentOffset <= '1';
					when "01010" =>
						latchProtocol <= '1';
					when "01101" | "01110" | "01111" | "10000" =>
						shiftInSourceIP <= '1';
					when "10001" | "10010" | "10011" | "10100" =>					
						shiftInTargetIP <= '1';
					when others =>
				end case;
			
			when stGetDataByte =>
				-- if we haven't finished receiving the data, then
				if cnt /= datagramLen then
					nextState <= stSetupWriteDataByte;
					-- read an IP data byte from the data stream...
					getNewByte <= '1';
				elsif endFrame = '1' and frameValid = '1' then
					-- this means that the frame is finished and was valid
					-- so update the buffer data and go to final state
					nextState <= stCompleteFragment;
					resetTimeout <= '1';	-- start/restart timer
					latchIdent <= '1';		-- allocate buffer to data
					if fragmentOffset = 0 then	-- check if this is the first fragment
						resetPosition <= '1';	-- give position initial value
					else
						updatePosition <= '1';  -- or add to the amount of data stored
					end if;
				elsif endFrame = '1' then
					-- the frame is complete but not valid so ignore it
					nextState <= stIdle;
				else
					-- the frame is not complete so keep looping until it is
					nextState <= stGetDataByte;
				end if;
				
			when stSetupWriteDataByte =>
				nextState <= stGetDataByte;
				--Set up to write the byte that was read in stGetDataByte to RAM
				doWrite <= '1';
				wrData <= frameDataLatch;

			when stCompleteFragment =>
				-- Signal the transport protocols if the datagram is finished
				-- or await next frame.
				nextState <= stIdle;
				if moreFragments = '0' then
					-- Last frame so :
					newDatagram <= '1';		-- notify higher protocols it's ready
					resetIdent <= '1';		-- free buffer for next time
					if bufferSelectSig = '0' then	-- output datagram size from correct buffer
						datagramSize <= position0;
					else
						datagramSize <= position1;
					end if;
				end if;
				
			when stDoWrite =>
				-- Wait for RAM write request to be serviced
				if complete = '0' then
					-- keep signals asserted until complete is high
					nextState <= stDoWrite;
					wrRAM <= '1';
					-- The address is based on the fragment offset and buffer
					if bufferSelectSig = '0' then
						wrAddr <= "001" & (wrCnt + (fragmentOffset & "000"));
					else
						wrAddr <= "010" & (wrCnt + (fragmentOffset & "000"));
					end if;
					wrData <= frameDataLatch;
				else
					-- when write is finished, go to returnState
					nextState <= returnState;
					incWrCnt <= '1';
				end if;

			when stGetNewByte =>
				if newFrameByte = '0' then
					-- wait for new byte to arrive
					nextState <= stgetNewByte;
				else
					-- latch new byte and go to returnState
					nextState <= returnState;
					incCnt <= '1';
					latchFrameData <= '1';
				end if;
			when others =>
		end case;
	end process;
	
	-- Perform 2's complement to one's complement conversion, and invert output
	checksumInt <= checksumLong(15 downto 0) + checksumLong(16);
	checksum <= NOT checksumInt;

	process (clk,rstn)
	begin
		if rstn = '0' then
			checkState <= stMSB;
			latchMSB <= (others => '0');
			checkSumLong <= (others => '0');
			lastNewByte <= '0';
		elsif clk'event and clk = '1' then
			-- this is used to check only for positive transitions
			lastNewByte <= newByte;		
			
			case checkState is
				when stMSB =>
					if newHeader = '1' then
						-- reset calculation
						checkState <= stMSB;
						checkSumLong <= (others => '0');
					elsif newByte = '1' and lastNewByte = '0' then
						-- latch MSB of 16 bit data
						checkState <= stLSB;
						latchMSB <= inByte;
					else
						checkState <= stMSB;
					end if;
				when stLSB =>
					if newHeader = '1' then
						-- reset calculation
						checkState <= stMSB;
						checkSumLong <= (others => '0');
					elsif newByte = '1' and lastnewByte = '0' then
						-- add with 2's complement arithmetic (convert to 1's above)
						checkState <= stMSB;
						checkSumLong <= ('0' & checkSumInt) + ('0' & latchMSB & inByte);
					else
						checkState <= stLSB;
					end if;
				when others =>
					checkState <= stMSB;
			end case;
		end if;
	end process;	
end internet_arch;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -