📄 ethernetsnd.vhd
字号:
when '0' & x"0" =>
next_TX_DATA <= destinationMACLatch (43 downto 40);
-- also send each byte to the CRC generator to create the CRC using
-- newCRCByte and CRCByte
when '0' & x"1" =>
next_TX_DATA <= destinationMACLatch (47 downto 44);
newCRCByte <= '1';
CRCByte <= destinationMACLatch (47 downto 40);
-- second byte of destination MAC address
when '0' & x"2" =>
next_TX_DATA <= destinationMACLatch(35 downto 32);
when '0' & x"3" =>
next_TX_DATA <= destinationMACLatch(39 downto 36);
newCRCByte <= '1';
CRCByte <= destinationMACLatch(39 downto 32);
-- third byte of destination MAC address
when '0' & x"4" =>
next_TX_DATA <= destinationMACLatch(27 downto 24);
when '0' & x"5" =>
next_TX_DATA <= destinationMACLatch(31 downto 28);
newCRCByte <= '1';
CRCByte <= destinationMACLatch(31 downto 24);
-- fourth byte of destination MAC address
when '0' & x"6" =>
next_TX_DATA <= destinationMACLatch(19 downto 16);
when '0' & x"7" =>
next_TX_DATA <= destinationMACLatch(23 downto 20);
newCRCByte <= '1';
CRCByte <= destinationMACLatch(23 downto 16);
-- fifth byte of destination MAC address
when '0' & x"8" =>
next_TX_DATA <= destinationMACLatch(11 downto 8);
when '0' & x"9" =>
next_TX_DATA <= destinationMACLatch(15 downto 12);
newCRCByte <= '1';
CRCByte <= destinationMACLatch(15 downto 8);
-- sixth byte of destination MAC address
when '0' & x"A" =>
next_TX_DATA <= destinationMACLatch(3 downto 0);
when '0' & x"B" =>
next_TX_DATA <= destinationMACLatch(7 downto 4);
newCRCByte <= '1';
CRCByte <= destinationMACLatch(7 downto 0);
-- first byte of source MAC address
when '0' & x"C" =>
next_TX_DATA <= DEVICE_MAC(43 downto 40);
when '0' & x"D" =>
next_TX_DATA <= DEVICE_MAC(47 downto 44);
newCRCByte <= '1';
CRCByte <= DEVICE_MAC(47 downto 40);
-- second byte of source MAC address
when '0' & x"E" =>
next_TX_DATA <= DEVICE_MAC(35 downto 32);
when '0' & x"F" =>
next_TX_DATA <= DEVICE_MAC(39 downto 36);
newCRCByte <= '1';
CRCByte <= DEVICE_MAC(39 downto 32);
-- third byte of source MAC address
when '1' & x"0" =>
next_TX_DATA <= DEVICE_MAC(27 downto 24);
when '1' & x"1" =>
next_TX_DATA <= DEVICE_MAC(31 downto 28);
newCRCByte <= '1';
CRCByte <= DEVICE_MAC(31 downto 24);
-- fourth byte of source MAC address
when '1' & x"2" =>
next_TX_DATA <= DEVICE_MAC(19 downto 16);
when '1' & x"3" =>
next_TX_DATA <= DEVICE_MAC(23 downto 20);
newCRCByte <= '1';
CRCByte <= DEVICE_MAC(23 downto 16);
-- fifth byte of source MAC address
when '1' & x"4" =>
next_TX_DATA <= DEVICE_MAC(11 downto 8);
when '1' & x"5" =>
next_TX_DATA <= DEVICE_MAC(15 downto 12);
newCRCByte <= '1';
CRCByte <= DEVICE_MAC(15 downto 8);
-- sixth byte of source MAC address
when '1' & x"6" =>
next_TX_DATA <= DEVICE_MAC(3 downto 0);
when '1' & x"7" =>
next_TX_DATA <= DEVICE_MAC(7 downto 4);
newCRCByte <= '1';
CRCByte <= DEVICE_MAC(7 downto 0);
-- ethernet type field byte one
when '1' & x"8" =>
next_TX_DATA <= x"8";
when '1' & x"9" =>
next_TX_DATA <= x"0";
newCRCByte <= '1';
CRCByte <= x"08";
-- ethernet type field byte two - 0 for IP and 6 for ARP (0000 or 0110)
when '1' & x"A" =>
next_TX_DATA <= '0' & NOT frameTypeLatch & NOT frameTypeLatch & '0';
CRCByte <= "00000" & NOT frameTypeLatch & NOT frameTypeLatch & '0';
newCRCByte <= '1';
-- after setting the last nybble, start sending the actual frame data
when '1' & x"B" =>
next_TX_DATA <= x"0";
when others =>
end case;
else
nextState <= stSendFrameHeaderCLKHI;
end if;
when stReadData =>
-- get the next byte of data from RAM, and latch it
if complete = '0' then
nextState <= stReadData;
rdRAM <= '1';
-- depending on the frame type, either pull the data from the ARP buffer or IP buffer
if frameTypeLatch = '1' then
rdAddr <= "00000001" & cnt;
else
rdAddr <= "00000000" & cnt;
end if;
else
nextState <= stSendFrameLoNybbleCLKLO;
latchRdData <= '1';
-- increment the address counter
incCnt <= '1';
end if;
when stSendFrameLoNybbleCLKLO =>
-- wait for another falling edge
-- do nothing in TX_CLKBuf low time
if TX_CLKBuf = '0' then
nextState <= stSendFrameLoNybbleCLKLO;
else
nextState <= stSendFrameHiNybbleCLKHI;
-- send the data just read to the CRC generator
newCRCByte <= '1';
CRCByte <= rdLatch;
end if;
when stSendFrameHiNybbleCLKHI =>
-- wait for the falling edge, then set TX_DATA
if TX_CLKBuf = '0' then
nextState <= stSendFrameHiNybbleCLKLO;
next_TX_DATA <= rdLatch (3 downto 0);
-- the CRC generator needs four bytes of 0s sent to it after we
-- finish sending it the frame data (ie count = frame length) to
-- correctly calculate the CRC
-- it needs 8 clock cycles to process each byte
-- send the first byte 0s needed for the CRC
if cnt = frameLen then
newCRCByte <= '1';
CRCByte <= x"00";
end if;
else
nextState <= stSendFrameHiNybbleCLKHI;
end if;
when stSendFrameHiNybbleCLKLO =>
-- do nothing when the transmit clock is low
if TX_CLKBuf = '0' then
nextState <= stSendFrameHiNybbleCLKLO;
else
nextState <= stSendFrameLoNybbleCLKHI;
-- send the second byte of 0s needed for the CRC to the CRC generator,
-- once all the data has been sent
if cnt = frameLen then
newCRCByte <= '1';
CRCByte <= x"00";
end if;
end if;
when stSendFrameLoNybbleCLKHI =>
-- on the falling edge send the lower nybble of data
if TX_CLKBuf = '0' then
-- if we've finished sending the data, prepare to send the CRC
-- after setting the last nybble of data
if cnt = frameLen then
nextState <= stSetCRCLO;
rstCnt <= '1';
-- send the third byte of 0s needed for the CRC to the CRC generator
newCRCByte <= '1';
CRCByte <= x"00";
-- otherwise keep reading and sending data
else
nextState <= stReadData;
end if;
next_TX_DATA <= rdLatch (7 downto 4);
-- wait for the falling edge
else
nextState <= stSendFrameLoNybbleCLKHI;
end if;
when stSetCRCLO =>
if TX_CLKBuf = '0' then
-- once we've sent the CRC, make sure we don't send anything else for
-- a while, and inform the next layer that the frame has been sent, and
-- take transmit enable back to low
if cnt = 9 then
nextState <= stLineWait;
frameSent <= '1';
rstLinePause <= '1';
TX_EN <= '0';
else
nextState <= stSetCRCLO;
end if;
else
nextState <= stSetCRCHI;
-- send the fourth byte of zeros needed to the CRC generator
-- the CRC should be ready now for the next falling edge so we
-- can send it
if cnt = 0 then
newCRCByte <= '1';
CRCByte <= x"00";
end if;
end if;
when stSetCRCHI =>
-- set the CRC on the falling edge, low byte first
if TX_CLKBuf = '0' then
nextState <= stSetCRCLO;
incCnt <= '1';
case cnt (2 downto 0) is
when "000" =>
next_TX_DATA <= CRC (3 downto 0);
when "001" =>
next_TX_DATA <= CRC (7 downto 4);
when "010" =>
next_TX_DATA <= CRC (11 downto 8);
when "011" =>
next_TX_DATA <= CRC (15 downto 12);
when "100" =>
next_TX_DATA <= CRC (19 downto 16);
when "101" =>
next_TX_DATA <= CRC (23 downto 20);
when "110" =>
next_TX_DATA <= CRC (27 downto 24);
when "111" =>
next_TX_DATA <= CRC (31 downto 28);
when others =>
end case;
-- wait for the falling edge
else
nextState <= stSetCRCHI;
end if;
when stLineWait =>
-- wait for linePause to overflow before being able to send another frame
-- make sure we're not still trying to transmit by keeping transmit enable low
TX_EN <= '0';
if linePauseOverflow = '1' then
nextState <= stIdle;
else
nextState <= stLineWait;
end if;
when others =>
end case;
end process;
end ethernetSnd_arch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -