Skip to content

Simple UDP Example

Julian Kemmerer edited this page Jul 29, 2018 · 21 revisions

I am working on a basic networking (ethernet/ip/udp) implementation.

The hardware I am using is a Digilent Arty Artix-35T board. https://store.digilentinc.com/arty-a7-artix-7-fpga-development-board-for-makers-and-hobbyists/

It uses a 32 bit AXIS (Advanced eXtensible Interface Streaming 4) interface from a Xilinx Tri-Mode Ethernet MAC. You might need to obtain an additional free license for the TEMAC - yeah, super annoying. My license might run out in a few weeks or so, so fuck me right.

Don't put too much weight behind the name 'AXIS' - its really simple:

Say I want to send you 7 bytes of data. I can send it in one chunk of 7 bytes, chunks of 2 bytes, or maybe I'll use 32b AXIS to do it in chunks of 4 bytes.

uint32_t data;

If you think of functions as being run in a loop then AXIS is how you receive a byte array over time. Sometimes in this loop you may have a valid set of 4 bytes to receive and sometimes not.

uint32_t data;
uint1_t valid; // The data is valid right now - do something with it

How will I know when I have received all the bytes? Tell me when I get the last chunk.

uint32_t data;
uint1_t valid; // The data is valid right now - do something with it
uint1_t last; // Last 4 bytes flag

But wait - two chunks of 4 bytes is 8 bytes total not 7! Well, only keep 3 bytes of the last chunk.

uint32_t data;
uint1_t valid; // The data is valid right now - do something with it
uint1_t last; // Last 4 bytes flag
uint4_t keep; // A bit for each byte in data (ex. keep = 7 (binary 0111) means keep only the first 3 bytes of data)

Ok so sending 7 bytes would look like this over time:

// 0+ iterations with valid=0
[... valid = 0; ...]
// The first chunk of 4 bytes
[data = (byte3, byte2, byte1, byte0); valid = 1; last = 0; keep=15]
// 0+ iterations with valid=0
[... valid = 0; ...]
// The last chunk of 3 bytes
[data = (<invalid>, byte6, byte5, byte4); valid = 1; last = 1; keep=7]

You can use AXIS to send any length byte array.

typedef struct axis32_t
{
	uint32_t data;
	uint1_t valid;
	uint1_t last;
	uint4_t keep;
} axis32_t;

So receiving a packet can look like:

... receive(axis32_t payload_axis)
{

}

And transmitting a packet can look like:

axis32_t transmit(...)
{
  axis32_t payload_axis;
  ...
  return payload_axis;
}

So what does this example project do?

Right now it receives two numbers in a UDP packet and sends another UDP packet with their sum. You should be able to replace 'two numbers' with anything and 'their sum' with some other work and make something at least mildly useful.

Here is the source code:

Clone this wiki locally