Code examples to showcase how to get started with FPGA Manager. Error handling is kept at a minimum to show the bare necessities. The examples can be run against a reference design target.
.NET Core Hello World
FPGA Manager assembly hello world.
{
class Program
{
static void Main(string[] args)
{
using (var mgr =
new FPGAMgr.FpgaManagerApi(
FPGAMgr.ApiUrl.UDP(
"192.168.33.12")))
{
Console.WriteLine($"FPGA Manager Version: {mgr.Details.BaseDllVersion} / {mgr.Details.ApiDllVersion}");
var memory = mgr.CreateMemoryMap(0);
mgr.Open();
Console.WriteLine($"Register: {memory.ReadRegister(0x10001000):X8}");
}
}
}
}
.NET Core Basic Memory I/O
Basic memory access done quick.
{
class Program
{
static void Main(string[] args)
{
using (var mgr =
new FPGAMgr.FpgaManagerApi(
FPGAMgr.ApiUrl.UDP(
"192.168.33.12")))
{
var memory = mgr.CreateMemoryMap(0);
mgr.Open();
memory.WriteRegister(0x10001000, 0xDEADBEEF);
var registerValue = memory.ReadRegister(0x10001000);
Console.WriteLine($"Read {registerValue:X8} from register");
var fifoBuffer = new UInt32[100];
memory.ReadMailbox(0x10001000, fifoBuffer);
memory.WriteMailbox(0x10001000, fifoBuffer);
var byteBuffer = new byte[100];
memory.ReadContiguous(0x00000000, byteBuffer, 0, byteBuffer.Length);
memory.WriteContiguous(0x00000000, byteBuffer, 0, byteBuffer.Length);
}
}
}
}
.NET Core Simple Stream Loopback
Push data trough a byte stream in TAP fashion.
{
class Program
{
static async Task Main(string[] args)
{
using (var mgr =
new FPGAMgr.FpgaManagerApi(
FPGAMgr.ApiUrl.UDP(
"192.168.33.12")))
{
var memory = mgr.CreateMemoryMap(0);
var stream = mgr.CreateStream(1,
FPGAMgr.StreamType.ByteStream,
FPGAMgr.StreamDirection.Bidirectional);
mgr.Open();
memory.WriteRegister(0x10002000, 0);
const int TransferSize = 1100;
var bufferOut = new byte[TransferSize];
var bufferIn = new byte[TransferSize];
new Random().NextBytes(bufferOut);
var readTask = stream.ReadAsync(bufferIn);
stream.Write(bufferOut);
var transferred = (await readTask).TransferredLength;
var matches = bufferOut.SequenceEqual(bufferIn);
Console.WriteLine($"Read {transferred} bytes, data {(matches ? "matches" : "does not match")}");
}
}
}
}
.NET Core Register Bank Helper
Hassle free handling of IP register offsets
{
class Program
{
static void Main(string[] args)
{
using (var mgr =
new FPGAMgr.FpgaManagerApi(
FPGAMgr.ApiUrl.UDP(
"192.168.33.12")))
{
var memory = mgr.CreateMemoryMap(0);
mgr.Open();
var bankBabe =
new FPGAMgr.RegisterBank(0x10001000, memory);
var bankBram =
new FPGAMgr.RegisterBank(0x00000000, memory);
var bankLedz =
new FPGAMgr.RegisterBank(0x10000000, memory);
Console.WriteLine($"Read {bankBabe.ReadRegister(0):X8} from register");
bankLedz.WriteRegister(0, 1);
var byteBuffer = new byte[100];
bankBram.ReadContiguous(0x00000047, byteBuffer, 0, byteBuffer.Length);
memory.WriteContiguous(0x00000147, byteBuffer, 0, byteBuffer.Length);
}
}
}
}
C++ Hello World
FPGA Manager C++ API hello world.
#include "FpgaManager.h"
#include <iostream>
int main()
{
std::cout << "FPGA Manager Version: " << mgr.Details() << std::endl;
auto& mm = mgr.CreateMemoryMap(0);
mgr.Open();
std::cout << "Register: " << std::hex << mm.ReadRegister(0x10001000) << std::endl;
return 0;
}
C++ Simple Stream Loopback
Push data trough a byte stream
#include "FpgaManager.h"
#include <iostream>
#include <vector>
#include <random>
#include <mutex>
#include <algorithm>
#include <condition_variable>
int main()
{
auto& memory = mgr.CreateMemoryMap(0);
auto& stream = mgr.CreateStream(1, fpgamgr::StreamType::ByteStream, fpgamgr::StreamDirection::Bidirectional);
mgr.Open();
memory.WriteRegister(0x10002000, 0);
constexpr int TransferSize = 1100;
std::vector<uint8_t> buffer_out(TransferSize);
std::vector<uint8_t> buffer_in(TransferSize);
{
std::random_device rnd_device;
std::mt19937 rnd_engine(rnd_device());
std::uniform_int_distribution<int> distribution(0, 255);
std::generate(buffer_out.begin(), buffer_out.end(), [&] { return distribution(rnd_engine); });
}
std::mutex mx;
std::condition_variable cv;
stream.ReadAsync(buffer_in.data(), buffer_in.size(),
[&cv](const fpgamgr::IStream::TransferDetails& details)
{
std::cout << "transferred " << details.transferred << " bytes of " << details.requested << " requested" << std::endl;
cv.notify_one();
});
stream.Write(buffer_out.data(), buffer_out.size());
{
std::unique_lock<std::mutex> lk(mx);
cv.wait(lk);
}
bool matches = 0 == std::memcmp(buffer_in.data(), buffer_out.data(), buffer_in.size());
std::cout << "received data " << (matches ? "matches" : "does not match") << std::endl;
return 0;
}
AnsiC Hello World
FPGA Manager library hello world.
#include "FpgaManagerApi.h"
#include <stdio.h>
#include <stdint.h>
int main()
{
SystemHandle sysHandle = NULL;
uint8_t major, minor;
printf("FPGA Manager Version: %d.%02d\n", major, minor);
DeviceHandle devHandle = NULL;
MmAccessHandle mmHandle = NULL;
uint8_t buffer[4];
MmAccessApi_Read(mmHandle, buffer,
sizeof(buffer), 0x10001000,
false,
false, NULL);
printf("Register: %02x%02x%02x%02x\n", buffer[3], buffer[2], buffer[1], buffer[0]);
return 0;
}