// Copyright (2019-2023) Paul Scherrer Institute #include #include #include #include #include "../fpga/hls/hls_jfjoch.h" #include "../jungfrau/sls_packet.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") { AXI_STREAM arp_in; AXI_STREAM arp_out; arp(arp_in, arp_out, 0x1, 0x1, 1, 1); packet_512_t network_packet; REQUIRE(arp_out.read_nb(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 > udp_metadata; auto jf_packet_axi = (ap_uint<512> *) packet; uint64_t packet_counter; ap_uint<1> clear_counter = 0; ap_uint<1> udp_idle = 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, udp_idle); } 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_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 > udp_metadata; auto jf_packet_axi = (ap_uint<512> *) packet; uint64_t packet_counter; ap_uint<1> clear_counter = 0; ap_uint<1> udp_idle = 1; 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, udp_idle); } REQUIRE(udp_idle == 1); 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_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; ap_uint<1> udp_idle = 0; STREAM_512 udp_in; STREAM_512 udp_out; hls::stream > 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, udp_idle); } 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_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.row = 5; jf_packet->jf.detectortype = SLS_DETECTOR_TYPE_JUNGFRAU; for (int i = 0; i < 4096; i++) jf_packet->jf.data[i] = i; STREAM_512 udp_in; STREAM_512 udp_out; hls::stream > udp_metadata; STREAM_512 raw_out; hls::stream addr0; uint64_t packet_counter; uint64_t sls_packet_counter; uint32_t err_counter1, err_counter2; ap_uint<1> clear_counter = 0; ap_uint<1> udp_idle = 0; ap_uint<1> sls_idle = 0; uint64_t bunchid = 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, udp_idle); } REQUIRE(udp_in.size() == 0); REQUIRE(udp_metadata.size() == 1); REQUIRE(udp_out.size() == 129); REQUIRE(udp_idle == 1); while (!udp_out.empty()) { sls_detector(udp_out, udp_metadata, raw_out, addr0, sls_packet_counter, err_counter1, err_counter2, bunchid, clear_counter, sls_idle); } REQUIRE(sls_idle == 1); 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 == jf_packet->jf.framenum - 1); REQUIRE(addr.module == 5 / 2); REQUIRE(addr.eth_packet == (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.row = 4; jf_packet->jf.detectortype = SLS_DETECTOR_TYPE_JUNGFRAU; for (int i = 0; i < 4096; i++) jf_packet->jf.data[i] = i; STREAM_512 udp_in; STREAM_512 udp_out; hls::stream > udp_metadata; STREAM_512 raw_out; hls::stream 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; ap_uint<1> udp_idle = 1; ap_uint<1> sls_idle = 1; uint64_t bunchid = 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, udp_idle); } REQUIRE(udp_in.size() == 0); REQUIRE(udp_metadata.size() == 1); REQUIRE(udp_out.size() == 129); REQUIRE(udp_idle == 1); while (!udp_out.empty()) { sls_detector(udp_out, udp_metadata, raw_out, addr0, sls_packet_counter, err_counter1, err_counter2, bunchid, clear_counter, sls_idle); } REQUIRE(raw_out.size() == 128); REQUIRE(addr0.size() == 1); REQUIRE(sls_idle == 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 == jf_packet->jf.framenum - 1); REQUIRE(addr.module == 2); REQUIRE(addr.eth_packet == 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.row = 2; jf_packet->jf.detectortype = SLS_DETECTOR_TYPE_JUNGFRAU; for (int i = 0; i < 4096; i++) jf_packet->jf.data[i] = i; STREAM_512 udp_in; STREAM_512 udp_out; hls::stream > udp_metadata; STREAM_512 raw_out; hls::stream 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; ap_uint<1> udp_idle = 1; ap_uint<1> sls_idle = 1; uint64_t bunchid = 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, udp_idle); } 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, udp_idle); } 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, bunchid, clear_counter, sls_idle); } 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 == jf_packet->jf.framenum - 1); REQUIRE(addr.module == 1); REQUIRE(addr.eth_packet == 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.row = 4; jf_packet->jf.detectortype = SLS_DETECTOR_TYPE_JUNGFRAU; for (int i = 0; i < 4096; i++) jf_packet->jf.data[i] = i; STREAM_512 udp_in; STREAM_512 udp_out; hls::stream > udp_metadata; STREAM_512 raw_out; hls::stream 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; ap_uint<1> udp_idle = 1; ap_uint<1> sls_idle = 1; uint64_t bunchid = 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, udp_idle); 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, udp_idle); } 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, udp_idle); } 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, udp_idle); } 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, bunchid, clear_counter, sls_idle); 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 == jf_packet->jf.framenum - 1); REQUIRE(addr.module == 2); REQUIRE(addr.eth_packet == jf_packet->jf.packetnum); REQUIRE(udp_packet_counter == 4); REQUIRE(sls_packet_counter == 1); REQUIRE(err_counter_eth == 2); REQUIRE(err_counter_len == 1); } TEST_CASE("HLS_Network_UDP_SLS_detector_4kB") { char packet[130*64]; auto jf_packet = (eiger_raw_packet *) packet; jf_packet->udp_length = htons(4096+48+8); jf_packet->udp_dest_port = htons(128 + 5); jf_packet->eiger.framenum = 123456; jf_packet->eiger.packetnum = 60; jf_packet->eiger.detectortype = SLS_DETECTOR_TYPE_EIGER; for (int i = 0; i < 2048; i++) jf_packet->eiger.data[i] = i; STREAM_512 udp_in; STREAM_512 udp_out; hls::stream > udp_metadata; STREAM_512 raw_out; hls::stream addr0; ap_uint<1> udp_idle; uint64_t packet_counter; uint64_t sls_packet_counter; uint32_t err_counter_eth, err_counter_len; ap_uint<1> sls_idle = 1; uint64_t bunchid = 0; auto jf_packet_axi = (ap_uint<512> *) packet; ap_uint<1> clear_counter = 0; for (int i = 0; i < 66; i++) { packet_512_t packet_in; packet_in.user = 0; packet_in.last = (i == 65); packet_in.data = jf_packet_axi[i]; udp_in.write(packet_in); udp(udp_in, udp_out, udp_metadata, packet_counter, clear_counter, udp_idle); } REQUIRE(udp_in.size() == 0); REQUIRE(udp_metadata.size() == 1); REQUIRE(udp_out.size() == 65); while (!udp_out.empty()) { sls_detector(udp_out, udp_metadata, raw_out, addr0, sls_packet_counter, err_counter_eth, err_counter_len, bunchid, clear_counter, sls_idle); } REQUIRE(raw_out.size() == 64); REQUIRE(addr0.size() == 1); for (int i = 0; i < 64; i++) { auto packet_out = raw_out.read(); REQUIRE(memcmp(&(packet_out.data), jf_packet->eiger.data + 32 * i, 64) == 0); } auto addr = addr0.read(); REQUIRE(addr.frame_number == jf_packet->eiger.framenum - 1); } TEST_CASE("HLS_Network_UDP_SLS_detector_bunchid") { ap_uint<512> tmp[2]; auto packet = (bunchid_raw_packet *) tmp; for (int i = 0; i < 6; i++) packet->dest_mac[i] = 0xFF; packet->udp_length = htons(sizeof(bunchid_payload) + 8); packet->payload.magicn[0] = BUNCHID_MAGICN; packet->payload.magicn[1] = BUNCHID_MAGICN; packet->payload.magicn[2] = BUNCHID_MAGICN; packet->payload.bunchid_msb[0] = 0xAABBCCDD; packet->payload.bunchid_msb[1] = 0xAABBCCDD; packet->payload.bunchid_lsb[0] = 0xFFDDCCBB; packet->payload.bunchid_lsb[1] = 0xFFDDCCBB; STREAM_512 udp_in; STREAM_512 udp_out; hls::stream > udp_metadata; STREAM_512 raw_out; hls::stream addr0; uint64_t udp_packet_counter; uint64_t sls_packet_counter; uint32_t err_counter_eth, err_counter_len; ap_uint<1> clear_counter = 0; ap_uint<1> udp_idle = 1; ap_uint<1> sls_idle = 1; uint64_t bunchid = 0; clear_counter = 1; packet_512_t packet_in; packet_in.user = 0; packet_in.last = 0; packet_in.data = tmp[0]; udp_in.write(packet_in); packet_in.last = 1; packet_in.data = tmp[1]; udp_in.write(packet_in); udp(udp_in, udp_out, udp_metadata, udp_packet_counter, clear_counter, udp_idle); udp(udp_in, udp_out, udp_metadata, udp_packet_counter, clear_counter, udp_idle); clear_counter = 0; REQUIRE(udp_in.size() == 0); REQUIRE(udp_metadata.size() == 1); REQUIRE(udp_out.size() == 1); clear_counter = 1; sls_detector(udp_out, udp_metadata, raw_out, addr0, sls_packet_counter, err_counter_eth, err_counter_len, bunchid, clear_counter, sls_idle); clear_counter = 0; REQUIRE(raw_out.size() == 0); REQUIRE(addr0.size() == 0); REQUIRE(bunchid == 0xAABBCCDDFFDDCCBB); REQUIRE(udp_packet_counter == 1); REQUIRE(sls_packet_counter == 0); REQUIRE(err_counter_eth == 0); REQUIRE(err_counter_len == 0); }