-
Notifications
You must be signed in to change notification settings - Fork 56
Simple UDP Example
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.