ethernet checksum nightmare

Hi, I have been fighting with this for some time now and I cannot figure it out. I have read the 802.3 information and I have read a lot of forums and they all have some kind of general answer.

I am trying to create a very simple MAC module that will send data to a PHY for transmission. I am currently using the aesic crc VHDL function to perform my CRC checks.

Let's say I want to send the following packet (I know this is not a correct ethernet packet. Bear with me):

00 00 12 33 FF FF (in bytes) The bytes will be sent with the left most byte first.

0000 0000 0000 0000 0001 0010 0011 0011 1111 1111 (in bits)

I would first switch the bits in each byte individually and then feed it to the CRC module which has been initialized with all 1s.

Therefore

0000 0000 0000 0000 1000 0100 1100 1100 1111 1111

is fed into the CRC module starting with the byte on the left most side.

Hopefully this is correct so far.

After the last byte is fed through, I will grab the output of the CRC module, Invert it and shift it's bits.

The output from the CRC is

7E 11 64 34 ( in bytes)

0111 1110 0001 0001 0110 0100 0011 0100 ( in bits)

After inverting

1000 0001 1110 1110 1001 1011 1100 1011 ( in bits)

After switching

1101 0011 1101 1001 0111 0111 1000 0001 ( in bits)

D3 D9 77 81 ( in bytes)

This means that my packet that I will send to the PHY will be start with the left most byte

00 00 12 33 FF FF D3 D9 77 81 ( in bytes)

This value seems to agree with some CRC32 software I found on the net.

**************************************************

NOW lets say i am receiving this data from the PHY.

00 00 12 33 FF FF D3 D9 77 81 ( in bytes)

I do the same as for sending, I switch the bits in each byte (including the FCS) and feed it to the CRC module which has been initialized to all 1. After sending the right most byte, I should get the magic number C7 04 DD 7B out which says that it is working but i don't. Below is the exact sequence of CRC output:

Previous CRC Value | Input | Next CRC Value | Next FCS Value FFFFFF | 00 | 4E08BFB4 | D202EF8D

4E08BFB4 | 00 | 00B7647D | 41D912FF 00B7647D | 12 | A5EAE0CF | 0CF8A85A A5EAE0CF | 33 | 648CF998 | E660CED9 648CF998 | FF | 82AF68FF | 00E90ABE 82AF68FF | FF | 7E116434 | D3D97781 7E116434 | D3 | BB9FD215 | 57B40622 BB9FD215 | D9 | 07F1A3E0 | F83A701F 07F1A3E0 | 77 | 16C33676 | 91933c97 16C33676 | 81 | F86C1D9B | 2647C9E0

