¿Diseño de enrutador Verilog y la mejor manera de manejar paquetes de tamaño variable en verilog?

Tengo una pregunta de diseño lógico/Verilog sintetizable. Mi pregunta es más lógica que la sintaxis.

Deseo implementar algún tipo de enrutador que tenga tres puertos de entrada/salida de UART RS232 de dúplex completo, que se envían paquetes entre sí.

Principales puntos de diseño:

  • Los paquetes son de tamaño variable y contienen los siguientes campos: fuente (1 byte), destino (1 byte), longitud de la carga útil (2 bytes), carga útil.
  • la longitud de la carga útil es variable entre 4 y 2000 bytes.
  • Quiero tener algún tipo de tabla de enrutamiento "qué destino se enrutará a cuál de los puertos UART", y algún tipo de firewall (no estoy seguro del nombre correcto) algo así como "qué fuentes permiten enviar paquetes a qué puertos UART".
  • se permite loopback (el paquete que se recibe y se envía a través del mismo puerto)
  • se permite la transmisión (tal vez la dirección de destino que se enrutó a más de un puerto UART)
  • el módulo debe ser genérico para poder expandirlo a más de 4 puertos.

Para mí, creo que la parte más difícil para empezar es cómo manejar paquetes de tamaño variable. Si los paquetes tuvieran un tamaño fijo y no demasiado grandes, habría tenido un FIFO de entrada y un FIFO de salida para cada puerto UART:

reg [tamaño_paquete-1:0] fifo[núm_de_paquetes]

cada FIFO de entrada habría almacenado en cada FIFO [I] un paquete completo que se recibió del uart, y un módulo que lee paquetes completos de cada FIFO de entrada, verifica la fuente el destino de cada paquete y usa eso enruta el paquete al quería salida FIFO, y desde allí un transmisor UART que toma un paquete y lo envía byte tras byte. El problema es que un paquete puede ser realmente muy grande, por lo que no quiero tener un fifo que tenga 2000 bytes en cada celda...

Eso también trae la pregunta de cómo transferir los paquetes entre los módulos internos. Como se dijo, un paquete puede llegar a ser realmente grande.

Me doy cuenta de que hay muchas preguntas en mi publicación, pero agradeceré mucho cualquier ayuda. Además, si hay algunos diseños de referencia o algo similar que pueda ayudarme, con gusto lo revisaré.

Gracias por la ayuda.

¿Es posible un escenario en el que múltiples puertos de entrada reciban un paquete masivo de 2k simultáneamente, cada uno destinado al mismo puerto de salida?

Respuestas (3)

Suponiendo que varios puertos de entrada puedan recibir datos a la vez, no puede garantizar que pueda transmitir de un puerto a otro en tiempo real. Porque dos puertos podrían intentar enrutar al mismo destino al mismo tiempo.

Por lo tanto, necesitará un búfer de paquetes para cada puerto de entrada.

Ciertamente, no desea un FIFO de 2000 bytes x N porque eso desperdiciaría mucha memoria.

La consecuencia de desperdiciar memoria, por supuesto, es que no puede almacenar en el búfer tantos paquetes. En situaciones en las que hay mucho tráfico, esto podría provocar la pérdida de paquetes.

En lugar de utilizar un FIFO en el que cada elemento sea un paquete, utilice un buffer de bytes circular. De esa manera, no habrá desperdiciado espacio al almacenar paquetes más pequeños.

Para implementar el búfer circular solo mantenga algunos índices.

Deje que el índice P1 apunte al inicio del primer paquete en el búfer. Deje que el índice P2 apunte justo después del final del último paquete completo en el búfer. Deje que el índice P3 apunte al último byte recibido.

A medida que los paquetes entran procesan su cabecera en tiempo real. Solo colóquelos en el búfer si tiene espacio (que se puede calcular a partir de P1, P2 y el tamaño de su búfer).

Si puede ajustar el paquete, coloque sus bytes en el búfer a medida que ingresan. P3 se incrementa para cada byte.

Si un paquete solo se recibe parcialmente y se agota el tiempo de espera, puede restablecer P3 a P2.

En pocas palabras, "análisis del peor de los casos", y en este caso, supongo que tiene requisitos de rendimiento mínimos o nulos, y solo desea recibir datos y transmitirlos.

2kB no es mucha memoria, pero el preámbulo aparentemente tiene toda la información que necesita para transmitir "en tiempo real". Una vez que sepa adónde va (destino), y suponiendo que no tiene necesidad de interpretar ni operar con los datos, todo lo que necesita hacer, después de recibir el preámbulo y configurar su transmisor, es recopilar un byte/palabra (lo que sea). el tamaño de sus datos es para la carga útil) y transmítalos, una y otra vez, hasta que haya alcanzado el conteo de bytes. Debería poder hacer esto con una arquitectura "ping-pong FIFO"... probablemente, con una latencia cercana a la longitud del preámbulo (es decir, un retraso en la canalización).

El almacenamiento mínimo (memoria y/o registros) para lo que describí es ~ (número de bytes en el preámbulo) + (2*número de bits para datos)

Bueno, necesita usar FIFO, pero almacenarán bytes en lugar de paquetes y usará máquinas de estado para controlar las transferencias para que se transfiera la cantidad correcta de bytes para cada paquete. También es posible dividir el encabezado de las cargas útiles y almacenarlas en FIFO separados, lo que puede o no ser útil según la aplicación.

Pero, ¿es esta realmente una buena aplicación para un FPGA? Los UART suelen ser bastante lentos y puede obtener microcontroladores que tienen muchos UART de hardware (es decir, Atmel xmega).