2D Perlin Noise Generator Accelerator
This is simple example that generate 2D perlin noise in FPGA and write the values to a file as python style lists. The main aim of this example is to introduce the DATAFLOW pragma which enable task level parallelism. However, the main purpose of using DATAFLOW pragma is to show how writing HLS C++ code for hardware generally requires a diffrent style of programming.
void perlin(int nx, int ny, float* result, const float freq)
{
#pragma HLS INTERFACE m_axi port=result
#pragma HLS DATAFLOW
hls::stream<Coord> coord_stream;
hls::stream<float> noise_stream;
const int N = nx*ny;
gen_coord(coord_stream, nx, ny, freq);
perlin_calc(coord_stream, noise_stream, N);
write_mem(noise_stream, result, N);
}
In the code snippet above, it might seem like gen_coord
is executed and then perlin_calc
and write_mem
respectively. In real hardware, those three functions are actually executed concurrently with data streams (coord_stream
and noise_stream
) connecting them. The data ‘flows’ between those 3 tasks, thus the name DATAFLOW.
gen_coord
generate x and y coordiate and write them tocoord_stream
one by one.perlin_calc
reads coordinates fromcoord_stream
and writes generated noise values tonoise_stream
.write_mem
reads noise values fromnoise_stream
and writes them to memory.
For more complex dataflows, the flow must be carefully designed to prevent any potential deadlocks.
Setup
This must be done everytime a new terminal is opened
source /opt/xilinx/xrt/setup.sh
# Replace <Vitis install path> and <vesion>
source <Vitis install path>/Vitis/<version>/settings64.sh
export PLATFORM_REPO_PATHS=/opt/xilinx/platforms
# Change to appropiate platform
export PLATFORM=xilinx_u250_gen3x16_xdma_4_1_202210_1
For software emulation:
export XCL_EMULATION_MODE=sw_emu
cd sw_emu
For hardware emulation:
export XCL_EMULATION_MODE=hw_emu
cd hw_emu
For hardware:
cd hw
Build Host Software
g++ -Wall -g -std=c++11 ../src/host.cpp -o perlin -I${XILINX_XRT}/include/ -L${XILINX_XRT}/lib/ -lOpenCL -pthread -lrt -lstdc++
Build And Link Kenel
# Replace ${TARGET} with / Set TARGET to:
# sw_emu if targeting software emulation
# hw_emu if targeting hardware emulation
# hw if targeting hardware
v++ -c -t ${TARGET} --platform ${PLATFORM} --config ../src/perlin.cfg -k perlin -I../src ../src/perlin.cpp -o perlin.xo
v++ -l -t ${TARGET} --platform ${PLATFORM} --config ../src/perlin.cfg ./perlin.xo -o perlin.xclbin
Configure Emulator
Only when targeting software/hardware emulation
emconfigutil --platform ${PLATFORM} --nd 1
Run the host software
# Replace <W> with width, <H> with height, and <freq> with frequency
./perlin perlin.xclbin <W> <H> <freq>
After running, a text file perlin_hls.txt
will be generated and contains lists of generated noise value.