The VHDL code I used is below: process(clk) begin if(clk'event and clk = '1') then crc_32_out

Reply to
axr0284
Loading thread data ...

Did you remeber to initialize the CRC funtion to all 1 at the beginning.

Rough code from my old working Ethernet CRC calculator is following (there might be some twists in the code that i don't remember anymore). The CRC function seems to be the same that easics tool give, altough it's done by other tools.

Pseudocode:

data_input,incoming_data,crc_tmp,final_crc : std_logic_vector(7 downto 0)

for_all_bytes: for i in 0 to 7 loop data_input(i) '1') else crc_tmp=crc_32_8(data_input,crc_tmp)

finish_calc: final_crc=NOT(crc_tmp)

--Kim

Reply to
Kim Enkovaara

Yes the CRC module is always initialized to all 1 for the first byte. Amish

Reply to
axr0284

When computing the packet for sending, it gives me the proper answer. It's when receiving that i am having an issue since I do not see the "magic number as the output of the CRC module. I think i might be feeding in the original CRC at the end of the packet the wrong way or something. Amish

Reply to
axr0284

Then just why don't you calculate the CRC while receiving only for the data and compare the two CRC values. You just have to make sure that the sender works fine. I used commercial testers to make sure that the calculated CRC matches real world.

--Kim

Reply to
Kim Enkovaara

You flipped nibbles, not bytes.

0000 0000 0000 0000 0100 1000 1100 1100 1111 1111 or 00 00 48 CC FF FF hex is what you should input

The FCS of the ethernet packet is the only portion that is sent most significant bit first. Thus there is no need to "switch" it.

Reply to
Colin Hankins

Go here for an exactly correct packet:

formatting link

=================== Philip Freidin snipped-for-privacy@fpga-faq.org Host for

formatting link

Reply to
Philip Freidin

Hi Colin, Thanks for the answer. This is strange. I guess i am confused with the results from software programs I used such as the one on this website

formatting link
and what I get in hardware. I would expect it to the same but i am not sure that it is. I am trying to implement a MAC in an FPGA and I need to be sure that what I am sending to the PHY and out on the wire will be understood by the receiving MAC from a NIC card for example.

So if I send 00 00 12 33 FF FF to the PHY from the FPGA, this is what is sent on the WIRE from the PHY

00 00 84 CC FF FF

lsb first for each byte

So I feed the original data "00 00 12 33 FF FF" as is through the EASICS module with initialization of all 1, I get the AA C5 98 B0

Now it clearly states in the 802.3 specs that "The bit sequence is complemented and the result is the CRC"

So I need to complement the to get the : 55 3A 67 4F

Then I need to send it MSB first since the 802.3 spec says

"The 32 bits of the CRC value are placed in the frame check sequence field so that the x31 term is the leftmost bit of the first octet, and the x0 term is the right most bit of the last octet. (The bits of the CRC are thus """transmitted""" in the order x31, x30..., x1, x0.)"

So I need to switch the bits in each byte before appending to the Packet Therefore the becomes the AA 5C E6 F2

So the full packet is

00 00 12 33 FF FF AA 5C E5 F2

but what is sent on the wire is

00 00 84 CC FF 55 3A 67 4F

On receiving , I guess i need to flip the CRC back to 55 3A 67 4F before feeding it into the EASICS module to get the magic number.

I hope I got it right this time. This took a while. I think i will just recompute the packet and compare the incoming FCS with that. It might be easier. Thanks a lot, I really appreciate you taking the time to help me out, Amish

Reply to
axr0284

I am pretty sure that the design allows a simple LFSR with the transmitted bits as input, and then shifted out at the appropriate time. I believe, but am slightly less sure, that it also works such that a properly received frame will generate a constant value in the same LFSR when run through the data and FCS of the incoming frame.

Ethernet was designed in the days when logic was much more expensive than today. Simplifying the required logic was important.

(snip)

(snip)

(snip)

-- glen

Reply to
glen herrmannsfeldt

(snip)

That isn't quite true, as an FCS isn't a number, it is a bit string. That is, it doesn't have place values. All bits are equally significant in the result. (Being only tested for equality.)

Mathematically each bit is a coefficient of a term in a polynomial, but they are separate terms. Now, you might associate the bit with the higher power with the MSB, but if you consider it in terms of an LFSR even that doesn't matter.

-- glen

Reply to
glen herrmannsfeldt

That wouldn't make sense, because, as the bits come in you don't know when the CRC starts until after it is done. Consider doing it with an LFSR with the bit stream as input.

-- glen

Reply to
glen herrmannsfeldt

The packet start and end are available from the physical layer (for example in 8b/10b coding the S and T sets). Add few pipeline stages and the crc can be easily extracted from the packet.

I think the single bit LFSR solution is the worst one with current technology. With gigabit Ethernet the LFSR must run at 1GHz frequency, that is hard even with ASICs and consumes power. With 32b parallel crc calculation the frequency is just ~30MHz which is easy to handle, and with 32 bits the parallel implementation does not have so many layers of logic.

The pseudocode I sent earlier is from working ethernet mac chip, it does not use the magic number, but recalculates the crc and compares the two crc values.

--Kim

Reply to
Kim Enkovaara

Yes. The point is that one bit order works and the opposite does not.

-- Mike Treseler

Reply to
Mike Treseler

I believe, but am slightly less sure, that it also works

Both statements are true.

Yes and this is also the source of much confusion about the spec. The recommended LFSR circuit in the appendix does not implement the mathematical description in the text directly, even though the result is the same.

-- Mike Treseler

Reply to
Mike Treseler

Well, the OP didn't mention speed, but my answer was mostly meant in conceptual terms. One can go through and determine the result of the LFSR, and then how to implement that in parallel. I believe the solution is somewhat different than the usual parallel software (and look-up table) solution, but I don't remember it right now.

When ethernet was new, logic was much more expensive and the LFSR solution worked well.

-- glen

Reply to
glen herrmannsfeldt

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.