📄 internetsnd.vhd
字号:
else
-- latch all information about the datagram and set up first fragment
nextState <= stSetHeader;
rstCnt <= '1';
newHeader <= '1';
rstFragmentOffset <= '1';
latchDatagramSize <= '1';
latchIden <= '1';
latchAddressOffset <= '1';
latchDestinationIP <= '1';
latchProtocol <= '1';
end if;
when stSetHeader =>
-- write header into RAM
if cnt = x"14" then
-- header has been fully written so go to data stage
nextState <= stWrChksumHi;
nextWrData <= checksum (15 downto 8);
else
nextState <= stWrHeader;
newByte <= '1'; -- send byte to checksum calculator
-- choose wrData and inByte values
-- inByte is the data for the checksum signals
case cnt(4 downto 0) is
-- version and header length
when '0' & x"0" =>
nextWrData <= x"45";
inByte <= x"45";
-- total length high byte
when '0' & x"2" =>
nextWrData <= datagramLen (15 downto 8);
inByte <= datagramLen (15 downto 8);
-- total length low byte
when '0' & x"3" =>
nextWrData <= datagramLen (7 downto 0);
inByte <= datagramLen (7 downto 0);
-- identification high byte
when '0' & x"4" =>
nextWrData <= idenLatch(15 downto 8);
inByte <= idenLatch(15 downto 8);
-- identification low byte
when '0' & x"5" =>
nextWrData <= idenLatch (7 downto 0);
inByte <= idenLatch (7 downto 0);
-- flags and fragmentOffset high bits
when '0' & x"6" =>
nextWrData <= "00" & moreFragments & fragmentOffset(5 downto 1);
inByte <= "00" & moreFragments & fragmentOffset(5 downto 1);
-- fragmentOffset low byte
when '0' & x"7" =>
nextWrData <= fragmentOffset(0) & "0000000";
inByte <= fragmentOffset(0) & "0000000";
-- time to live
when '0' & x"8" =>
nextWrData <= x"20";
inByte <= x"20";
-- protocol
when '0' & x"9" =>
nextWrData <= protocolLatch;
inByte <= protocolLatch;
-- source IP for C, D, E, F
when '0' & x"C" =>
nextWrData <= DEVICE_IP(31 downto 24);
inByte <= DEVICE_IP(31 downto 24);
when '0' & x"D" =>
nextWrData <= DEVICE_IP(23 downto 16);
inByte <= DEVICE_IP(23 downto 16);
when '0' & x"E" =>
nextWrData <= DEVICE_IP(15 downto 8);
inByte <= DEVICE_IP(15 downto 8);
when '0' & x"F" =>
nextWrData <= DEVICE_IP(7 downto 0);
inByte <= DEVICE_IP(7 downto 0);
-- destination IP for 10, 11, 12, 13
when '1' & x"0" =>
nextWrData <= destinationIPLatch(31 downto 24);
inByte <= destinationIPLatch(31 downto 24);
when '1' & x"1" =>
nextWrData <= destinationIPLatch(23 downto 16);
inByte <= destinationIPLatch(23 downto 16);
when '1' & x"2" =>
nextWrData <= destinationIPLatch(15 downto 8);
inByte <= destinationIPLatch(15 downto 8);
when '1' & x"3" =>
nextWrData <= destinationIPLatch(7 downto 0);
inByte <= destinationIPLatch(7 downto 0);
-- Service type and checksum which will be updated later
when others =>
nextWrData <= (others => '0');
inByte <= (others => '0');
end case;
end if;
when stWrHeader =>
-- Write a byte to RAM
if complete = '0' then
-- Wait for RAM to acknowledge the write
nextState <= stWrHeader;
wrRAM <= '1';
wrAddr <= "00000001" & Cnt;
else
-- When it does increment the counter and go to next header byte
nextState <= stSetHeader;
incCnt <= '1';
end if;
when stWrChksumHi =>
-- Write high byte of the checksum to RAM
if complete = '0' then
-- Wait for RAM to acknowledge the write
nextState <= stWrChksumHi;
wrRAM <= '1';
wrAddr <= "000" & x"080a";
else
-- When it does write the lower byte
nextState <= stWrChksumLo;
nextWrData <= checksum (7 downto 0);
end if;
when stWrChksumLo =>
-- Write low byte of the checksum to RAM
if complete = '0' then
nextState <= stWrChksumLo;
wrRAM <= '1';
wrAddr <= "000" & x"080B";
else
-- When it does copy data from RAM to write location
nextState <= stGetData;
end if;
when stGetData =>
-- Read data from RAM if there is more left
if cnt = datagramLen then
-- If there is no more data left, wait until the frame completes sending
if frameSent = '1' then
nextState <= stMoreFragments;
else
-- otherwise tell the frame to send until it does finish sending
nextState <= stGetData;
sendFrame <= '1';
frameSize <= datagramLen (10 downto 0);
end if;
else
-- if there is more data then perform a read from RAM
if complete = '0' then
-- Wait for RAM to acknowledge read
nextState <= stGetData;
rdRAM <= '1';
rdAddr <= (addressOffsetLatch & (fragmentOffset + cnt(10)) & cnt(9 downto 0)) - 20;
else
-- Then get ready to write the data
nextState <= stWrData;
latchRdData <= '1';
end if;
end if;
when stWrData =>
-- Write one data byte
if complete = '0' then
-- Wait for RAM to acknoledge the write
nextState <= stWrData;
wrRAM <= '1';
wrAddr <= "00000001" & cnt;
else
-- When done, read another byte
nextState <= stGetData;
incCnt <= '1';
end if;
when stMoreFragments =>
-- When the frame has finished transmitting
if moreFragments = '1' then
-- There are more fragments so set up data for the next fragment and generate it
nextState <= stSetHeader;
rstCnt <= '1';
newHeader <= '1';
incFragmentOffset <= '1';
else
-- There are no more fragments so wait for a new datagram to arrive
nextState <= stIdle;
end if;
when others =>
end case;
end process;
-- checksum calculator : see internet.vhd for comments
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');
valid <= '0';
lastNewByte <= '0';
elsif clk'event and clk = '1' then
lastNewByte <= newByte;
case checkState is
when stMSB =>
if newHeader = '1' then
checkState <= stMSB;
checkSumLong <= (others => '0');
valid <= '0';
elsif newByte = '1' and lastNewByte = '0' then
checkState <= stLSB;
latchMSB <= inByte;
valid <= '0';
else
checkState <= stMSB;
valid <= '1';
end if;
when stLSB =>
valid <= '0';
if newHeader = '1' then
checkState <= stMSB;
checkSumLong <= (others => '0');
elsif newByte = '1' and lastnewByte = '0' then
checkState <= stMSB;
checkSumLong <= ('0' & checkSumInt) + ('0' & latchMSB & inByte);
else
checkState <= stLSB;
end if;
when others =>
checkState <= stMSB;
valid <= '0';
end case;
end if;
end process;
end InternetSnd_arch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -