3
\$\begingroup\$

i am trying to transmit a Ethernet frame from fpga to pc. my udp frame is:

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");

for the above frame i have calculated the FCS using the crc-32.

polynomial-X"04C11DB7".

FCS is-X"D96F0BBF"

I have adopted following method to calculate FCS:

IEEE 802.3 defines the polynomial M(x) as the destination address, source address,length/type, and data of a frame, with the first 32-bits complemented. The result of CRC is complemented, and the result is the IEEE 802.3 32-bit CRC,referred to as the Frame Check Sequence (FCS) field. The FCS is appended to the end of the Ethernet frame, and is transmitted highest order bit first (x31, x30,…, x1, x0).

please tell me ,Is FCS correct or not?

and also tell me that if the FCS is not correct then will wireshark capture it or not?

the CRC logic which i have used to calculate-

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
);

end ethcrc32;


architecture nano of ethcrc32 is

-- 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;

end nano;

\$\endgroup\$
2
  • 1
    \$\begingroup\$ If enabled in your NIC, wireshark will display all frames. It also displays the correct checksum for the frame if you send a faulty one. \$\endgroup\$
    – Paebbels
    Commented May 15, 2015 at 7:21
  • \$\begingroup\$ Should this be an edit to your previous question? electronics.stackexchange.com/questions/169965/… \$\endgroup\$
    – David
    Commented May 15, 2015 at 7:30

2 Answers 2

3
\$\begingroup\$

Here is a sample implementation of an Ethernet CRC in VHDL, suitable for a test bench:

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;

The CRC for your frame is (as written in the previous answer): 9B F6 D0 FD.

If you have an MII interface (4 bits wide), the end of the frame should appear as:

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

The CRC is initalised with FFFFFFFF to correctly detect leading zeros in the frame. It is inverted and complemented at the end to generate a constant remainder to the Galois polynomial division: If you apply the CRC algorithm to the whole frame, including the 4 bytes FCS, you should always get the 'magic' constant 0xC704DD7B, for all valid frames.

\$\endgroup\$
1
  • \$\begingroup\$ i edit the code for crc which i have used to calcaluate FCS. please check it. \$\endgroup\$ Commented May 20, 2015 at 7:35
1
\$\begingroup\$

Wireshark will capture it unless your NIC drops it due to the bad CRC. Also, I think the FCS of that packet should be fdd0f69b. Don't forget that there are some odd bit reorderings that you have to do for the CRC to work out correctly.

Note that there are also open source implementations of this that you can use for reference, for example https://github.com/alexforencich/verilog-ethernet/blob/master/rtl/axis_eth_fcs.v .

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.