Skip to content

Simple UDP Example

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

I am working on a basic 100Mb/s networking (eth/ip/udp) implementation.

The example uses 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.

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

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

uint32_t data;

If you think of the main function 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 bytes.

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 = 0; 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?

I'll tell you when I'm done.

Clone this wiki locally