Electronic – Verilog router design and best way to handle variable size packets in verilog

digital-logicfifofpgasystem-verilogverilog

I have a synthesizable Verilog/logical design question. My question is more logical than syntax.

I wish to implement some sort of router that has three input/output ports of full-duplex UART RS232, that are sending packets to each other.

Main points of design:

  • The packets are with variable size and they contain the following fields: source(1 byte), destination(1 byte), payload length(2 bytes), payload.
  • payload length is variable between 4-2000 bytes.
  • I want to have some sort of routing table "what destination will be routed to which of the UART ports", and some sort of firewall(not sure the proper name) something like "which sources allowed to send packets to which UART ports".
  • loopback is allowed (the packet that is received and sent through the same port)
  • broadcasting is allowed (maybe destination address that routed to more than one UART port)
  • the module needs to be generic so I could expand it to more than 4 ports.

For me, I think the hardest part to start with – is how to handle variable size packets? If the packets were fixed size, and not too big, I would have had an input FIFO and an output FIFO for each UART port:

reg [packet_size-1:0] fifo[num_of_packets]

each input FIFO would have stored in each fifo[I] a whole packet that was received from the uart, and a module that reads whole packets from each input FIFO, checks for source the dest of each packet and using that routes the packet to the wanted output FIFO,and from there a UART transmitter that takes a packet and sends it byte after byte.
Problem is that a packet can be really really big, so I don't want to hold a fifo that has 2000 bytes in each cell…

That also brings the question of how to transfer the packets between the internal modules?
As said, a packet can get really big.

I realize there are a lot of questions in my post, but I will much appreciate any help. Also, if there are some reference designs or something similar that can help me, I will happily review it.

Thanks for the help.

Best Answer

Supposing that multiple input ports may receive data at once, you can't guarantee that you can transmit from one port to another in real time. Because two ports could try to route to the same destination at the same time.

Therefore you will need a packet buffer for each input port.

You certainly don't want a 2000 byte x N FIFO because that would waste a lot of memory.

The consequence of wasting memory of course is that you can't buffer as many packets. In situations where there is a lot of traffic this could lead to dropped packets.

Instead of using a FIFO with each element being a packet, use a circular byte fuffer. That way you won't have wasted space when storing smaller packets.

To implement the circular buffer just keep a few indexes.

Let index P1 point to the start of the first packet in the buffer. Let index P2 point just past the end of the last complete packet in the buffer. Let index P3 point to the last byte received.

As the packets come in process their header in real time. Only put them in the buffer if you have space (which can be calculated from the P1, P2, and your buffer size).

If you can fit the packet then put its bytes into the buffer as they come in. P3 is incremented for each byte.

If a packet is only partially received and a timeout occurs you can reset P3 back to P2.