Files
Jungfraujoch/tests/FPGANetworkTest.cpp

472 lines
14 KiB
C++

// Copyright (2019-2022) Paul Scherrer Institute
// SPDX-License-Identifier: GPL-3.0-or-later
#include <catch2/catch.hpp>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <net/if_arp.h>
#include "../receiver/HLSSimulatedDevice.h"
// ARP packet - from if_arp.h
#pragma pack(push)
#pragma pack(2)
struct RAW_ARP_Packet
{
unsigned char dest_mac[6];
unsigned char sour_mac[6];
uint16_t ether_type;
unsigned short int ar_hrd; /* Format of hardware address. */
unsigned short int ar_pro; /* Format of protocol address. */
unsigned char ar_hln; /* Length of hardware address. */
unsigned char ar_pln; /* Length of protocol address. */
unsigned short int ar_op; /* ARP opcode (command). */
unsigned char __ar_sha[6]; /* Sender hardware address. */
unsigned char __ar_sip[4]; /* Sender IP address. */
unsigned char __ar_tha[6]; /* Target hardware address. */
unsigned char __ar_tip[4]; /* Target IP address. */
};
#pragma pack(pop)
TEST_CASE("HLS_Network_ARP_Gratuitous") {
HLSSimulatedDevice device(0, 64);
const uint16_t nmodules = 4;
DiffractionExperiment x((DetectorGeometry(nmodules)));
auto gain_from_file = GainCalibrationFromTestFile();
device.CreateFinalPacket(x);
device.StartAction(x);
device.WaitForActionComplete();
packet_512_t network_packet;
device.OutputStream().read(network_packet);
auto arp_packet = (RAW_ARP_Packet *) &network_packet.data;
for (int i = 0; i < 6; i++) {
REQUIRE(arp_packet->dest_mac[i] == 0xFF);
REQUIRE(arp_packet->__ar_tha[i] == 0xFF);
}
REQUIRE(arp_packet->ether_type == htons(ETHER_ARP));
REQUIRE(arp_packet->ar_op == htons(ARPOP_REQUEST));
REQUIRE(arp_packet->ar_hrd == htons(ARPHRD_ETHER));
REQUIRE(arp_packet->ar_pro == htons(ETHER_IP));
REQUIRE(arp_packet->ar_hln == 6);
REQUIRE(arp_packet->ar_pln == 4);
}
TEST_CASE("HLS_Network_UDP") {
char packet[130*64];
auto jf_packet = (jf_raw_packet *) packet;
jf_packet->ipv4_header_sour_ip = htonl(0x12345640);
jf_packet->udp_length = htons(8248);
jf_packet->udp_dest_port = htons(129);
jf_packet->jf.framenum = 123456;
STREAM_512 udp_in;
STREAM_512 udp_out;
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > udp_metadata;
auto jf_packet_axi = (ap_uint<512> *) packet;
uint64_t packet_counter;
ap_uint<1> clear_counter = 0;
for (int i = 0; i < 130; i++) {
packet_512_t packet_in;
packet_in.user = 0;
packet_in.last = (i == 129);
packet_in.data = jf_packet_axi[i];
udp_in.write(packet_in);
udp(udp_in, udp_out, udp_metadata, packet_counter, clear_counter);
}
REQUIRE(udp_in.size() == 0);
REQUIRE(udp_metadata.size() == 1);
REQUIRE(udp_out.size() == 129);
packet_512_t packet_out;
udp_out.read(packet_out);
REQUIRE(packet_out.data(63,0) == jf_packet->jf.framenum);
ap_uint<UDP_METADATA_STREAM_WIDTH> udp_metadata_out;
udp_metadata.read(udp_metadata_out);
REQUIRE(udp_metadata_dest_port(udp_metadata_out) == 129);
REQUIRE(udp_metadata_payload_size(udp_metadata_out) == 8240);
REQUIRE(udp_metadata_eth_err(udp_metadata_out) == 0);
REQUIRE(udp_metadata_len_err(udp_metadata_out) == 0);
}
TEST_CASE("HLS_Network_UDP_EthErr") {
char packet[130*64];
auto jf_packet = (jf_raw_packet *) packet;
jf_packet->udp_length = htons(8248);
jf_packet->udp_dest_port = htons(129);
jf_packet->jf.framenum = 123456;
STREAM_512 udp_in;
STREAM_512 udp_out;
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > udp_metadata;
auto jf_packet_axi = (ap_uint<512> *) packet;
uint64_t packet_counter;
ap_uint<1> clear_counter = 0;
for (int i = 0; i < 130; i++) {
packet_512_t packet_in;
packet_in.user = (i == 129) ? 1 : 0;
packet_in.last = (i == 129);
packet_in.data = jf_packet_axi[i];
udp_in.write(packet_in);
udp(udp_in, udp_out, udp_metadata, packet_counter, clear_counter);
}
REQUIRE(udp_in.size() == 0);
REQUIRE(udp_metadata.size() == 1);
REQUIRE(udp_out.size() == 129);
packet_512_t packet_out;
udp_out.read(packet_out);
REQUIRE(packet_out.data(63,0) == jf_packet->jf.framenum);
ap_uint<UDP_METADATA_STREAM_WIDTH> udp_metadata_out;
udp_metadata.read(udp_metadata_out);
REQUIRE(udp_metadata_dest_port(udp_metadata_out) == 129);
REQUIRE(udp_metadata_payload_size(udp_metadata_out) == 8240);
REQUIRE(udp_metadata_eth_err(udp_metadata_out) == 1);
REQUIRE(udp_metadata_len_err(udp_metadata_out) == 0);
}
TEST_CASE("HLS_Network_UDP_LenErr") {
char packet[130*64];
auto jf_packet = (jf_raw_packet *) packet;
jf_packet->udp_length = htons(8248);
jf_packet->udp_dest_port = htons(129);
jf_packet->jf.framenum = 123456;
uint64_t packet_counter;
ap_uint<1> clear_counter = 0;
STREAM_512 udp_in;
STREAM_512 udp_out;
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > udp_metadata;
auto jf_packet_axi = (ap_uint<512> *) packet;
for (int i = 0; i < 128; i++) {
packet_512_t packet_in;
packet_in.user = 0;
packet_in.last = (i == 127);
packet_in.data = jf_packet_axi[i];
udp_in.write(packet_in);
udp(udp_in, udp_out, udp_metadata, packet_counter, clear_counter);
}
REQUIRE(udp_in.size() == 0);
REQUIRE(udp_metadata.size() == 1);
REQUIRE(udp_out.size() == 127);
packet_512_t packet_out;
udp_out.read(packet_out);
REQUIRE(packet_out.data(63,0) == jf_packet->jf.framenum);
ap_uint<UDP_METADATA_STREAM_WIDTH> udp_metadata_out;
udp_metadata.read(udp_metadata_out);
REQUIRE(udp_metadata_dest_port(udp_metadata_out) == 129);
REQUIRE(udp_metadata_payload_size(udp_metadata_out) == 8240);
REQUIRE(udp_metadata_eth_err(udp_metadata_out) == 0);
REQUIRE(udp_metadata_len_err(udp_metadata_out) == 1);
}
TEST_CASE("HLS_Network_UDP_SLS_detector_1") {
char packet[130*64];
auto jf_packet = (jf_raw_packet *) packet;
jf_packet->ipv4_header_sour_ip = htonl(32);
jf_packet->udp_length = htons(8248);
jf_packet->udp_dest_port = htons(128 + 5);
jf_packet->jf.framenum = 123456;
jf_packet->jf.packetnum = 60;
jf_packet->jf.xCoord = 5;
for (int i = 0; i < 4096; i++)
jf_packet->jf.data[i] = i;
STREAM_512 udp_in;
STREAM_512 udp_out;
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > udp_metadata;
STREAM_512 raw_out;
hls::stream<ap_uint<ADDR_STREAM_WIDTH> > addr0;
uint64_t packet_counter;
uint64_t sls_packet_counter;
uint32_t err_counter1, err_counter2;
ap_uint<1> clear_counter = 0;
auto jf_packet_axi = (ap_uint<512> *) packet;
for (int i = 0; i < 130; i++) {
packet_512_t packet_in;
packet_in.user = 0;
packet_in.last = (i == 129);
packet_in.data = jf_packet_axi[i];
udp_in.write(packet_in);
udp(udp_in, udp_out, udp_metadata, packet_counter, clear_counter);
}
REQUIRE(udp_in.size() == 0);
REQUIRE(udp_metadata.size() == 1);
REQUIRE(udp_out.size() == 129);
while (!udp_out.empty()) {
sls_detector(udp_out, udp_metadata, raw_out, addr0, sls_packet_counter, err_counter1, err_counter2, clear_counter);
}
REQUIRE(raw_out.size() == 128);
REQUIRE(addr0.size() == 1);
for (int i = 0; i < 128; i++) {
auto packet_out = raw_out.read();
REQUIRE(memcmp(&(packet_out.data), jf_packet->jf.data + 32 * i, 64) == 0);
}
auto addr = addr0.read();
REQUIRE(addr_frame_number(addr) == jf_packet->jf.framenum);
REQUIRE(addr_module(addr) == 5 / 2);
REQUIRE(addr_eth_packet(addr) == (jf_packet->jf.packetnum | 64));
}
TEST_CASE("HLS_Network_UDP_SLS_detector_2") {
char packet[130*64];
auto jf_packet = (jf_raw_packet *) packet;
jf_packet->udp_length = htons(8248);
jf_packet->ipv4_header_sour_ip = htonl(32+4);
jf_packet->jf.framenum = UINT64_MAX - 300;
jf_packet->jf.packetnum = 35;
jf_packet->jf.xCoord = 4;
for (int i = 0; i < 4096; i++)
jf_packet->jf.data[i] = i;
STREAM_512 udp_in;
STREAM_512 udp_out;
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > udp_metadata;
STREAM_512 raw_out;
hls::stream<ap_uint<ADDR_STREAM_WIDTH> > addr0;
auto jf_packet_axi = (ap_uint<512> *) packet;
uint64_t packet_counter;
uint64_t sls_packet_counter;
uint32_t err_counter1, err_counter2;
ap_uint<1> clear_counter = 0;
for (int i = 0; i < 130; i++) {
packet_512_t packet_in;
packet_in.user = 0;
packet_in.last = (i == 129);
packet_in.data = jf_packet_axi[i];
udp_in.write(packet_in);
udp(udp_in, udp_out, udp_metadata, packet_counter, clear_counter);
}
REQUIRE(udp_in.size() == 0);
REQUIRE(udp_metadata.size() == 1);
REQUIRE(udp_out.size() == 129);
while (!udp_out.empty()) {
sls_detector(udp_out, udp_metadata, raw_out, addr0, sls_packet_counter, err_counter1, err_counter2, clear_counter);
}
REQUIRE(raw_out.size() == 128);
REQUIRE(addr0.size() == 1);
for (int i = 0; i < 128; i++) {
auto packet_out = raw_out.read();
REQUIRE(memcmp(&(packet_out.data), jf_packet->jf.data + 32 * i, 64) == 0);
}
auto addr = addr0.read();
REQUIRE(addr_frame_number(addr) == jf_packet->jf.framenum);
REQUIRE(addr_module(addr) == 2);
REQUIRE(addr_eth_packet(addr) == jf_packet->jf.packetnum);
}
TEST_CASE("HLS_Network_UDP_SLS_detector_2_packets") {
char packet[130*64];
auto jf_packet = (jf_raw_packet *) packet;
jf_packet->ipv4_header_sour_ip = htonl(192);
jf_packet->udp_length = htons(8248);
jf_packet->udp_dest_port = htons(128);
jf_packet->jf.framenum = UINT64_MAX - 300;
jf_packet->jf.packetnum = 35;
jf_packet->jf.xCoord = 2;
for (int i = 0; i < 4096; i++)
jf_packet->jf.data[i] = i;
STREAM_512 udp_in;
STREAM_512 udp_out;
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > udp_metadata;
STREAM_512 raw_out;
hls::stream<ap_uint<ADDR_STREAM_WIDTH> > addr0;
auto jf_packet_axi = (ap_uint<512> *) packet;
uint64_t packet_counter;
uint64_t sls_packet_counter;
uint32_t err_counter1, err_counter2;
ap_uint<1> clear_counter = 0;
for (int i = 0; i < 130; i++) {
packet_512_t packet_in;
packet_in.user = 0;
packet_in.last = (i == 129);
packet_in.data = jf_packet_axi[i];
udp_in.write(packet_in);
udp(udp_in, udp_out, udp_metadata, packet_counter, clear_counter);
}
for (int i = 0; i < 130; i++) {
packet_512_t packet_in;
packet_in.user = 0;
packet_in.last = (i == 129);
packet_in.data = jf_packet_axi[i];
udp_in.write(packet_in);
udp(udp_in, udp_out, udp_metadata, packet_counter, clear_counter);
}
REQUIRE(udp_in.size() == 0);
REQUIRE(udp_metadata.size() == 2);
REQUIRE(udp_out.size() == 2*129);
while (!udp_out.empty()) {
sls_detector(udp_out, udp_metadata, raw_out, addr0, sls_packet_counter, err_counter1, err_counter2, clear_counter);
}
REQUIRE(raw_out.size() == 256);
REQUIRE(addr0.size() == 2);
for (int j = 0; j < 2; j++) {
for (int i = 0; i < 128; i++) {
auto packet_out = raw_out.read();
REQUIRE(memcmp(&(packet_out.data), jf_packet->jf.data + 32 * i, 64) == 0);
}
auto addr = addr0.read();
REQUIRE(addr_frame_number(addr) == jf_packet->jf.framenum);
REQUIRE(addr_module(addr) == 1);
REQUIRE(addr_eth_packet(addr) == jf_packet->jf.packetnum);
}
}
TEST_CASE("HLS_Network_UDP_SLS_detector_packets_err") {
char packet[130*64];
auto jf_packet = (jf_raw_packet *) packet;
jf_packet->ipv4_header_sour_ip = htonl(32+4);
jf_packet->udp_length = htons(8248);
jf_packet->udp_dest_port = htons(128 + 4);
jf_packet->jf.framenum = UINT64_MAX - 300;
jf_packet->jf.packetnum = 35;
jf_packet->jf.xCoord = 4;
for (int i = 0; i < 4096; i++)
jf_packet->jf.data[i] = i;
STREAM_512 udp_in;
STREAM_512 udp_out;
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > udp_metadata;
STREAM_512 raw_out;
hls::stream<ap_uint<ADDR_STREAM_WIDTH> > addr0;
auto jf_packet_axi = (ap_uint<512> *) packet;
uint64_t udp_packet_counter;
uint64_t sls_packet_counter;
uint32_t err_counter_eth, err_counter_len;
ap_uint<1> clear_counter = 0;
clear_counter = 1;
for (int i = 0; i < 125; i++) {
packet_512_t packet_in;
packet_in.user = 0;
packet_in.last = (i == 124);
packet_in.data = jf_packet_axi[i];
udp_in.write(packet_in);
udp(udp_in, udp_out, udp_metadata, udp_packet_counter, clear_counter);
clear_counter = 0;
}
for (int i = 0; i < 130; i++) {
packet_512_t packet_in;
packet_in.user = 0;
packet_in.last = (i == 129);
packet_in.data = jf_packet_axi[i];
udp_in.write(packet_in);
udp(udp_in, udp_out, udp_metadata, udp_packet_counter, clear_counter);
}
for (int i = 0; i < 130; i++) {
packet_512_t packet_in;
packet_in.user = 1;
packet_in.last = (i == 129);
packet_in.data = jf_packet_axi[i];
udp_in.write(packet_in);
udp(udp_in, udp_out, udp_metadata, udp_packet_counter, clear_counter);
}
for (int i = 0; i < 130; i++) {
packet_512_t packet_in;
packet_in.user = 1;
packet_in.last = (i == 129);
packet_in.data = jf_packet_axi[i];
udp_in.write(packet_in);
udp(udp_in, udp_out, udp_metadata, udp_packet_counter, clear_counter);
}
REQUIRE(udp_in.size() == 0);
REQUIRE(udp_metadata.size() == 4);
REQUIRE(udp_out.size() == 129*3+124);
clear_counter = 1;
while (!udp_out.empty()) {
sls_detector(udp_out, udp_metadata, raw_out, addr0, sls_packet_counter, err_counter_eth, err_counter_len, clear_counter);
clear_counter = 0;
}
REQUIRE(raw_out.size() == 128);
REQUIRE(addr0.size() == 1);
for (int i = 0; i < 128; i++) {
auto packet_out = raw_out.read();
REQUIRE(memcmp(&(packet_out.data), jf_packet->jf.data + 32 * i, 64) == 0);
}
auto addr = addr0.read();
REQUIRE(addr_frame_number(addr) == jf_packet->jf.framenum);
REQUIRE(addr_module(addr) == 2);
REQUIRE(addr_eth_packet(addr) == jf_packet->jf.packetnum);
REQUIRE(udp_packet_counter == 4);
REQUIRE(sls_packet_counter == 1);
REQUIRE(err_counter_eth == 2);
REQUIRE(err_counter_len == 1);
}