FCS verification of ethernet frame

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

• 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. – Paebbels May 15 '15 at 7:21
• Should this be an edit to your previous question? electronics.stackexchange.com/questions/169965/… – David May 15 '15 at 7:30

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.

• i edit the code for crc which i have used to calcaluate FCS. please check it. – sidharth kashyap May 20 '15 at 7:35

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 .