FCS-Verifizierung des Ethernet-Frames

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;

Wenn in Ihrer Netzwerkkarte aktiviert, zeigt Wireshark alle Frames an. Es zeigt auch die korrekte Prüfsumme für den Rahmen an, wenn Sie einen fehlerhaften senden.
Sollte dies eine Bearbeitung Ihrer vorherigen Frage sein? electronic.stackexchange.com/questions/169965/…

Antworten (2)

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.

Ich bearbeite den Code für crc, mit dem ich FCS berechnet habe. Überprüfen Sie bitte das.

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 .