Revisión del valor CRC después del ajuste de datos

1

Tengo un flujo de datos de 181 bytes con un valor CRC32 de 4 bytes al final. La longitud total del mensaje es de 185 bytes.

El flujo de datos se almacena en la memoria de un chip FPGA y está a la espera de que TCP lo conecte.

Antes de enviar el mensaje, hay que modificar algunos datos de 32 bits en el flujo de datos, por lo que es necesario revisar el valor de CRC.

La ubicación de los nuevos valores de bit son desde 41st - 63rd bit (comenzando el quinto byte) desde el LSB del flujo.

Como el CRC está dentro de la carga útil del mensaje tcp, el encabezado tcp y la suma de comprobación ip también deben revisarse.

Actualmente tengo que construir un módulo de canalización para volver a calcular el CRC de esta manera:

module crc32 (
input rst,
input clk,
input [255:0] in_data,
input crc_en,
output crc_out
);

Funciona pero necesita gastar 181 bytes / 256 bits ~ = 6 ciclos para revisar el valor CRC de un mensaje TCP de 181 bytes.

Aunque el CRC se encuentra al final del mensaje de negocios, la suma de control del encabezado tcp (que es más importante que la carga útil del TCP) solo se puede revisar cuando se calcula el nuevo valor de CRC. Esa es la razón por la que tiene que esperar 6 ciclos.

¿Hay algún algoritmo CRC de revisión inteligente para poder usar menos ciclos para revisar el CRC de un flujo de datos modificado?

Ideas:

  1. ¿Hay alguna forma de volver a calcular el CRC en función del antiguo valor CRC? CRC (nuevo) = revisar (CRC (antiguo))?
  2. Aprendo de este documento que parcheando el flujo de datos para mantener el antiguo valor CRC.

CH5: OBTENER UN CRC ELEGIDO ALTERANDO UNA POSICIÓN ELEGIDA

Es interesante pero requiere volver a calcular crc de n bit a m bit

donde n = ubicación de bit de inicio del campo modificado

m = ubicación de bit de inicio del campo de parche

que no se ve bien para guardar ciclos de reloj.

    
pregunta Ken Tsang

1 respuesta

0

1) Sí

2) Es complicado.

El CRC es una operación lineal en GF (2) (GF (2) es solo la manera elegante y discreta de decir binario, módulo 2 añadido). Por lo tanto, cada bit de tus 32 bits tendrá el mismo efecto en tus dos CRC en el modo add-modulo 2.

La forma realmente sensata (pero posiblemente lo suficientemente buena) de hacer esto es tener una tabla de 32 palabras de 32 bits. Para cada bit en su campo que voltea, XOR el CRC con la palabra correspondiente de la tabla. Eso debería funcionar bien. Las palabras reales en esa tabla son los CRC para todo el flujo de datos con cada bit, pero el bit en cuestión se establece en cero.

Hay formas alternativas de hacerlo: puede tener cuatro tablas de 256 palabras cada una, por ejemplo, con cada byte de su campo variable de 32 bits seleccionando una palabra de su tabla correspondiente. Eso le ahorra XORs al costo de mantener la tabla en la memoria.

Si funciona, es probable que desee generar su mensaje largo con la sección de variable establecida en cero, entonces no tendrá que calcular qué bits se han volteado, porque sabe que cualquier bit se establece en 1 en su variable de reemplazo campo son los bits volteados.

Pasar de un CRC de n bits hacia atrás a un campo de n bits que puede establecer libremente debería tener la misma propiedad de linealidad; Si puede agregar algunos bits al paquete después del mensaje deseado, debería poder decidir con anticipación qué desea que sea el paquete CRC, y luego configurarlo después del hecho. O puede hacer el mismo truco que mencioné anteriormente, con cada bit en el mensaje correspondiente a un patrón diferente de 32 bits en el espacio libre que necesita para alternar.

    
respondido por el TimWescott

Lea otras preguntas en las etiquetas