Ich versuche, einen Ethernet-Frame von FPGA auf den PC zu übertragen. Mein UDP-Frame ist:
constant udp_frameB :frame60:=
(x"FF",x"FF",x"FF",x"FF", -- mac dest
x"FF",x"FF",x"00",x"00",
x"00",x"04",x"14",x"13", -- mac src
x"08",x"00",x"45",x"00", -- IP header
x"00",x"2E",x"00",x"00",
x"00",x"00",x"40",x"11",
x"7A",x"C0",x"00",x"00", -- IP src
x"00",x"00",x"FF",x"FF", -- IP dest
x"FF",x"FF",x"00",x"00", -- port src
x"50",x"DA",x"00",x"12",-- port dest + len
x"00",x"00",x"42",x"42", -- checksum udp + data "B"
x"42",x"42",x"42",x"42",
x"42",x"42",x"42",x"42",
x"42",x"42",x"42",x"42",
x"42",x"42",x"42",x"42");
Für den obigen Rahmen habe ich den FCS mit dem CRC-32 berechnet.
Polynom-X"04C11DB7".
FCS ist-X"D96F0BBF"
Ich habe folgende Methode zur Berechnung von FCS übernommen:
IEEE 802.3 definiert das Polynom M(x) als Zieladresse, Quelladresse, Länge/Typ und Daten eines Rahmens, wobei die ersten 32 Bits komplementiert sind. Das Ergebnis von CRC wird komplementiert, und das Ergebnis ist das IEEE 802.3 32-Bit-CRC, das als Frame Check Sequence (FCS)-Feld bezeichnet wird. Der FCS wird an das Ende des Ethernet-Frames angehängt und zuerst mit dem höchstwertigen Bit übertragen (x31, x30,…, x1, x0).
Bitte sagen Sie mir, ist FCS korrekt oder nicht?
und sagen Sie mir auch, dass, wenn das FCS nicht korrekt ist, es dann von Wireshark erfasst wird oder nicht?
die CRC-Logik, die ich zur Berechnung verwendet habe-
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity ethcrc32 is
port (clk: in STD_LOGIC; -- Input clock
rst: in STD_LOGIC; -- Asynchronous reset
en : in STD_LOGIC; -- Assert to compute calculations
is_msb: in STD_LOGIC; -- Assert to indicate the sens of data_in
data_in: in STD_LOGIC_VECTOR(7 downto 0); -- Data to compute
crc_out: out STD_LOGIC_VECTOR (31 downto 0) -- CRC output
);
ethcrc32 beenden;
Architektur nano von ethcrc32 ist
-- The Generator polynomial is
-- 32 26 23 22 16 12 11 10 8 7 5 4 2
-- x + x + x + x + x + x + x + x + x + x + x + x + x + x + 1
constant GENERATOR : STD_LOGIC_VECTOR := X"04C11DB7";
begin
process (clk,rst) is
variable crc_buf : STD_LOGIC_VECTOR (31 downto 0):=x"00000000";
begin
if rst = '1' then -- reset signals to values
crc_buf := (others => '0');
elsif rising_edge(clk) then -- operate on positive edge
if (en='1') then
if is_msb='1' then
for I in data_in'reverse_range loop
crc_buf := (crc_buf(30 downto 0) & data_in(I)) XOR (GENERATOR AND (0 to 31=>crc_buf(31)));
end loop;
else
for I in data_in'reverse_range loop
crc_buf := (crc_buf(30 downto 0) & data_in(I)) XOR (GENERATOR AND (0 to 31=>crc_buf(31)));
end loop;
end if;
end if;
end if;
crc_out<=crc_buf;
end process;
Ende Nano;
Hier ist eine beispielhafte Implementierung eines Ethernet-CRC in VHDL, geeignet für einen Prüfstand:
TYPE arr_byte IS ARRAY(natural RANGE <>) OF unsigned(7 DOWNTO 0);
CONSTANT CRC_POLY : unsigned(31 DOWNTO 0) := x"04C11DB7";
FUNCTION crc (data : arr_byte) RETURN arr_byte IS
VARIABLE r : arr_byte(0 TO 3) := (x"00",x"00",x"00",x"00");
VARIABLE c : unsigned(31 DOWNTO 0) :=x"FFFFFFFF";
VARIABLE mm : unsigned(31 DOWNTO 0);
BEGIN
FOR I IN data'range LOOP
FOR J IN 0 TO 7 LOOP
mm:=(OTHERS => data(I)(J) XOR c(31));
c:=(c(30 DOWNTO 0) & '0') XOR (mm AND CRC_POLY);
END LOOP;
END LOOP;
FOR I IN 0 TO 31 LOOP
mm(I):=NOT c(31-I);
END LOOP;
r(3):=mm(31 DOWNTO 24);
r(2):=mm(23 DOWNTO 16);
r(1):=mm(15 DOWNTO 8);
r(0):=mm( 7 DOWNTO 0);
RETURN r;
END FUNCTION crc;
Der CRC für Ihren Frame lautet (wie in der vorherigen Antwort geschrieben): 9B F6 D0 FD.
Wenn Sie eine MII-Schnittstelle (4 Bit breit) haben, sollte das Ende des Rahmens wie folgt aussehen:
2 4 2 4 2 4 2 4 2 4 2 4 | B 9 6 F 0 D D F ]
end of the payload | CRC
Der CRC wird mit FFFFFFFF initialisiert, um führende Nullen im Rahmen korrekt zu erkennen. Es wird invertiert und am Ende ergänzt, um einen konstanten Rest der Galois-Polynomdivision zu erzeugen: Wenn Sie den CRC-Algorithmus auf den gesamten Rahmen anwenden, einschließlich der 4 Bytes FCS, sollten Sie immer die "magische" Konstante 0xC704DD7B erhalten, für alle gültig Rahmen.
Wireshark erfasst es, es sei denn, Ihre NIC löscht es aufgrund des schlechten CRC. Außerdem denke ich, dass der FCS dieses Pakets fdd0f69b sein sollte. Vergessen Sie nicht, dass Sie einige ungerade Bitumordnungen vornehmen müssen, damit der CRC richtig funktioniert.
Beachten Sie, dass es auch Open-Source-Implementierungen davon gibt, die Sie als Referenz verwenden können, zum Beispiel https://github.com/alexforencich/verilog-ethernet/blob/master/rtl/axis_eth_fcs.v .
Paebbels
David