FPGA: Add multipixel - handle division by 2 and 4 for multipixels.

This commit is contained in:
2023-10-24 18:05:48 +02:00
parent e195432aea
commit c37a9fa768
3 changed files with 122 additions and 37 deletions

View File

@@ -8,6 +8,42 @@ struct add_multipixel_packet {
ap_uint<1> last;
};
ap_uint<512> divide_by_two(const ap_uint<512> &input) {
#pragma HLS PIPELINE II=1
ap_int<16> val[32];
unpack32(input, val);
for (int i = 0; i < 32; i++) {
if ((val[i] == INT16_MIN) || (val[i] == INT16_MAX))
val[i] = val[i];
else
val[i] = val[i] / 2;
}
return pack32(val);
}
void divide_last_by_two(ap_uint<512> &input) {
#pragma HLS PIPELINE II=1
ap_int<16> val[32];
unpack32(input, val);
if ((val[31] == INT16_MIN) || (val[31] == INT16_MAX))
val[31] = val[31];
else
val[31] = val[31] / 2;
input = pack32(val);
}
void divide_first_by_two(ap_uint<512> &input) {
#pragma HLS PIPELINE II=1
ap_int<16> val[32];
unpack32(input, val);
if ((val[0] == INT16_MIN) || (val[0] == INT16_MAX))
val[0] = val[0];
else
val[0] = val[0] / 2;
input = pack32(val);
}
void add_multipixel_in_stream(STREAM_512 &data_in,
hls::stream<add_multipixel_packet> &data_out) {
packet_512_t packet_in;
@@ -22,6 +58,40 @@ void add_multipixel_in_stream(STREAM_512 &data_in,
data_out << add_multipixel_packet{.data = packet_in.data, .user = packet_in.user, .last = packet_in.last};
}
void add_multipixel_div(hls::stream<add_multipixel_packet> &data_in,
hls::stream<add_multipixel_packet> &data_out) {
#pragma HLS INTERFACE axis port=data_in
#pragma HLS INTERFACE axis port=data_out
add_multipixel_packet packet_in, packet_out;
data_in >> packet_in;
data_out << packet_in;
ap_uint<1> add_multipixel = ((ACT_REG_MODE(packet_in.data) & MODE_ADD_MULTIPIXEL)) ? 1 : 0;
data_in >> packet_in;
if (!add_multipixel) {
while (!packet_in.user) {
#pragma HLS PIPELINE II=1
data_out << packet_in;
data_in >> packet_in;
}
} else {
while (!packet_in.user) {
#pragma HLS PIPELINE II=32
for (int i = 0; i < 32; i++) {
if ((i == 8 - 1) || (i == 2 * 8 - 1) || (i == 3 * 8 - 1))
divide_last_by_two(packet_in.data);
if ((i == 8) || (i == 2 * 8) || (i == 3 * 8))
divide_first_by_two(packet_in.data);
data_out << packet_in;
data_in >> packet_in;
}
}
}
data_out << packet_in;
}
void add_multipixel_cols(hls::stream<add_multipixel_packet> &data_in,
hls::stream<add_multipixel_packet> &data_out) {
#pragma HLS INTERFACE axis port=data_in
@@ -48,7 +118,7 @@ void add_multipixel_cols(hls::stream<add_multipixel_packet> &data_in,
ap_uint<512> save = packet_in.data;
data_in >> packet_in;
for (int i = 1; i < 8; i++) {
packet_out.data(511-8,0) = save(511,16);
packet_out.data(511-16,0) = save(511,16);
packet_out.data(511,512-16) = packet_in.data(15, 0);
data_out << packet_out;
save = packet_in.data;
@@ -56,10 +126,18 @@ void add_multipixel_cols(hls::stream<add_multipixel_packet> &data_in,
}
packet_out = packet_in;
packet_out.data = save(511,16);
packet_out.data(511, 512-16) = packet_out.data(511-16, 512-32);
data_out << packet_out;
save = 0;
for (int k = 1; k < 4; k++) {
if (k == 1) {
save = packet_in.data(15, 0);
} else if (k == 2) {
save(31,16) = save(15,0);
} else if (k == 3) {
save(63,48) = save(47,32);
}
for (int i = 0; i < 8; i++) {
packet_out.data(511, (k * 2 - 1) * 16) = packet_in.data(511 - (k * 2 - 1) * 16, 0);
packet_out.data((k * 2 - 1) * 16 - 1, 0) = save;
@@ -67,6 +145,10 @@ void add_multipixel_cols(hls::stream<add_multipixel_packet> &data_in,
data_out << packet_out;
data_in >> packet_in;
}
if (k == 1)
save(47, 32) = packet_in.data(15,0);
else if (k == 2)
save(79, 64) = packet_in.data(15,0);
}
packet_out.data = save;
@@ -105,8 +187,8 @@ void add_multipixel_line(hls::stream<add_multipixel_packet> &data_in,
#pragma HLS PIPELINE II=66
ap_uint<512> packet[33];
for (int i = 0; i < 33; i++) {
packet[i] = packet_in.data;
data_out << packet_in;
packet[i] = divide_by_two(packet_in.data);
data_out << add_multipixel_packet{.data = packet[i], .user = 0, .last = 0};
data_in >> packet_in;
}
for (int i = 0; i < 33; i++) {
@@ -189,8 +271,24 @@ void add_multipixel(STREAM_512 &data_in, STREAM_512 &data_out) {
hls::stream<add_multipixel_packet, 2> stream_0;
hls::stream<add_multipixel_packet, 2> stream_1;
hls::stream<add_multipixel_packet, 2> stream_2;
hls::stream<add_multipixel_packet, 2> stream_3;
#ifndef JFJOCH_HLS_NOSYNTH
add_multipixel_in_stream(data_in, stream_0);
add_multipixel_cols(stream_0, stream_1);
add_multipixel_line(stream_1, stream_2);
add_multipixel_output(stream_2, data_out);
add_multipixel_div(stream_0, stream_1);
add_multipixel_cols(stream_1, stream_2);
add_multipixel_line(stream_2, stream_3);
add_multipixel_output(stream_3, data_out);
#else
std::vector<std::thread> multipix_cores;
multipix_cores.emplace_back([&] {add_multipixel_in_stream(data_in, stream_0);});
multipix_cores.emplace_back([&] {add_multipixel_div(stream_0, stream_1);});
multipix_cores.emplace_back([&] {add_multipixel_cols(stream_1, stream_2);});
multipix_cores.emplace_back([&] {add_multipixel_line(stream_2, stream_3);});
multipix_cores.emplace_back([&] {add_multipixel_output(stream_3, data_out);});
for (auto &i : multipix_cores)
i.join();
#endif
}

View File

@@ -1,6 +1,7 @@
// Copyright (2019-2023) Paul Scherrer Institute
#include "hls_jfjoch.h"
#include "../../common/RawToConvertedGeometryCore.h"
int main() {
@@ -9,12 +10,14 @@ int main() {
STREAM_512 input;
STREAM_512 output;
size_t nframes = 1;
std::vector<int16_t> input_frame(nframes * RAW_MODULE_SIZE), output_frame(nframes * 257 * 64 * 32);
for (int i = 0; i < nframes * RAW_MODULE_SIZE; i++) {
std::vector<int16_t> input_frame(RAW_MODULE_SIZE), input_frame_transformed(CONVERTED_MODULE_SIZE),
output_frame(257 * 64 * 32);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
input_frame[i] = i % INT16_MAX;
}
TransferModuleAdjustMultipixels<int16_t, int16_t>(input_frame_transformed.data(), input_frame.data(),
CONVERTED_MODULE_COLS, INT16_MIN, INT16_MAX);
auto input_frame_512 = (ap_uint<512>*) input_frame.data();
auto output_frame_512 = (ap_uint<512>*) output_frame.data();
@@ -22,7 +25,7 @@ int main() {
ACT_REG_MODE(action_control) = MODE_ADD_MULTIPIXEL;
input << packet_512_t { .data = action_control, .user = 0 };
for (int i = 0; i < nframes * RAW_MODULE_SIZE * sizeof(uint16_t) / 64; i++)
for (int i = 0; i < RAW_MODULE_SIZE * sizeof(uint16_t) / 64; i++)
input << packet_512_t { .data = input_frame_512[i], .user = 0 };
input << packet_512_t { .user = 1 };
@@ -31,40 +34,23 @@ int main() {
if (input.size() != 0)
ret = 1;
if (output.size() != nframes * (257 * 64) + 2)
if (output.size() != (257 * 64) + 2)
ret = 1;
output.read();
for (int i = 0; i < nframes * 257 * 64 ; i++)
for (int i = 0; i < 257 * 64 ; i++)
output_frame_512[i] = output.read().data;
output.read();
size_t diff = 0;
for (int line = 1; line < 511; line++) {
int new_line = line + (line / 256) * 2 - 1;
for (int col = 1; col < 1023; col++) {
int new_col = col + (col / 256) * 2 - 1;
if (output_frame[new_line * 1028 + new_col] != input_frame[line * 1024 + col])
for (int line = 0; line < 512; line++) {
for (int col = 0; col < 1027; col++) {
if (output_frame[line * 1028 + col] != input_frame_transformed[(line + 1) * 1030 + (col+1)])
diff++;
}
}
for (int col = 1; col < 1023; col++) {
int new_col = col + (col / 256) * 2 - 1;
if (output_frame[254 * 1028 + new_col] != input_frame[255 * 1024 + col])
diff++;
if (output_frame[255 * 1028 + new_col] != input_frame[255 * 1024 + col])
diff++;
}
for (int col = 1; col < 1023; col++) {
int new_col = col + (col / 256) * 2 - 1;
if (output_frame[256 * 1028 + new_col] != input_frame[256 * 1024 + col])
diff++;
if (output_frame[257 * 1028 + new_col] != input_frame[256 * 1024 + col])
diff++;
}
if (diff > 0) {
ret = 1;
std::cout << diff << std::endl;

View File

@@ -27,7 +27,8 @@ ADD_EXECUTABLE(CatchTest
CBORTest.cpp ../tests/stream2.h ../tests/stream2.c
JFConversionTest.cpp DetectorGeometryTest.cpp JFJochBrokerParserTest.cpp DetectorSetupTest.cpp DiffractionGeometryTest.cpp ROIFilterTest.cpp
FPGAHLSBitshuffleTest.cpp
FPGASpotFindingUnitTest.cpp)
FPGASpotFindingUnitTest.cpp
FPGAAddMultipixelTest.cpp)
target_link_libraries(CatchTest JFJochBroker JFJochReceiver JFJochWriter ImageAnalysis CommonFunctions HLSSimulation)
target_include_directories(CatchTest PRIVATE .)