# Calculate CRC-16/Maxim in VHDL

I try to do a CRC-16/Maxim calculation in VHDL. My current implementation looks as follows

lfsr_c(0)  <= lfsr_q(15) XOR data_in;
lfsr_c(1)  <= lfsr_q(0);
lfsr_c(2)  <= lfsr_q(1) XOR lfsr_q(15) XOR data_in;
lfsr_c(3)  <= lfsr_q(2);
lfsr_c(4)  <= lfsr_q(3);
lfsr_c(5)  <= lfsr_q(4);
lfsr_c(6)  <= lfsr_q(5);
lfsr_c(7)  <= lfsr_q(6);
lfsr_c(8)  <= lfsr_q(7);
lfsr_c(9)  <= lfsr_q(8);
lfsr_c(10) <= lfsr_q(9);
lfsr_c(11) <= lfsr_q(10);
lfsr_c(12) <= lfsr_q(11);
lfsr_c(13) <= lfsr_q(12);
lfsr_c(14) <= lfsr_q(13);
lfsr_c(15) <= lfsr_q(14) XOR lfsr_q(15) XOR data_in;


With lfsr_q initiated to 0x0000. But this gives me the result for CRC-16/BUYPASS according to https://www.crccalc.com/

What do these RefIn and RefOut exactly mean and how would I change the above lfsr to output the CRC-16/MAXIM? Is my assumption correct that I don't have to manipulate my input so I still can shift in MSB first?

• I found some references that mention that one need to shift in the opposite direction, so right instead of left, but that seems to give completely wrong results. – po.pe May 24 '19 at 8:16

From crccalc's source code (Ref stands for 'reflect'):

    /// <summary>
/// This is a boolean parameter. If it is FALSE, input bytes are
/// processed with bit 7 being treated as the most significant bit
/// (MSB) and bit 0 being treated as the least significant bit.If this
/// parameter is FALSE, each byte is reflected before being processed.
/// </summary>
public bool RefIn { get; private set; }

/// <summary>
/// This is a boolean parameter. If it is set to FALSE, the
/// final value in the register is fed into the XOROUT stage directly,
/// otherwise, if this parameter is TRUE, the final register value is
/// reflected first.
/// </summary>


So basically, for the CRC/MAXIM, since both are true:

• You shift in LSB first because RefIn is true
• You mirror the output bits before applying the XOR mask

Regarding that XOR mask: you seem to have forgotten it, the MAXIM implementation specified 0xFFFF, which means you should invert each of your output bits before calculating the next stage polynomial.

Handy little resouces:

• That means this is not suitable for crc calculation in a serial protocol if I don't want to buffer the whole message first? – po.pe May 27 '19 at 16:47
• @Humpawumpa What gives you that idea? The XOR mask? that happens at every stage, so if your message is 15 bits long and you CRC 1 bit each clock cycle, you perform an XOR each stage. – DonFusili May 28 '19 at 7:13
• @Humpawumpa If your problem is the fact that you shift in LSB first, this is not a problem, you just have to shift in in the same order on both the send and receive side. – DonFusili May 28 '19 at 7:15