One of ASH1 features is that it can perform – what we can call – software-controlled CRC calculation.

As we know CRC incorporates bit shifting, xoring and in sometimes inversion. We decided to have a unit in ASH1 that is dedicated to all these operations. For instance, we want to calculate CRC for a data byte prior to its transmission, we would simply push the byte on the stack, signal the CRC unit to start the calculation and then -without the need to wait for the calculation to be completed- we can send the byte out (over a physical line). Afterwards, if we’re interested in the CRC value, we could check for the completion through a special flag and then do whatever we want with the CRC. A more detailed description is coming below…

 

Here is the ASMD chart of the CRC unit.

 

The operation of the CRC unit is associated with one instruction which breaks down into two schemes calculation/checking and pushing/storing.

The first scheme deals with CRC calculation and checking where the byte stream for which the CRC to be generated/checked are pushed on the stack and the CRC unit will take these bytes sequentially and calculates/checks their CRC. This scheme is controlled by four signals (start, update, crc5en and data11bit_en) .

The second scheme usually comes after the CRC calculation is done, where the CRC field will be pushed onto the stack. Eventually, it will be ready for sending it over the physical line. A special care needs to be taken into how the CRC field is pushed.  As it was mentioned before, a typical USB packet sends its bytes with the LSB first, but when it comes to CRC field the MSB will be sent first. Therefore, ASH1 reverses the CRC field to allocate for this condition.

There are two types of CRC for USB packets, a 5-bti and 16-bit CRCs. Since the data stack elements are 8-bit wide care must be taken as ASH1 pushes a single byte for CRC 5 (which needs to be shifted to the right 3 times afterwards to get the MSB of the 5-bit CRC) and pushes two bytes so a programmer must pop the first byte after it has been sent over the physical line.

CRC calculation/ checking takes more than one cycle as it needs a sequence of bit shifting and XORing for a single byte of data. Therefore, ASH1 gives the option of calculating/ checking CRC independently while running other instructions. Whenever the programmer wants to acquire the result, the flag (ready_crc: flag2[1]) must be checked for CRC calculation. This flag can be checked directly after the CRC instruction.

A typical pseudo code for a CRC operation is summarized in the following steps:

  1. Push data on stack.
  2. Start CRC.
  3. Perform Other instructions/ Check for completion.
  4. Push CRC on stack.