4
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Is a scenario possible where multiple input ports receive a massive 2k packet simultaneously each destined for the same output port? \$\endgroup\$ – Tom Carpenter Oct 16 '18 at 7:09
1
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

Simply put, "Worst-case analysis", and in this case, I'm guessing you have little-to-no performance requirements, and just want to receive data and transmit it.

2kB is not a lot of memory, but, the preamble seemingly has all the information you need to transmit "real-time". Once you know where it is going (destination), and assuming you have no need to interpret or operate on the data, all you need to do, after receiving the preamble, and setting up your transmitter , is collect a byte/word (whatever your data size is for the payload) and transmit it, over-and-over, until you have met the byte count. You should be able to do this with a "ping-pong FIFO" architecture... probably, with a latency close to the preamble length (i.e. a pipeline delay).

Minimum storage (memory and/or registers) for what I described is ~ (number of bytes in preamble) + (2*number of bits for data)

\$\endgroup\$
0
\$\begingroup\$

Well, you need to use FIFOs, but they will store bytes instead of packets and you'll use state machines to control transfers so that the correct number of bytes are transferred for each packet. It is also possible to split the header from the payloads and store them in separate FIFOs, which may or may not be useful depending on the application.

But is this really a good application for an FPGA? UARTs are usually quite slow, and you can get microcontrollers that have a lot of hardware UARTs (i.e. Atmel xmega).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.